Reputation:
I want to make a search functionality for JTable object. I have a JTextFiled where i put my text to search. I want to change colors rows and cells which contains this text. Now i'm stuck because i have no idea how to change color dynamically.
public class TableSearchCellRenderer extends DefaultTableCellRenderer {
String search = "";
public void setSearch(String search) {
this.search = search;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (table.getValueAt(row, column).equals(search)) {
setBackground(Color.green);
}
return this;
}
}
I've tried with something like this but it doesn't work.
I tried to call rerender table like this way
String selectedTitle = tabbed.getTitleAt(tabbed.getSelectedIndex());
JTable table = tabels.get(selectedTitle);
((TableSearchCellRenderer)table.getDefaultRenderer(String.class)).setSearch(searchField.getText());
table.repaint();
((AbstractTableModel) table.getModel()).fireTableDataChanged();
but with no success :(
Could you help me?
Upvotes: 1
Views: 10447
Reputation:
It works. I change prepare renderer.
JTable table = new JTable() {
private static final long serialVersionUID = 1L;
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
Component c = super.prepareRenderer(renderer, row, column);
**if (column == 0) {
for (int i = 0; i < getModel().getColumnCount(); i++) {
if (((TableSearchRenderer) getDefaultRenderer(String.class)).getSearch().length() > 0 && ((TableSearchRenderer) getDefaultRenderer(String.class)).getSearch().toLowerCase().equals(getModel().getValueAt(row, i).toString().toLowerCase()))
((TableSearchRenderer) getDefaultRenderer(String.class)).getRows().add(row);
}
}**
if (((TableSearchRenderer) getDefaultRenderer(String.class)).getRows().contains(row) && c.getBackground() != Color.RED) {
c.setBackground(Color.GREEN);
}
return c;
}
};
Upvotes: 0
Reputation: 324118
See Table Row Rendering. The example does row level highlighting on a fixed word. You would need to modify the code to do the highlighting on your search word.
Another approach is to filter the table to see only the rows that contain the text you are searching for. See Sorting and Filtering for a working example.
Upvotes: 1
Reputation: 47608
Here is a working version of your search feature based on the TableCellRenderer. One of the issue you may have hit, is that, although your TableModel contains String, if you use the DefaultTableModel
, it always returns Object.class
for all data and the JTable
will therefore use the DefaultTableCellRenderer
instead of your TableSearchCellRenderer
.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.Random;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
public class TestTable2 {
private String search;
public String getSearch() {
return search;
}
public void setSearch(String search) {
this.search = search;
}
private class TableSearchRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setBackground(null);
Component tableCellRendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (getSearch() != null && getSearch().length() > 0 && value.toString().contains(getSearch())) {
setBackground(Color.RED);
}
return tableCellRendererComponent;
}
}
protected void initUI() {
DefaultTableModel model = new DefaultTableModel();
for (int i = 0; i < 5; i++) {
model.addColumn("Column " + (i + 1));
}
Random random = new Random();
for (int i = 0; i < 200; i++) {
Vector<Object> row = new Vector<Object>();
for (int j = 0; j < 40; j++) {
row.add(WORDS[random.nextInt(WORDS.length)]);
}
model.addRow(row);
}
table = new JTable(model);
TableSearchRenderer renderer = new TableSearchRenderer();
table.setDefaultRenderer(Object.class, renderer);
textField = new JTextField(30);
textField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
updateSearch();
}
@Override
public void insertUpdate(DocumentEvent e) {
updateSearch();
}
@Override
public void changedUpdate(DocumentEvent e) {
updateSearch();
}
});
JFrame frame = new JFrame(TestTable2.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane scrollpane = new JScrollPane(table);
scrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
frame.add(scrollpane, BorderLayout.CENTER);
frame.add(textField, BorderLayout.NORTH);
frame.setSize(1000, 800);
frame.setVisible(true);
}
protected void updateSearch() {
setSearch(textField.getText());
table.repaint();
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
UnsupportedLookAndFeelException {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new TestTable2().initUI();
}
});
}
private static final String[] WORDS = { "art", "australia", "baby", "beach", "birthday", "blue", "bw", "california", "canada", "canon",
"cat", "chicago", "china", "christmas", "city", "dog", "england", "europe", "family", "festival", "flower", "flowers", "food",
"france", "friends", "fun", "germany", "holiday", "india", "italy", "japan", "london", "me", "mexico", "music", "nature",
"new", "newyork", "night", "nikon", "nyc", "paris", "park", "party", "people", "portrait", "sanfrancisco", "sky", "snow",
"spain", "summer", "sunset", "taiwan", "tokyo", "travel", "trip", "uk", "usa", "vacation", "water", "wedding" };
private JTable table;
private JTextField textField;
}
Upvotes: 4