GBa
GBa

Reputation: 1006

Swing JTable customization for filtering/searching

I'd like to add filtering/searching capability for all columns (so that it is generic) the logic is not a problem. However, I was thinking is that the best way to do that in terms of visualization is having a text field above each column header (or part of the column header)?

I've run into a couple of problems when trying to achieve that:

  1. Embedding within the column header demands implementing a new renderer + there's the problem that somehow I need to catch the event because the cell is drawn and does not respond to events. Looks like an overkill to me.
  2. Having a separate line (panel) of text field components above each column sounds much easier at first glance, however, aligning the text field with the columns is problematic since I didn't find an API in JTable or TableColumn that returns the coordinates of the column. Moreover, moving the column around would mean adjusting the text fields as well (which is possible but another overhead).

Am I missing something or it is indeed that hard to achieve something as simple as that? Any other suggestions?

Upvotes: 3

Views: 6772

Answers (3)

Kai
Kai

Reputation: 39631

There is a library for your first approach. It can easily be integrated and works really great: Swing Bits

Upvotes: 3

Mohamed Bawaneen
Mohamed Bawaneen

Reputation: 101

See hereunder an sample for Filtering rely on text field entries filtering your Jtable data rely on text box entry :

import java.awt.BorderLayout;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class TestTableSorterFilter extends JApplet {

private String[] columnNames
        = {"Country", "Capital", "Population in Millions", "Democracy"};

private Object[][] data = {
    {"USA", "Washington DC", 280, true},
    {"Canada", "Ottawa", 32, true},
    {"United Kingdom", "London", 60, true},
    {"Germany", "Berlin", 83, true},
    {"France", "Paris", 60, true},
    {"Norway", "Oslo", 4.5, true},
    {"India", "New Delhi", 1046, true}
};

private JTable jTable = new JTable(data, columnNames);

private TableRowSorter<TableModel> rowSorter
        = new TableRowSorter<>(jTable.getModel());

private JTextField jtfFilter = new JTextField();
private JButton jbtFilter = new JButton("Filter");

public TestTableSorterFilter() {
    jTable.setRowSorter(rowSorter);

    JPanel panel = new JPanel(new BorderLayout());
    panel.add(new JLabel("Specify a word to match:"),
            BorderLayout.WEST);
    panel.add(jtfFilter, BorderLayout.CENTER);

    add(panel, BorderLayout.SOUTH);
    add(new JScrollPane(jTable), BorderLayout.CENTER);

    jtfFilter.getDocument().addDocumentListener(new DocumentListener(){

        @Override
        public void changedUpdate(DocumentEvent arg0) {}

        @Override
        public void insertUpdate(DocumentEvent arg0) {
            String text = jtfFilter.getText();

            if (text.trim().length() == 0) {
                rowSorter.setRowFilter(null);
            } else {
                rowSorter.setRowFilter(RowFilter.regexFilter(text));
            }   
        }

        @Override
        public void removeUpdate(DocumentEvent arg0) {
            String text = jtfFilter.getText();
            if (text.trim().length() == 0) {
                rowSorter.setRowFilter(null);
            } else {
                rowSorter.setRowFilter(RowFilter.regexFilter(text));
            }   
        }
    });
}
}

Upvotes: 0

mKorbel
mKorbel

Reputation: 109815

of visualization is having a textfield above each column header 
(or part of the column header)... 

Upvotes: 2

Related Questions