# Per KeyListener Zeilen aus JTable löschen



## Felix (21. Jun 2008)

Hallo zusammen,

kann mir jemand erklären, warum bei folgendem Code in der JTable nicht die ganze Zeile, sondern die Zeile bis auf die selektierte Zelle und die Zelle unter der selektierten Zelle gelöscht werden? Das ist absolut seltsam...


```
public void keyReleased(KeyEvent ke) {
	if (ke.getKeyCode() == KeyEvent.VK_DELETE) { // Key festlegen
		if (ke.getSource() == table && table.getSelectedRow() > -1) { // Source festlegen

			if (JOptionPane
					.showConfirmDialog(this,
							"Wollen Sie die Vokabel wirklich löschen?",
							"löschen?", JOptionPane.YES_NO_OPTION,
							JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {

				model.removeRow(table.getSelectedRow());
			}
		}
	}
}
```

Gruß
der Felix


----------



## Felix (22. Jun 2008)

Oder was natürlich noch besser wäre: gibt es eine JTable, die das schon automatisch kann, und in der ich zB auch meine Zeilen ordnen kann?


----------



## Wildcard (22. Jun 2008)

Aus deinem Code geht das Problem nicht hervor.
Tabellen sortiert man mit einem RowSorter


----------



## Felix (22. Jun 2008)

Ja schon, aber ich mach ja nicht mehr. Das ist es ja, was mich so verwundert... Welche möglichen Ursachen gibt es denn noch dafür, bzw. welcher Code sollte den Fehler verursachen? Ich denke nicht, dass es an Java im allgemeinen liegt, oder?


----------



## Wildcard (22. Jun 2008)

Felix hat gesagt.:
			
		

> Ich denke nicht, dass es an Java im allgemeinen liegt, oder?


Du denkst richtig.


----------



## Felix (22. Jun 2008)

Das ist mir jetzt keine große Hilfe , aber trotzdem danke!


----------



## Wildcard (22. Jun 2008)

Ich sag doch, der Fehler ist aus diesem Code nicht ersichtlich.
Poste ein lauffähiges kurzes Beispiel, das dein Problem demonstriert.


----------



## Felix (22. Jun 2008)

Alles klar, gerne:


```
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class TableTest extends JFrame implements KeyListener,
		TableModelListener {

	private DefaultTableModel model = new DefaultTableModel();

	private JTable table = new JTable(model);

	public static void main(String[] args) {
		new TableTest();
	}

	public TableTest() {
		this.add(table);
		model.addColumn("Column1");
		model.addColumn("Column2");
		model.addColumn("Column3");
		model.addColumn("Column4");
		String[] s1 = { "test1", "test01", "01", "1" };
		model.addRow(s1);
		String[] s2 = { "test2", "test02", "02", "2" };
		model.addRow(s2);
		String[] s3 = { "test3", "test03", "03", "3" };
		model.addRow(s3);
		String[] s4 = { "test4", "test04", "04", "4" };
		model.addRow(s4);
		String[] s5 = { "test5", "test05", "05", "5" };
		model.addRow(s5);
		model.addTableModelListener(this);
		table.addKeyListener(this);
		this.setSize(500, 500);
		this.setVisible(true);
	}

	public void keyPressed(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void keyReleased(KeyEvent ke) {
		if (ke.getKeyCode() == KeyEvent.VK_DELETE) { // Key festlegen
			if (ke.getSource() == table && table.getSelectedRow() > -1) { // Source
				if (JOptionPane
						.showConfirmDialog(this,
								"Wollen Sie die Zeile wirklich löschen?",
								"löschen?", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {

					model.removeRow(table.getSelectedRow());
				}
			}
		}
	}

	public void keyTyped(KeyEvent arg0) {
		// TODO Auto-generated method stub

	}

	public void tableChanged(TableModelEvent tme) {
		if (tme.getType() == TableModelEvent.UPDATE && tme.getFirstRow() > -1
				&& tme.getColumn() > -1
				&& tme.getLastRow() < model.getRowCount()
				&& tme.getColumn() < model.getColumnCount()) {

			String s = (String) table.getValueAt(tme.getFirstRow(), tme
					.getColumn());
			if (s.equals("")) {
				if (JOptionPane
						.showConfirmDialog(this,
								"Wollen Sie die Zeile wirklich löschen?",
								"löschen?", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {

					model.removeRow(tme.getFirstRow());

				}
			}
		}
	}
}
```

Es gibt jetzt 2 Möglichkeiten eine Zeile zu löschen:

makieren der Zeile und "Entf"-Taste drücken (hier tritt das Problem auf)
irgendeinen Zelleninhalt mit einem leeren String versehen (hier tritt das Problem nicht auf)


----------



## Wildcard (22. Jun 2008)

Der KeyCode kollidiert mit einem anderen KeyBinding.
So funktioniert's richtig:

```
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

public class TableTest extends JFrame implements TableModelListener {

	private DefaultTableModel model = new DefaultTableModel();

	private JTable table = new JTable(model);

	public static void main(String[] args) {
		new TableTest();
	}

	public TableTest() {
		this.add(table);
		model.addColumn("Column1");
		model.addColumn("Column2");
		model.addColumn("Column3");
		model.addColumn("Column4");
		String[] s1 = { "test1", "test01", "01", "1" };
		model.addRow(s1);
		String[] s2 = { "test2", "test02", "02", "2" };
		model.addRow(s2);
		String[] s3 = { "test3", "test03", "03", "3" };
		model.addRow(s3);
		String[] s4 = { "test4", "test04", "04", "4" };
		model.addRow(s4);
		String[] s5 = { "test5", "test05", "05", "5" };
		model.addRow(s5);
		model.addTableModelListener(this);
		table.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0),
				"remove row");
		table.getActionMap().put("remove row", new AbstractAction() {

			public void actionPerformed(ActionEvent e) {
				model.removeRow(table.getSelectedRow());

			}

		});
		this.setSize(500, 500);
		this.setVisible(true);
	}

	public void tableChanged(TableModelEvent tme) {
		if (tme.getType() == TableModelEvent.UPDATE && tme.getFirstRow() > -1
				&& tme.getColumn() > -1
				&& tme.getLastRow() < model.getRowCount()
				&& tme.getColumn() < model.getColumnCount()) {

			String s = (String) table.getValueAt(tme.getFirstRow(), tme
					.getColumn());
			if (s.equals("")) {
				if (JOptionPane
						.showConfirmDialog(this,
								"Wollen Sie die Zeile wirklich löschen?",
								"löschen?", JOptionPane.YES_NO_OPTION,
								JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {

					model.removeRow(tme.getFirstRow());

				}
			}
		}
	}
}
```

Merke: wenn du für Taste XY etwas ausführen möchtest, verwende ein KeyBinding. KeyListener sind ein Low-Level Mechanismus, der fast nur für irgendwelche Mini-Spiele Sinn macht.


----------



## Felix (22. Jun 2008)

Perfekt, danke! Ich hab zwar von KeyBinding bis jetzt noch nie was gehört, aber es klappt super, und ich werde mich mal informieren.  :toll:


----------

