2014-03-06 76 views
3

如何在更改JTextField中的搜索值之後刷新JTable中的突出顯示器?它適用於JTextfield下的JTextArea,但JTable不會刷新突出顯示。有什麼建議麼??在更改搜索值時刷新/更新JTable中的突出顯示器

這是我的代碼:

import java.awt.*; 
import java.awt.event.*; 

import javax.swing.*; 
import javax.swing.table.*; 
import javax.swing.text.*; 
import javax.swing.text.DefaultHighlighter.DefaultHighlightPainter; 

public class BeispielTabelle { 
JTextField field; 
JTextArea textFeld = new JTextArea("Hello World!"); 
String input="Stefan"; 

//Titel der Tabelle 
String[] title = {"EINS", "ZWEI", "DREI"}; 

//Tabellendaten 
Object[][] playerdata = {  
{"34", "Stefan", "Mein Name ist Stefan"}, 
{"32", "Dirk", "Ich bin der Dirk"}, 
{"99", "Patrick", "Ich heisse Patrick"}, 
{"100", "Anna", "Ich bin die Anna"},}; 

//TableModel 
DefaultTableModel model = new DefaultTableModel(playerdata,title); 

//Tabelle erstellen 
JTable textTable = new JTable(model);  

public JPanel erstelleTabelle() {    
    JPanel totalGUI = new JPanel();  
    //CellRenderer 
    SearchRenderer cellRenderer = new SearchRenderer(); 


    //Spaltenbreiten festlegen 
    textTable.setDefaultRenderer(String.class, cellRenderer); 
    textTable.getColumnModel().getColumn(0).setCellRenderer(cellRenderer); 
    textTable.getColumnModel().getColumn(1).setCellRenderer(cellRenderer);  
    textTable.getColumnModel().getColumn(2).setCellRenderer(cellRenderer); 

    textTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); // Autoresizing abschalten, sonst sind alle Spalten gleich breit: 
    textTable.getColumnModel().getColumn(0).setPreferredWidth(60); 
    textTable.getColumnModel().getColumn(1).setPreferredWidth(60); 
    textTable.getColumnModel().getColumn(2).setPreferredWidth(180);  

    //das Ganze scrollbar machen 
    JScrollPane scrollPane = new JScrollPane(textTable); 

    //TextFeld erstellen 
    field = new JTextField(); 
    field.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      input = field.getText(); 
      System.out.println(input); 
      //updateRowHeights(); 
      highlightText(); 
     } 
    });   

    totalGUI.add(scrollPane); 
    totalGUI.add(field); 
    totalGUI.add(textFeld);   
    return totalGUI; 
} 

void highlightText() { 
    DefaultHighlightPainter yellowPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW); 
    Highlighter highlighter = textFeld.getHighlighter(); 
    highlighter.removeAllHighlights();  
    String text = textFeld.getText(); 
    String pattern = input; 
    int index = text.indexOf(pattern);  
    while (index >= 0) { 
     int len = pattern.length(); 
     try { 
      highlighter.addHighlight(index, index+len, yellowPainter); 
     } catch (BadLocationException e) { 
      e.printStackTrace(); 
     } 
     index = text.indexOf(pattern, index+len); 
    } 
} 

private static void createAndShowGUI() { 

    //create main frame 
    JFrame mainFrame = new JFrame(""); 
    BeispielTabelle test = new BeispielTabelle(); 

    JPanel totalGUI = new JPanel(); 
    totalGUI = test.erstelleTabelle(); 
    totalGUI.setLayout(new BoxLayout(totalGUI, BoxLayout.Y_AXIS)); 

    //visible mode 
    mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    mainFrame.add(totalGUI); //integrate main panel to main frame 
    mainFrame.pack(); 
    mainFrame.setVisible(true);  
} 


public static void main (String[] args) {    

    createAndShowGUI();  

}//main 
}//GUI_main 

這是我SearchRenderer

import javax.swing.*; 
import javax.swing.table.*; 
import javax.swing.text.BadLocationException; 

import java.awt.*; 

public class SearchRenderer extends JTextArea implements TableCellRenderer { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 
public SearchRenderer() {}//constructor 
BeispielTabelle tabelle = new BeispielTabelle(); 
String textForSearch=tabelle.input; 

@Override 
public Component getTableCellRendererComponent (JTable table, 
               Object value, 
               boolean isSelected, 
               boolean hasFocus, 
               int row,      
               int column) { 
    this.setText((String) value); 
    if(value != null) { 
     String string = value.toString(); 
     if(string.contains(textForSearch)){ 
      int indexOf = string.indexOf(textForSearch); 
      while(indexOf >=0) { 
      try { 
         this.getHighlighter().addHighlight(indexOf,indexOf+textForSearch.length(),new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.GREEN)); 
      } catch (BadLocationException e) { 
       e.printStackTrace(); 
      } 
      indexOf = string.indexOf(textForSearch, indexOf+textForSearch.length()); 
     } 
    } 
    } else { 
     this.setText(""); 
     this.getHighlighter().removeAllHighlights(); 
    } 
    return this; 
} 
} 
+0

