KeyListener in JTable reagiert nicht

Hallo!

Habe eine GUI, auf der ein JTable ist, und ein KeyListener soll mich benachrichtigen, wenn eine Taste gedrückt wurde, wenn eine Row (oder was anderes auf der JTable) markiert ist. Leider funktioniert das bei meinem Code komischerweise nicht. Ich habe den KeyListener auch auf andere Components im Fenster hinzugefügt, will aber auch nicht reagieren. Bei einem JTextField gings komischerweise…

Der Code: {{Toten externen Link entfernt}} - s. Zeile 88

Habe öfters versucht, den Code fürs Forum so klein wie möglich zu halten, aber immer, wenn ich das getan habe, hat’s funktioniert… :confused:
Deswegen hab ich mal den ganzen Code gepostet.

[War zu lang fürs Forum, ist hier auf 11000 Zeichen begrenzt :D]

Gruß,
pcworld

Mit der Abfrage “if (e.getKeyCode() == KeyEvent.VK_DELETE)” in “keyPressed” funktioniert es bei mir.
Beispiel: GUI.jar (Quellcode im jar)

Danke für die Antwort!

Bei mir funktioniert komischerweise dein Beispiel auch… - was hast du verändert bzw. hast du was verändert?

Gruß,
pcworld

Ich hab den Fehler gefunden.

Dieser JLabelEditor (s. Z. 84) wird sofort aufgerufen, wenn der User auf eine Zelle klickt. Man kann keinen Text editieren, aber er soll bewirken, dass man Text in einer Zelle markieren kann.
Und jetzt ist das also so: Immer, wenn man eine Reihe selektiert, wird gleichzeitig der JLabelEditor aufgerufen, und so ist nicht die Table im Focus, sondern der Editor.

Der Editor: s. http://wiki.byte-welt.de/wiki/Markierbarer_Text_in_den_Zellen_einer_JTable

Wäre es jetzt die beste Lösung, wenn ich dem Editor einen Listener hinzufüge, und dann immer die selektierten Reihen der JTable abfrage? Was anderes ist mir nicht eingefallen.

[QUOTE=pcworld]so ist nicht die Table im Focus, sondern der Editor.
…Wäre es jetzt die beste Lösung, wenn ich dem Editor einen Listener
hinzufüge, und dann immer die selektierten Reihen der JTable abfrage?
Was anderes ist mir nicht eingefallen.[/QUOTE]
Was anderes bleibt uns in dem Fall wohl nicht übrig ;).
Beispiel:

public class JLabelEditor extends JTextField implements TableCellEditor {
    private JTable uploadTable;
    public JLabelEditor() {
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_DELETE) {
                    int[] indexes = uploadTable.getSelectedRows();
                    MyDefaultTableModel tableModel = (MyDefaultTableModel) uploadTable.getModel();
                    for (int i = indexes.length - 1; i > -1; i--) {
                        int index = indexes**;
                        tableModel.removeRow(index);
                    }
                }
            }
        });
...
    }
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        uploadTable = table;
...```

[QUOTE=AndreUhres]Was anderes bleibt uns in dem Fall wohl nicht übrig ;).
Beispiel:

public class JLabelEditor extends JTextField implements TableCellEditor {
    private JTable uploadTable;
    public JLabelEditor() {
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_DELETE) {
                    int[] indexes = uploadTable.getSelectedRows();
                    MyDefaultTableModel tableModel = (MyDefaultTableModel) uploadTable.getModel();
                    for (int i = indexes.length - 1; i > -1; i--) {
                        int index = indexes**;
                        tableModel.removeRow(index);
                    }
                }
            }
        });
...
    }
    public Component getTableCellEditorComponent(JTable table, Object value,
            boolean isSelected, int row, int column) {
        uploadTable = table;
...```[/QUOTE]

Danke erstmal!

Wär es besser, wenn ich meinen alten Listener bei der JTable lass und dem JLabelEditor (mittlerweile MarkableCellEditor) einen neuen KeyListener geb, der die JTable benachrichtigt (über getKeyListeners() usw.)... - oder ist es vielleicht noch besser, wenn ich einfach der JTable **und** dem Editor das gleiche Listener-Objekt übergebe?

Gruß,
pcworld

Hab es jetzt folgendermaßen gemacht (s. gleich):
Hab aber noch ein Problem - wenn ich [Entf] drücke, kommt zwar “keyTyped()” auf der Kommandozeile, aber “VK_DELETE” erscheint nicht, und die selektierten Rows werden auch nicht gelöscht.

