Wie lassen sich Inhalte in einer JTable
suchen? v.1.6
Im Beispiel wird zur Datenverwaltung zunächst ein einfaches DefaultTableModel
model
mit fünf Einträgen und einem Header erzeugt.
Das Model wird zur Erzeugung der Tabelle anschließend dem
Konstruktor einer JTable
übergeben. Die dann
aufgerufene Methode createRowSorter()
erzeugt einen TableRowSorter
auf dem TableModel und fügt diesen der Tabelle hinzu. Er ist
die Grundlage für die Filterung des Tabellen-Inhaltes.
Im
weiteren Verlauf des Konstruktors werden die Tabellenzellen mit
einem Rahmen versehen (Achtung! Die Standardrahmenfarbe ist
weiß, deshalb muss sie, um sichbar zu werden, explizit gesetzt
werden) und zwei Buttons im unteren Teil des Fensters erzeugt, die
zur Anzeige des Suchfensters und zum Zurücksetzen des
Tabelleninhaltes dienen.
Der Aufruf des Buttons Suche
ruft die Methode search()
auf. In ihr wird als erstes
ein Input-Dialog erzeugt, der neben dem obligatorischen Suchfeld
noch eine Checkbox aufweist, mit der zwischen zwei verschiedenen
Such- und Anzeigemodi gewählt werden kann.
Checkbox | Modus |
---|---|
checked | Anzeige nur der selektierten Zeilen |
unchecked | Anzeige aller Zeilen mit Markierung der selektierten Zeilen |
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableRowSorter;
public class Tabellensuche {
TableRowSorter<DefaultTableModel> sorter;
private JTable table;
public Tabellensuche() {
init();
}
private void init() {
Object[] header = { "Nr", "Vorname", "Name", "Job" };
Object[][] data = { { "3", "Karl", "Meier", "Chef" }, { "2", "Paul", "Schmitz", "Azubi" },
{ "1", "Fritz", "Kunze", "Geselle" }, { "4", "Heinz", "Hinze", "Meister" },
{ "5", "Fritz", "Brecht", "Hausmeister" } };
DefaultTableModel model = new DefaultTableModel(data, header);
JFrame frame = new JFrame("Tabellensuche");
table = new JTable(model);
table.setShowGrid(true);
table.setGridColor(Color.BLACK);
createRowSorter(model);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
JButton searchButt = new JButton("Suche");
searchButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
search();
}
});
JButton resetButt = new JButton("Zur\u00FCcksetzen");
resetButt.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
createRowSorter((DefaultTableModel) table.getModel());
}
});
JPanel buttPanel = new JPanel(new FlowLayout());
buttPanel.add(searchButt);
buttPanel.add(resetButt);
frame.add(buttPanel, BorderLayout.SOUTH);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void search() {
JPanel panel = new JPanel(new FlowLayout());
JCheckBox cb = new JCheckBox("Selektive Suche");
panel.add(cb);
String text = JOptionPane.showInputDialog(panel);
if (cb.isSelected()) {
sorter.setRowFilter(RowFilter.regexFilter(text));
for (int i = 0; i < table.getRowCount(); i++) {
for (int j = 0; j < table.getColumnCount(); j++) {
System.out.println(table.getValueAt(i, j));
}
}
} else {
DefaultTableModel model = (DefaultTableModel) table.getModel();
for (int i = 0; i < model.getRowCount(); i++) {
for (int j = 0; j < model.getColumnCount(); j++) {
if (model.getValueAt(table.convertRowIndexToModel(i), table.convertColumnIndexToModel(j)).toString()
.indexOf(text) != -1) {
Rectangle r = table.getCellRect(i, 0, false);
table.scrollRectToVisible(r);
table.changeSelection(i, j, true, false);
for (int k = 0; k < table.getColumnCount(); k++) {
System.out.println(table.getValueAt(i, k));
}
}
}
}
}
}
private void createRowSorter(DefaultTableModel model) {
sorter = new TableRowSorter<DefaultTableModel>(model);
table.setRowSorter(sorter);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Tabellensuche());
}
}
Abhängig vom Auswahlzustand der Checkbox wird zwischen den
beiden Modi in einer Verzweigung unterschieden: Ist die Checkbox
selektiert, so wird eine Suche nach dem eingetragenen Text als
regulärem Ausdruck durchgeführt und die
Tabellendarstellung auf die Suchergebnisse beschnitten. Die Ausgabe
(oder ggf. Weiterverarbeitung) der Suchergebnisse erfolgt so, dass
die verbleibende Tabelle Zelle für Zelle durchlaufen und
ausgelesen wird.
Ist die Checkbox nicht selektiert, so erfolgt
die Suche etwas anders: Hier wird in einer geschachtelten Schleife
das Model durchlaufen. Der Inhalt jeder Tabellenzelle wird hierin
gegen den Inhalt des entsprechenden Modeleintrags getestet. Wichtig
ist hierbei, dass die Zellenindices durch die Methode convertColumnIndexToModel()
konvertiert werden. Der Hintergrund liegt darin begründet, dass
z.B. die Zeile 2 des Models nicht unbedingt der Zeile 2 der Tablle
entsprechen muss, z.B. nach einer Umsortierung, wie sie durch
Klicken auf den Tabellenkopf stattfinden kann.
Von der ersten
Zelle der passenden Zeile wird dann dessen Fläche als Rectangle
-Objekt ermittelt. Die Methode JComponent.scrollRectToVisible()
ermöglicht es dann, zu der gefundenen Position zu scrollen. Die
Methode JTable.table.changeSelection()
selektiert diese
dann. Der Methode werden vier Parameter übergeben: Neben dem
Zeilen- und Spaltenindex werden zwei boolean
Werte
erwartet, deren Kombinationen folgendes ermöglicht:
toggle | extend | Funktion |
---|---|---|
false | false | Lösche die bisherige Selektion und selektiere die neue Zelle |
false | true | Erweitere die bisherige Selektion bis zur angegebenen Zelle und lösche alle anderen Selektionen |
true | false | Kehre die Selektion der angegebenen Zelle ins Gegenteil um |
true | true | Übernimm den Selektionszustand der Ankerzelle zwischen diesem und der angegebenen Zelle |
Da die gesuchten Zeilen naturgemäß bislang nicht
selektiert sind, werden sie im Beispiel nach der dritten
Parameter-Variante selektiert. Zum Abschluss werden die
ausgewählten Zeilen Zelle für Zelle durchlaufen und
ausgegeben.
Ein mehrfaches Suchen und Markieren ist auf diese
Weise übrigens nicht möglich, da die Selektierten Zellen
bei einer erneuten Suche, die auch die bisher ausgewählten
Zeilen umfasst, deren Selektionszustand wiederum umkehrt, sodass
diese nun nicht mehr markiert sind. Dass die Suche dennoch
durchgeführt wird, zeigt die erfolgreiche Ausgabe. Im Beispiel
lässt sich das prima durch die Suche nach 'Fritz' und
'itz' nachvollziehen.
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.