Ich hab eine Methode, die alle markierten Reihen meiner JTable uploadTable entfernt:
int[] remRows = uploadTable.getSelectedRows();
for (int row : remRows) {
tableModel.removeRow(row);
}
}```
Jetzt möchte ich, dass nach dem Entfernen die Reihe selektiert ist, die nach der letzten zu löschenden Reihe kam.
**Beispiel:**
Vorher:
[IMG]http://www.abload.de/img/table-vorher1xz.png[/IMG]
Nachher:
[img]http://www.abload.de/img/table-nachher3b0.png[/img]
(gefärbt = selektiert)
Ich habe schon einige Stunden rumgebastelt, aber immer hatte der Code einen Haken...
Kann mir jemand helfen?
Gruß,
pcworld
PS: Ich schau mal, was ich noch an gebrauchbarem Code habe, um es euch nicht so schwer zu machen.
remRows = uploadTable.getSelectedRows();
System.out.print("remRows: ");
for (int row : remRows) {
System.out.print(row + " ");
}
System.out.println();
int lastSelectedRow = remRows[remRows.length - 1];
uploadTable.changeSelection(lastSelectedRow + 1, uploadTable
.getSelectedColumn(), false, false);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
for (int row : remRows) {
System.out.println("remove row: " + row);
tableModel.removeRow(row);
}
}
});
}```
Jedoch kommt da folgende Ausgabe mit Exception:
remRows: 0 1 3
remove row: 0
remove row: 1
remove row: 3
Exception occurred during event dispatching:
java.lang.ArrayIndexOutOfBoundsException: 3 >= 3
at java.util.Vector.removeElementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.removeRow(Unknown Source)
at gui.GUI$RemoveRowsListener$1.run(GUI.java:414)
…
Und wird da auch nicht alles korrekt gelöscht.
**Vorher:**
[IMG]http://www.abload.de/img/table-vorhercnx.png[/IMG]
**Nachher:**
[IMG]http://www.abload.de/img/table-nachher3q6.png[/img]
Wie man sieht, dürften eigentlich nur "C" und "E" übrig bleiben - so ist es aber nicht.
**Das Problem:**
In dem Moment, wenn eine Row gelöscht wird, ändern sich die Indexes und es werden die falschen Rows gelöscht...
Leider finde ich im **DefaultTableModel** nur ****eine**** [removeRow()-Methode](http://java.sun.com/javase/6/docs/api/javax/swing/table/DefaultTableModel.html#removeRow(int)), der man **einen** Integer übergeben kann, aber keine mit einem Integer-Array.
Gibt es trotzdem eine Aushilfe?
Klar, mit rumrechnen würde es gehen, aber ich hoffe, es geht einfacher...
Gruß,
pcworld
Hab den Code jetzt nochmal so erweitert, dass wenn die letzte Row selektiert ist, die vorletzte Reihe markiert wird.
int[] remRows = uploadTable.getSelectedRows();
int lastSelectedRow = remRows[remRows.length - 1];
int lastRow = uploadTable.getRowCount() - 1;
int selectedCol = uploadTable.getSelectedColumn();
if (lastRow > lastSelectedRow) {
uploadTable.changeSelection(lastSelectedRow + 1, selectedCol,
false, false);
} else if (lastRow == lastSelectedRow) {
uploadTable.changeSelection(lastSelectedRow - 1, selectedCol,
false, false);
}
for (int i = remRows.length - 1; i > -1; i--) {
int rowInModel = uploadTable.convertRowIndexToModel(remRows**);
tableModel.removeRow(rowInModel);
}
}```
Das funktioniert soweit.
Hab jetzt aber noch ein Problem:
**Vorher:**
[img]http://www.abload.de/img/table-vorherktj.png[/img]
**Nachher:**
[img]http://www.abload.de/img/table-nachherlho.png[/img]
Es ist keine Row selektiert!
**Das Problem:**
Es wird die Reihe über der letzten selektierten Reihe markiert, nämlich so, wie es im Code steht... - und die wird dann gelöscht. Dann ist natürlich keine Row mehr markiert!
Hab schon ein bisschen rumprobiert (s. [hier](http://nopaste.byte-welt.de/view.php?id=565)), konnte dieses Problem allerdings noch nicht lösen.
Könnt ihr mir weiterhelfen?
Gruß,
pcworld
Die Problemfälle treten ja ein, wenn vor dem Löschen die letzte Zeile selektiert ist.
Wir können dann einen boolean “selectLastRow” auf “true” setzen.
Nach dem Löschen selektieren wir in dem Fall einfach die letzte Zeile der Tabelle.
Hab es jetzt endlich hingekriegt… - damit ich an diesem Code nie mehr was ändern muss, und ich ihn mir hoffentlich nicht mehr ansehen muss, habe ich JTable erweitert…
Ich glaub, das ist einen Wiki-Beitrag wert
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class MyJTable extends JTable {
public MyJTable(TableModel model) {
setModel(model);
}
public void deleteSelectedRows() {
if (!(getModel() instanceof DefaultTableModel)) {
throw new UnsupportedOperationException(
"The TableModel must be a instance of DefaultTableModel.");
}
DefaultTableModel model = (DefaultTableModel) getModel();
int lastRow = getRowCount() - 1;
ArrayList<Integer> remRows = new ArrayList<Integer>();
for (int row : getSelectedRows()) {
remRows.add(row);
}
boolean isAllSelected = ((remRows.size() - 1) == lastRow);
if (remRows.size() == 0) {
return;
}
int lastSelectedRow = remRows.get(remRows.size() - 1);
int selectedColumn = getSelectedColumn();
int selectRow = -1;
boolean erfolg = false;
if (lastRow == lastSelectedRow && !isAllSelected) {
selectRow = lastSelectedRow;
while (!erfolg) {
erfolg = true;
selectRow--;
if (remRows.contains(selectRow)) {
erfolg = false;
}
}
} else if (lastSelectedRow < lastRow) {
selectRow = lastSelectedRow;
while (!erfolg) {
selectRow++;
erfolg = true;
if (remRows.contains(selectRow)) {
erfolg = false;
}
}
}
changeSelection(selectRow, selectedColumn, false, false);
// Rows löschen
for (int i = remRows.size() - 1; i > -1; i--) {
int rowInModel = convertRowIndexToModel(remRows.get(i));
model.removeRow(rowInModel);
}
}
}```
Hey,
das geht auch viel einfacher als du denkst. Ich hatte auch vor kurzem das selbe Problem.
ich gib dir einfach mal die Lösung und es erklärt sich von selbst denke ich ^^
//Es ist wichtig dass du getRow() zu einer variable zuweißt, denn nach jedem durchgang verändert sie sich ja. Es Funktioniert in kleineren Fällen auch ohne eine Variable aber mach es lieber mit.
if(jTableAusgabeModel.getRowCount()>=1) // Ich wollte die erste Zeile immer behalten, als Spalten name sozusagen {
for(int i=0;i<rows;i++)
((DefaultTableModel) jTableAusgabeModel).removeRow(0);
}```
@Unregistriert:
Dein Code ist so viel ich weiß nur dazu da, um tatsächlich die Reihen zu entfernen.
Mir ging es darum, dass nach dem Entfernen einer Reihe noch irgendwo der Fokus auf einer Reihe liegt, und das möglichst sinnvoll.