Der Listener:


    private RemoveRowListener removeRowListener = new RemoveRowListener();

    private class RemoveRowListener extends KeyAdapter {

        @Override
        public void keyTyped(KeyEvent e) {
            System.out.println("keyTyped()");
            if (e.getKeyCode() == KeyEvent.VK_DELETE) {
                System.out.println("VK_DELETE");
                for (int row : uploadTable.getSelectedRows()) {
                    tableModel.removeRow(row);
                }
            }
        }
    }
    ...
}```

**Listener vom Editor:**
```uploadTable.setDefaultEditor(JLabel.class, new MarkableCellEditor() {
                    private JTable table;
                
                    {
                        addKeyListener(removeRowListener);
                    }
                    
                    @Override
			public Component getTableCellEditorComponent(JTable table,
					Object value, boolean isSelected, int row, int column) {
                            for(KeyListener l : table.getKeyListeners()) {
                            }
                                this.table = table;
				selectAll();
				return super.getTableCellEditorComponent(table, value,
						isSelected, row, column);
			}
		});```

**Der Listener der Table:**
```uploadTable.addKeyListener(removeRowListener);```

[QUOTE=AndreUhres;6211]Mit der Abfrage „if (e.getKeyCode() == KeyEvent.VK_DELETE)“ in „keyPressed“ funktioniert es bei mir.
Beispiel: GUI.jar (Quellcode im jar)[/QUOTE]

OK, dann guck ich nochmal in deinem Code.

Gruß,
pcworld

Achso, jetzt fällt’s mir wieder ein… - der JLabelEditor…:

Aber ich weiß schon, wie ich’s hinkriegen kann - muss nur von meiner Lösung, die ich am liebsten gehabt hätte, abweichen… :slight_smile:

import java.awt.Component;
import java.util.EventObject;
 
import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.table.TableCellEditor;
 
public class JLabelEditor extends JTextField implements TableCellEditor {
 
	public JLabelEditor() {
		setEditable(false);
		// Die Selektier-Farbe ist standardmäßig die gleiche Farbe wie die von
		// selektierten Zellen - das könnte den User durcheinanderbringen.
		// Deswegen als SelectionColor ein helleres blau.
		// Markierter Text erhält die Textfarbe weiß.
		setSelectionColor(new Color(132, 112, 255));
		setSelectedTextColor(Color.WHITE);
		// Es soll kein Rand wie bei einem normalen Textfeld erscheinen
		setBorder(BorderFactory.createEmptyBorder());
	}
 
	public Component getTableCellEditorComponent(JTable table, Object value,
			boolean isSelected, int row, int column) {
		setText(value.toString());
		return this;
	}
 
	public void cancelCellEditing() {
		// ignorieren
	}
 
	public Object getCellEditorValue() {
		// Gibt den aktuellen Wert des Editors zurück (auch wenn er sich nicht
		// ändern kann)
		return getText();
	}
 
	public boolean isCellEditable(EventObject anEvent) {
		// Die Zelle ist nach einem Klick auf die Zelle sofort "editierbar"
		// (bzw. "markierbar")
		return true;
	}
 
	public void addCellEditorListener(CellEditorListener l) {
		// ignorieren
	}
 
	public void removeCellEditorListener(CellEditorListener l) {
		// ignorieren
	}
 
	public boolean shouldSelectCell(EventObject anEvent) {
		return true;
	}
 
	public boolean stopCellEditing() {
		// ignorieren
		return true;
	}
 
}```

Aktueller Code: http://nopaste.byte-welt.de/view.php?id=558
In Zeile 65 kommt der KeyListener.

Also der KeyCode ist ja schonmal nicht VK_DELETE - dann hab ich mal geschaut, was KeyCode ist. Und - er ist - immer 0. Egal welche Taste gedrückt wurde!
Ich versteh Java langsam nicht mehr… :frowning:

Gruß,
pcworld

Bitte beachte (ich hab in diesem Thread schon wiederholt darauf aufmerksam gemacht),
daß die KeyTyped Events keine KeyCode Informationen haben;
sie haben auch keine Modifier Informationen. Wenn wir wissen wollen,
welche Tasten der User drückt/loslässt, müssen wir die KeyPressed/KeyReleased Events verarbeiten.

Danke!

Jetzt funktioniert es.

Gruß,
pcworld