ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2019-11-01 22:02:24  阅读:234  来源: 互联网

标签:swing jtable abstracttablemodel tablecelleditor java


我尝试实现一个TableCellEditor,该表包含一些字段和一个删除按钮.效果很好,但是当删除该行时,删除的单元格(使用TableCellEditor呈现)中的内容不会更新.

当删除行时,我尝试在模型中同时调用fireTableRowsDeleted(row,row)和fireTableDataChanged(),但似乎没有通知TableCellEditor.当我选择另一行时,它将起作用,并且再次使用TableCellRenderer呈现了行索引.

关于如何通知TableCellEditor删除的任何建议?

>按下删除按钮

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

>再次使用CellRenderer时,行内容已更新.

这是代码:

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不会注意到它必须停止编辑单元格.

一个简单的解决方案是在您的CellEditor中添加另一个ActionListener,并在每次单击它时调用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();
    }
  });
}

标签:swing,jtable,abstracttablemodel,tablecelleditor,java
来源: https://codeday.me/bug/20191101/1986598.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有