# JTable getselectedrow liefert -1 wenn Focus verloren



## boorad (25. Mrz 2009)

Hallo,
nachdem ich meine Anwendung von JRE 1.4 auf 1.6 umgestellt habe bekomme ich Probleme mit dem Ermitteln der ausgewählten Zeile einer JTable. Es scheint so, dass getselectedRow -1 liefert weil der Focus nicht mehr auf der JTable ist. Ein Eintrag ist aber ausgewählt. Das hat in der JRE 1.4 funktioniert...
Kann mir hier jemand helfen?

Danke schonmal
Grüße
Matt


----------



## Ebenius (25. Mrz 2009)

Wäre mir neu. [Highlight=Java]final JTable table = new JTable(10, 10);
final JButton button =
      new JButton(new AbstractAction("Show Selection Data ...") {

        @SuppressWarnings("boxing")
        public void actionPerformed(ActionEvent e) {
          final String patt = "Selected Row: {0}\nSelected Column: {1}";
          final int row = table.getSelectedRow();
          final int col = table.getSelectedColumn();
          final String s = MessageFormat.format(patt, row, col);
          final Component comp = (Component) e.getSource();
          JOptionPane.showMessageDialog(SwingUtilities.getRoot(comp), s);
        }
      });
final JPanel panel = new JPanel(new BorderLayout(6, 6));
panel.add(button, BorderLayout.PAGE_END);
panel.add(new JScrollPane(table), BorderLayout.CENTER);

final JFrame f = new JFrame("Table Focus Fun");
f.setContentPane(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);[/Highlight]
Da machst Du also was anderes falsch. Schreib uns doch mal ein hübsches, knackiges, vollständiges Beispiel zum probieren.

Ebenius


----------



## boorad (25. Mrz 2009)

Das mit dem vollständigen Beispiel ist nicht so einfach: die Anwendung habe ich zur Weiterentwicklung übernommen und es handelt sich um ein recht kompliziertes System welches über recht viele Klassen verteilt ist.

Es wird beim Laden der JTable bzw. der Modeldaten ein 
*fireTableDataChanged();*
ausgeführt.
Das löst dann 2 *valueChanged* aus, wobei ich das 2. nicht nachvollziehen kann weil ich im Debugging bisher nichts gefunden habe was dazwischen an der JTable Selektion ändert. Beim 2. *valueChanged* ist dann der Wert von *ListSelectionEvent.**getFirstIndex* -1 -damit geht dann das Problem los.

Bin für jeden Hinweis dankbar.
Grüße
Matt


----------



## Ebenius (25. Mrz 2009)

Also nochmal langsam. Der Ablauf ist jetzt wie? Irgendwo wird das Modell vollständig neu bestückt (fireTableDataChanged() heißt ja, alles außer der Struktur hat sich geändert) und danach ist die Selektion leer? Das ist logisch und war auch bei Java 1.4 schon so.

FirstIndex und LastIndex im Event sagen nichts darüber aus, wie die Selektion aussieht, sondern stecken nur den Bereich ab, innerhalb dessen es eine Selektionsänderung gab. Beispiel: Selektiert waren Zeilen 1 und 4 und die Selektion wird geleert, dann kann der FirstIndex 1 sein und der LastIndex 4. Du musst schon das Modell fragen, welche Indices selektiert sind.

Kann es sein, dass der erste Event getValueIsAdjusting() == true hat? Dann kommt der zweite noch mit einem getValueIsAdjusting() == false nach. Oder die Selektion ändert sich tatsächlich ein zweites mal.

Ohne Quelltext kann man hier nur raten. Es wird wohl alles auf geduldiges Debugging hinauslaufen. Sofern keine Threading-Issues an dem Verhalten schuld sind (Modell asynchron zum Event Dispatch Thread geändert, oder ähnliches) kann ich mir ein unterschiedliches Verhalten zwischen Java 1.4 und Java 6 an dieser Stelle eher schwer vorstellen.

Ebenius


----------



## boorad (26. Mrz 2009)

Sooo, nun habe ich herausgefunden was das Problem war:
In *valueChanged* wurde ungünstig auf die Events reagiert. D.h. es wurde versucht mit *getselectedRow* einen gültigen Index zu ermitteln wenn es einen Unterschied zwischen *ListSelectionEvent.**getFirstIndex* und *ListSelectionEvent.**getLastIndex* gab. Die Gui ist dann bei der Verwendung des Indexwertes -1 abgestürzt.
Ich habe die Auswertung nun wie folgt umgestellt:
[highlight=Java]
public void valueChanged(ListSelectionEvent e) {
try {
ListSelectionModel lsm = (ListSelectionModel)e.getSource();
boolean bEmptySelection = lsm.isSelectionEmpty(); // Flag ist true wenn die Auswahl leer ist 

if (bEmptySelection == false){ // da mehrere Events kommen können nur bei denen mit gefüllter Auswahl reagieren
// da die JTable auf SingleSelection steht mus nicht in einem Bereich von Auswahlen gesucht werden
...
setWaitCursor();
int SelectionIndex = theProductTable.getSelectedRow(); // Index der Auswahl ermitteln
theModel.setSelectedItem(SelectionIndex);
}
} catch (Exception exc) {
...
}
}
[/highlight]
Also es wird nur der Index ermittelt wenn das Flag ListSelectionModel.isSelectionEmpty() false ist. 

Danke Ebenius

Grüße
Matt


----------