我不知道標準,普通vani lla Swing,從未試圖將JTextPane的熒光筆畫爲JTable中的rendereres J/Component(也不是用於半尺寸化的JTextArea),必須搜索一些基於Swing的自定義框架才能做到這一點(我會從Jide或SwingX開始? ??) – mKorbel

+0

就個人而言,我不會使用熒光筆,我會用適當的顏色繪製背景(和前景?)。表格處理得很好。 – Gorbles

+0

實際上突出顯示甚至可以在JTable中正常工作,我的問題是當我想要搜索另一個值時進行更新/刷新...我需要一個解決方案,在JTextField – Ramses

回答

4

也許你可以使用JTable#repaint()

enter image description here

import java.awt.*; 
import java.util.Objects; 
import java.util.regex.*; 
import javax.swing.*; 
import javax.swing.event.*; 
import javax.swing.table.*; 
import javax.swing.text.*; 

public final class SearchRendererTest { 
    private final JTextField field = new JTextField("Stefan"); 
    private final SearchRenderer renderer = new SearchRenderer(); 

    //Titel der Tabelle 
    private final String[] title = {"EINS", "ZWEI", "DREI"}; 

    //Tabellendaten 
    private final Object[][] playerdata = { 
    {"34", "Stefan", "Mein Name ist Stefan"}, 
    {"32", "Dirk", "Ich bin der Dirk"}, 
    {"99", "Patrick", "Ich heisse Patrick"}, 
    {"100", "Anna", "Ich bin die Anna"}, 
    }; 
    private final TableModel model = new DefaultTableModel(playerdata, title); 
    private final JTable table = new JTable(model); 

    public JComponent makeUI() { 
    table.setDefaultRenderer(Object.class, renderer); 
    field.getDocument().addDocumentListener(new DocumentListener() { 
     @Override public void insertUpdate(DocumentEvent e) { 
     fireDocumentChangeEvent(); 
     } 
     @Override public void removeUpdate(DocumentEvent e) { 
     fireDocumentChangeEvent(); 
     } 
     @Override public void changedUpdate(DocumentEvent e) { 
     /* not needed */ 
     } 
    }); 
    fireDocumentChangeEvent(); 

    JPanel sp = new JPanel(new BorderLayout(5, 5)); 
    sp.add(new JLabel("regex pattern:"), BorderLayout.WEST); 
    sp.add(field); 
    sp.add(Box.createVerticalStrut(2), BorderLayout.SOUTH); 
    sp.setBorder(BorderFactory.createTitledBorder("Search")); 

    JPanel p = new JPanel(new BorderLayout(5, 5)); 
    p.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); 
    p.add(sp, BorderLayout.NORTH); 
    p.add(new JScrollPane(table)); 
    return p; 
    } 

    private void fireDocumentChangeEvent() { 
    String pattern = field.getText().trim(); 
    renderer.setPattern(pattern); 
    table.repaint(); 
    } 

    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override public void run() { 
     createAndShowGUI(); 
     } 
    }); 
    } 

    public static void createAndShowGUI() { 
    JFrame f = new JFrame(); 
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
    f.getContentPane().add(new SearchRendererTest().makeUI()); 
    f.pack(); 
    f.setLocationRelativeTo(null); 
    f.setVisible(true); 
    } 
} 

class SearchRenderer implements TableCellRenderer { 
    private static final Color BACKGROUND_SELECTION_COLOR = new Color(220, 240, 255); 
    private final transient Highlighter.HighlightPainter highlightPainter 
    = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW); 
    private final JTextField field = new JTextField(); 
    private String pattern = ""; 
    private String prev; 

    public boolean setPattern(String str) { 
    if (str == null || str.equals(pattern)) { 
     return false; 
    } else { 
     prev = pattern; 
     pattern = str; 
     return true; 
    } 
    } 
    public SearchRenderer() { 
    super(); 
    field.setOpaque(true); 
    field.setBorder(BorderFactory.createEmptyBorder()); 
    field.setForeground(Color.BLACK); 
    field.setBackground(Color.WHITE); 
    field.setEditable(false); 
    } 
    @Override public Component getTableCellRendererComponent(
    JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
    String txt = Objects.toString(value, ""); 
    Highlighter highlighter = field.getHighlighter(); 
    highlighter.removeAllHighlights(); 
    field.setText(txt); 
    field.setBackground(isSelected ? BACKGROUND_SELECTION_COLOR : Color.WHITE); 
    if (pattern != null && !pattern.isEmpty() && !pattern.equals(prev)) { 
     Matcher matcher = Pattern.compile(pattern).matcher(txt); 
     if (matcher.find()) { 
     int start = matcher.start(); 
     int end = matcher.end(); 
     try { 
      highlighter.addHighlight(start, end, highlightPainter); 
     } catch (BadLocationException e) { 
      e.printStackTrace(); 
     } 
     } 
    } 
    return field; 
    } 
} 
+0

輸入更改時呈現表格,這是非常好的解決方案!謝謝!! – Ramses

+0

+1 [but ......](http://stackoverflow.com/a/16816985/714968)通過@Guillaume Polet在我的問題如何避免'JTable#repaint()' – mKorbel