Ich hab in einer komplexeren Anwendung das seltsame Problem, dass manchmal der Klick in eine Tabelle dergestalt nicht weitergereicht wird, dass zwar die Selektion dieser Zeile in der Tabelle selbst angezeigt wird, aber die Daten aus dieser Zeile nicht dargestellt werden.
Nach längeren versuchen mit synchronized
(da ich erst dachte, sich zeitlich überschneidende Aufrufe von mouseClicked()
wären Schuld) und Analysen dessen, was ich nach dem Tabellenklick anstelle, bin ich dann darauf gekommen, dass das Problem in tieferen Schichten liegen muss.
Hier ein Testprogramm:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
public class TableClickNotPassed {
static class TableEntry {
private String code;
private String contents;
public TableEntry(String code, String contents) {
this.code = code;
this.contents = contents;
}
public String getCode() {
return code;
}
public String getContents() {
return contents;
}
}
public class MyTableModel extends AbstractTableModel {
private static final long serialVersionUID = -1669485540341234132L;
private List<TableEntry> entryList;
public MyTableModel() {
super();
entryList = new ArrayList<TableEntry>();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public int getRowCount() {
return entryList.size();
}
@Override
public Object getValueAt(int row, int column) {
String value = "";
switch (column) {
case 0:
value = entryList.get(row).getCode();
break;
case 1:
value = entryList.get(row).getContents();
break;
}
return value;
}
public void clear() {
entryList.clear();
}
public void addEntry(TableEntry entry) {
entryList.add(entry);
}
}
private JTable myTable;
private JFrame frame;
private JTextField textField;
private List<TableEntry> data;
public TableClickNotPassed() {
data = createTestData();
frame = new JFrame();
frame.setLayout(new BorderLayout());
textField = new JTextField();
frame.add(textField, BorderLayout.NORTH);
MyTableModel tableModel = new MyTableModel();
fillTableModel(tableModel, data);
myTable = new JTable(tableModel, createTableColumnModel());
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
myTable.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent event) {
int row = myTable.rowAtPoint(event.getPoint());
System.out.println("mouseClicked: " + row);
if (row > -1) {
textField.setText(data.get(row).getContents());
}
}
});
JScrollPane scrollPane = new JScrollPane(myTable);
scrollPane.setPreferredSize(new Dimension(400, 300));
frame.add(scrollPane, BorderLayout.CENTER);
frame.setLocation(100, 100);
frame.pack();
}
private static List<TableEntry> createTestData() {
List<TableEntry> entries = new ArrayList<>();
entries.add(new TableEntry("001", "Aaaaaaaaaaaaaaaaaaaaa"));
entries.add(new TableEntry("002", "Bbbbbbbbbbbbbbbbbbbbb"));
return entries;
}
private static DefaultTableColumnModel createTableColumnModel() {
DefaultTableColumnModel columnModel1 = new DefaultTableColumnModel();
TableColumn col1 = new TableColumn(0, 50);
col1.setHeaderValue("Code");
col1.setMaxWidth(50);
columnModel1.addColumn(col1);
TableColumn col2 = new TableColumn(1, 350);
col2.setHeaderValue("Beschreibung");
columnModel1.addColumn(col2);
return columnModel1;
}
private static void fillTableModel(MyTableModel tableModel,
List<TableEntry> entries) {
for (TableEntry entry : entries) {
tableModel.addEntry(entry);
}
tableModel.fireTableDataChanged();
}
public void setVisible(boolean visble) {
frame.setVisible(visble);
}
public static void main(String[] args) {
TableClickNotPassed demo = new TableClickNotPassed();
demo.setVisible(true);
}
}
Normalerweise wird der unter Beschreibung in der Tabellenzeile angezeigte Text im Textfeld oben angezeigt. Klickt man lange und schnell genug zwischen den Tabellenzeilen hin und her, kann es vorkommen, dass z.B. die zweite Zeile Selektiert wird und im Textfeld noch der Inhalt der ersten Zeile angezeigt wird.
Die Testausgabe auf der Konsole endet auch entsprechend mit mouseClicked: 0
, was bedeutet, dass mouseClicked()
in diesem Fall nicht aufgerufen wurde.
Zur Verdeutlichung ein Bild: