Question

how can I refresh the highlighter in my JTable after changing the search value in the JTextField? It works fine with the JTextArea under the JTextfield, but I the JTable won't refresh the highlighter. Any Suggestions??

This is my Code:

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

And this is my 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;
}
}
Was it helpful?

Solution

Maybe you can use 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;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top