Java 如何通知TableCellEditor表行已删除?
我尝试实现一个TableCellEditor,它包含一些字段和一个delete按钮。它工作正常,但删除行时,已删除单元格中的内容(使用TableCellEditor呈现)不会更新 我尝试在删除行时调用模型中的Java 如何通知TableCellEditor表行已删除?,java,swing,jtable,tablecelleditor,abstracttablemodel,Java,Swing,Jtable,Tablecelleditor,Abstracttablemodel,我尝试实现一个TableCellEditor,它包含一些字段和一个delete按钮。它工作正常,但删除行时,已删除单元格中的内容(使用TableCellEditor呈现)不会更新 我尝试在删除行时调用模型中的fireTableRowsDeleted(row,row)和fireTableDataChanged(),但它似乎没有通知TableCellEditor。当我选择另一行时,行索引会再次使用TableCellRenderer呈现 关于删除时如何通知TableCellEditor有什么建议吗 按
fireTableRowsDeleted(row,row)
和fireTableDataChanged()
,但它似乎没有通知TableCellEditor。当我选择另一行时,行索引会再次使用TableCellRenderer呈现
关于删除时如何通知TableCellEditor有什么建议吗
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();
}
});
}
}
公共类StringTableDemo扩展JFrame{
公共StringTableDemo(){
最终StringTableModel模型=新StringTableModel();
模型。addRow(“Jonas”);
model.addRow(“你好”);
模型。addRow(“世界”);
RenderAndEditor RenderAndEditor=新的RenderAndEditor(模型);
JTable table=新的JTable(模型);
表.setDefaultRenderer(Record.class、renderAndEditor);
table.setDefaultEditor(Record.class、renderAndEditor);
添加(新的JScrollPane(表),BorderLayout.CENTER);
包装();
setDefaultCloseOperation(关闭时退出);
setVisible(真);
}
课堂记录{
字符串字符串;
布尔值被删除;
}
类StringTableModel扩展了AbstractTableModel{
私有最终列表数据=新的ArrayList();
@凌驾
public int getColumnCount(){
返回1;
}
@凌驾
public int getRowCount(){
返回data.size();
}
@凌驾
公共对象getValueAt(int行,int列){
返回数据.get(行);
}
@凌驾
公共类getColumnClass(int列){
返回记录.class;
}
@凌驾
公共布尔值可编辑(int行,int列){
返回true;
}
@凌驾
public void setValueAt(对象有效、整行、整列){
if(记录的有效实例){
记录r=(记录)aValue;
如果(!r.isDeleted){
数据集(行,r);
fireTableRowsUpdated(行、列);
}
}否则抛出新的非法状态异常(“aValue不是记录”);
}
public void addRow(字符串s){
记录r=新记录();
r、 字符串=s;
r、 isDeleted=假;
数据。添加(r);
fireTableRowsInserted(data.size()-1,data.size()-1);
}
公共无效清除器OW(int行){
数据删除(行);
//fireTableRowsDeleted(行,行);
fireTableDataChanged();
系统输出打印项次(“行”+行+“删除”);
}
}
类CellPanel扩展了JPanel{
私人最终行动removeAction=新抽象行动(“x”){
@凌驾
已执行的公共无效操作(操作事件arg0){
模型.指数;
isDeleted=真;
}
};
私有最终JButton removeBtn=新JButton(removeAction);
私有最终JTextField=新JTextField();
私有最终模型;
私有整数索引;
私有布尔值isDeleted=false;
公共单元面板(StringTableModel){
超级(新边框布局());
this.model=模型;
添加(字段、边框布局、中心);
添加(删除BTN,BorderLayout.EAST);
}
公共记录getRecord(){
记录r=新记录();
r、 string=field.getText();
r、 isDeleted=isDeleted;
返回r;
}
公共无效集合记录(记录r,整数索引){
field.setText(r.string);
这个指数=指数;
}
}
类RenderAndEditor扩展了AbstractCellEditor实现
TableCellEditor,TableCellRenderer{
私人最终CellPanel渲染器;
私人小组编辑;
公共渲染器和编辑器(StringTableModel模型){
渲染器=新单元面板(模型);
编辑器=新单元面板(模型);
}
@凌驾
公共对象getCellEditorValue(){
返回editor.getRecord();
}
@凌驾
公共组件GetTableCellRenderComponent(JTable表,
对象值,布尔isSelected,布尔hasFocus,
整数行,整数列){
renderer.setRecord((记录)值,行);
返回渲染器;
}
@凌驾
公共组件getTableCellEditorComponent(JTable表,
对象值,布尔值(选定,int行,int列){
editor.setRecord((记录)值,行);
返回编辑器;
}
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
新的StringTableDemo();
}
});
}
}
这是因为当您单击删除按钮时,单元格编辑器
没有注意到它必须停止编辑单元格
一个简单的解决方案是向CellEditor
添加另一个ActionListener
,并在每次单击它时调用StopCellEdit()
。这应该起作用:
public RendererAndEditor( StringTableModel model )
{
renderer = new CellPanel( model );
editor = new CellPanel( model );
editor.getRemoveBtn().addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
stopCellEditing();
}
});
}
顺便说一句,你的编辑是implem