JTable: ploetzlich ist der CellEditor weg? :(

Status
Nicht offen für weitere Antworten.

richardcurtle

Bekanntes Mitglied
Hi,

Ich habe eine Tabelle. Fuer Column mit Index 0 hab ich einen speziellen ComboboxEditor gesetzt. Eine JComboBox.

Wenn ich die letzte Column entferne ist auch dieser JComboBox Editor weg 🙁

1. Kann mir jemand erklaeren was genau ablaeuft? Warum ist der ComboboxEditor weg?

2. Mach ich was falsch wenn ich die Column entferne?

3. Hat jemand eine Idee wie ich das Problem beheben kann? Ich wuerde ungern nochmal den CellEditor auf Index 0 setzen.


[HIGHLIGHT="Java"]
package framework.uifactories;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Enumeration;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

public class MyTableDemo extends JPanel {
JTable table;
private MyOwnTableModel model;

private JButton button;

public MyTableDemo() {
super(new BorderLayout());
table = new JTable();

table.setFillsViewportHeight(true);
table.setColumnSelectionAllowed(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);



// Add table and a Button panel to the frame
// table.setPreferredSize(new Dimension(600,200));
table.setPreferredScrollableViewportSize(new Dimension(100, 100));
JScrollPane scrollPane = new JScrollPane(table);
this.add(scrollPane);
}

public void setModel(MyOwnTableModel m) {
System.err.println("setModel -> " + m);
this.model = m;
table.setModel(model);

JPanel buttonPanel = new JPanel();
this.add(buttonPanel, BorderLayout.SOUTH);

button = new JButton(new RemoveColumnAction("Remove Column"));
// button.setEnabled(false);
buttonPanel.add(button);

TableColumn column = table.getColumnModel().getColumn(0);
JComboBox comboBox = new JComboBox(new String[]{"one","two","three"});
comboBox.setBorder(BorderFactory.createEmptyBorder());
column.setCellEditor(new DefaultCellEditor(comboBox));
}


private final class RemoveColumnAction extends AbstractAction {

public RemoveColumnAction(String text) {
super(text);
}

public void actionPerformed(ActionEvent e) {
removeColumnAndData(table, table.getColumnCount()-1);
table.requestFocusInWindow();
}
}


public void removeColumnAndData(JTable table, int vColIndex) {
MyOwnTableModel model = (MyOwnTableModel)table.getModel();
TableColumn col = table.getColumnModel().getColumn(vColIndex);
int columnModelIndex = col.getModelIndex();
Vector data = model.getDataVector();
Vector colIds = model.getColumnIdentifiers();

// Remove the column from the table
table.removeColumn(col);

// Remove the column header from the table model
colIds.removeElementAt(columnModelIndex);

// Remove the column data
for (int r=0; r<data.size(); r++) {
Vector row = (Vector)data.get(r);
row.removeElementAt(columnModelIndex);
}
model.setDataVector(data, colIds);

// Correct the model indices in the TableColumn objects
// by decrementing those indices that follow the deleted column
Enumeration e = table.getColumnModel().getColumns();
for (; e.hasMoreElements(); ) {
TableColumn c = (TableColumn)e.nextElement();
if (c.getModelIndex() >= columnModelIndex) {
c.setModelIndex(c.getModelIndex()-1);
}
}
model.fireTableStructureChanged();
}

// This subclass adds a method to retrieve the columnIdentifiers
// which is needed to implement the removal of
// column data from the table model
static class MyOwnTableModel extends DefaultTableModel {
public Vector getColumnIdentifiers() {
return columnIdentifiers;
}
}








public static void main(String[] args) {
Object[][] dataVector = new Object[][] {
{ "one", 1324f, 9640821 },
{ "two", 1133f, 3287263 },
{ "three", 304f, 9629091 },
};
String[] columnIdentifiers = new String[] { "Country", "Population (mil)", "Area (km2)"};


MyOwnTableModel model = new MyOwnTableModel();
model.setDataVector(dataVector, columnIdentifiers);

MyTableDemo panel = new MyTableDemo();
panel.setModel(model);

JFrame frame = new JFrame();
frame.setContentPane(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(400,300));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

[/HIGHLIGHT]
 
Zuletzt bearbeitet:
Das Problem ist "fireTableStructureChanged". Die JTable wird damit angewiesen alles zu vergessen was sie über das Model weiss und sich neu aufzubauen. Dabei werden auch die alten Columns gelöscht und durch neue ersetzt. Damit geht auch deine Einstellung verloren.

Eine Lösung wäre mit JTable#setDefaultEditor dein Editor für eine bestimmte Klasse zu registrieren, und in TableModel#getColumnClass dann diese Klasse für die Column 0 zurückzugeben.

Eine nicht so tolle Lösung wäre den Editor immer wieder neu zu setzen.
 
Das Problem ist "fireTableStructureChanged". Die JTable wird damit angewiesen alles zu vergessen was sie über das Model weiss und sich neu aufzubauen. Dabei werden auch die alten Columns gelöscht und durch neue ersetzt. Damit geht auch deine Einstellung verloren.

Eine Lösung wäre mit JTable#setDefaultEditor dein Editor für eine bestimmte Klasse zu registrieren, und in TableModel#getColumnClass dann diese Klasse für die Column 0 zurückzugeben.

Eine nicht so tolle Lösung wäre den Editor immer wieder neu zu setzen.

Danke. Durch Ausprobieren habe ich jedesmal den Editor neu gesetzt. Nur wenn ich ihn nach fireTableStructureChanged setzte klappts auch.

Deinen besseren Vorschlag werde ich mir gerne durch den Kopf gehen lassen.

Vielen Dank!
 
Das Problem ist "fireTableStructureChanged". Die JTable wird damit angewiesen alles zu vergessen was sie über das Model weiss und sich neu aufzubauen. Dabei werden auch die alten Columns gelöscht und durch neue ersetzt. Damit geht auch deine Einstellung verloren.

Eine Lösung wäre mit JTable#setDefaultEditor dein Editor für eine bestimmte Klasse zu registrieren, und in TableModel#getColumnClass dann diese Klasse für die Column 0 zurückzugeben.

Eine nicht so tolle Lösung wäre den Editor immer wieder neu zu setzen.


getColumnClass??? Hat TableModel so eine Methode ueberhaupt?
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben