Настройка Swing JTable для фильтрации/поиска

Я хотел бы добавить возможность фильтрации/поиска для всех столбцов (чтобы она была общей), логика не проблема. Однако я подумал, что лучший способ сделать это с точки зрения визуализации — это текстовое поле над каждым заголовком столбца (или частью заголовка столбца)?

Я столкнулся с парой проблем при попытке добиться этого:

  1. Встраивание в заголовок столбца требует реализации нового рендерера + есть проблема, что каким-то образом мне нужно поймать событие, потому что ячейка рисуется и не реагирует на события. Мне кажется перебор.
  2. Наличие отдельной строки (панели) компонентов текстового поля над каждым столбцом на первый взгляд кажется намного проще, однако выравнивание текстового поля со столбцами проблематично, так как я не нашел API в JTable или TableColumn, который возвращает координаты столбец. Кроме того, перемещение столбца будет означать также настройку текстовых полей (что возможно, но требует дополнительных затрат).

Я что-то упустил или действительно так сложно добиться чего-то такого простого? Любые другие предложения?


person GBa    schedule 30.03.2012    source источник


Ответы (3)


Существует библиотека для вашего первого подхода. Его легко интегрировать, и он отлично работает: Swing Bits

person Kai    schedule 30.03.2012

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

См. ниже пример для фильтрации, основанной на записях текстового поля, фильтрация ваших данных Jtable зависит от записи текстового поля:

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;

открытый класс TestTableSorterFilter расширяет 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));
            }   
        }
    });
}
}
person Mohamed Bawaneen    schedule 26.10.2014