gpt4 book ai didi

java - 如何通知 TableCellEditor 表行已删除?

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:23:51 25 4
gpt4 key购买 nike

我尝试实现一个包含一些字段和删除按钮的 TableCellEditor。它运行良好,但当行被删除时,被删除单元格中的内容(使用 TableCellEditor 呈现)更新。

当删除行时,我尝试在模型中同时调用 fireTableRowsDeleted(row, row)fireTableDataChanged(),但它似乎没有通知表格单元格编辑器。当我选择另一行时它起作用,并且行索引再次使用 TableCellRenderer 呈现。

关于如何在删除时通知 TableCellEditor 有什么建议吗?

  1. 按下删除按钮

    enter image description here

  2. 行已删除,但 CellEditor 内容未更新

    enter image description here

  3. 当再次使用 CellRenderer 时,行内容已更新。

    enter image description here

代码如下:

public class StringTableDemo extends JFrame {

public StringTableDemo() {

final StringTableModel model = new StringTableModel();
model.addRow("Jonas");
model.addRow("Hello");
model.addRow("World");

RendererAndEditor rendererAndEditor = new RendererAndEditor(model);

JTable table = new JTable(model);
table.setDefaultRenderer(Record.class, rendererAndEditor);
table.setDefaultEditor(Record.class, rendererAndEditor);

add(new JScrollPane(table), BorderLayout.CENTER);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}

class Record {
String string;
boolean isDeleted;
}

class StringTableModel extends AbstractTableModel {

private final List<Record> data = new ArrayList<Record>();

@Override
public int getColumnCount() {
return 1;
}

@Override
public int getRowCount() {
return data.size();
}

@Override
public Object getValueAt(int row, int column) {
return data.get(row);
}

@Override
public Class<?> getColumnClass(int column) {
return Record.class;
}

@Override
public boolean isCellEditable(int row, int column) {
return true;
}

@Override
public void setValueAt(Object aValue, int row, int column) {
if(aValue instanceof Record) {
Record r = (Record)aValue;
if(!r.isDeleted) {
data.set(row, r);
fireTableRowsUpdated(row, column);
}
} else throw new IllegalStateException("aValue is not a Record");
}

public void addRow(String s) {
Record r = new Record();
r.string = s;
r.isDeleted = false;
data.add(r);
fireTableRowsInserted(data.size()-1, data.size()-1);
}

public void removeRow(int row) {
data.remove(row);
//fireTableRowsDeleted(row, row);
fireTableDataChanged();

System.out.println("row " + row + " deleted");
}

}

class CellPanel extends JPanel {
private final Action removeAction = new AbstractAction("x") {

@Override
public void actionPerformed(ActionEvent arg0) {
model.removeRow(index);
isDeleted = true;
}

};
private final JButton removeBtn = new JButton(removeAction);
private final JTextField field = new JTextField();
private final StringTableModel model;
private int index;
private boolean isDeleted = false;
public CellPanel(StringTableModel model) {
super(new BorderLayout());
this.model = model;
add(field, BorderLayout.CENTER);
add(removeBtn, BorderLayout.EAST);
}

public Record getRecord() {
Record r = new Record();
r.string = field.getText();
r.isDeleted = isDeleted;
return r;
}

public void setRecord(Record r, int index) {
field.setText(r.string);
this.index = index;
}
}

class RendererAndEditor extends AbstractCellEditor implements
TableCellEditor, TableCellRenderer {

private final CellPanel renderer;
private final CellPanel editor;

public RendererAndEditor(StringTableModel model) {
renderer = new CellPanel(model);
editor = new CellPanel(model);
}

@Override
public Object getCellEditorValue() {
return editor.getRecord();
}

@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row, int column) {

renderer.setRecord((Record)value, row);
return renderer;
}

@Override
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
editor.setRecord((Record)value, row);
return editor;
}

}


public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new StringTableDemo();
}

});
}
}

最佳答案

那是因为当您点击删除按钮时,您的 CellEditor 没有注意到它必须停止编辑单元格。

一个简单的解决方案是将另一个 ActionListener 添加到您的 CellEditor 并在您每次单击它时调用 stopCellEditing()。这应该有效:

public RendererAndEditor( StringTableModel model )
{
renderer = new CellPanel( model );
editor = new CellPanel( model );

editor.getRemoveBtn().addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
stopCellEditing();
}
});
}

关于java - 如何通知 TableCellEditor 表行已删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8801210/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com