简体   繁体   English

从jtable中删除AbstractAction

[英]Remove AbstractAction from jtable

Ok. 好。 I have a large project where a particular jtable is created at startup and never gets rebuilt. 我有一个大型项目,在启动时会创建一个特定的jtable,并且永远不会对其进行重建。 The table model is refreshed and the table redrawn based on various user actions. 将根据各种用户操作刷新表模型并重绘表。

I've added a custom TableCellListener class to react to cell changes along with an AbstractAction. 我添加了一个自定义TableCellListener类,以对单元格更改以及AbstractAction做出反应。 Here is the code that gets executed the first time the table is populated with data. 这是第一次在表中填充数据时执行的代码。 (Without the 'firstLoad' check, multiple actions were getting attached every time the table was redrawn). (没有“ firstLoad”检查,每次重绘表时都会附加多个操作)。

if(firstLoad) {
    AbstractAction action = new AbstractAction()
    {
        public void actionPerformed(ActionEvent e)
        {
            TableCellListener tcl = (TableCellListener)e.getSource();


                    sayIt("Row:" + tcl.getRow()+" Column:" + tcl.getColumn()+
                        " Old:" + tcl.getOldValue()+" New:" + tcl.getNewValue());

        }
    };

    firstLoad = false;
    TableCellListener tcl = new TableCellListener(table2, action);
}

TableCellListener is a custom listener posted here by Rob Camick and the 'sayIt' bit is my own debuging code. TableCellListener是Rob Camick在此处发布的自定义侦听器,“ sayIt”位是我自己的调试代码。

This all works great but I would like to remove the listener completely each time the table is rebuilt and add it in again because it is 'remembering' the value from the last selected cell, which is now not valid because the table data is new. 这一切都很好,但是我想在每次重建表时完全删除侦听器,然后再次添加它,因为它正在“记住”上次选择的单元格中的值,由于表数据是新的,因此现在无效。

I'm fairly sure a 'removePropertyChangeListener()' type call would do it but it expects the listener as an argument and I'm not sure how to find it. 我相当确定'removePropertyChangeListener()'类型的调用可以做到,但它希望将侦听器作为参数,而且我不确定如何找到它。

because it is 'remembering' the value from the last selected cell, which is now not valid because the table data is new. 因为它正在“记住”上次选择的单元格中的值,由于表数据是新数据,因此该值现在无效。

It should save the current value when you start editing and generate the event when you stop editing. 开始编辑时应保存当前值,停止编辑时应生成事件。 When you change the TableModel you should not be editing any cell. 更改TableModel时,不应编辑任何单元格。 Therefore, when you generate the next event that implies you selected and started editing on a different cell in which case you should have the current value for the new model. 因此,当您生成表示您选择并开始在其他单元格上进行编辑的下一个事件时,在这种情况下,您应该具有新模型的当前值。 It works fine for me: 这对我来说可以:

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.io.*;
import java.net.*;
import javax.swing.*;
import javax.swing.table.*;

public class TableCellListenerTest2
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }

    public static void createAndShowGUI()
    {
        final JTable table = new JTable( TableCellListenerTest2.createModel());
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        JScrollPane scrollPane = new JScrollPane(table);

        Action action = new AbstractAction()
        {
            public void actionPerformed(ActionEvent e)
            {
                TableCellListener tcl = (TableCellListener)e.getSource();
                System.out.println( tcl.getOldValue() + " : " + tcl.getNewValue() );
            }
        };

        TableCellListener tcl = new TableCellListener(table, action);

        JButton button = new JButton("Reset Model");
        button.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                table.setModel( TableCellListenerTest2.createModel() );
            }
        });

        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("Table Cell Listener");
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( scrollPane );
        frame.add(button, BorderLayout.SOUTH);
        frame.setSize(400, 160);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
    }

    public static TableModel createModel()
    {
        Random random = new Random();

        DefaultTableModel model = new DefaultTableModel(10, 2);

        for (int i = 0; i < model.getRowCount(); i++)
            model.setValueAt("" + random.nextInt(100), i, 0);

        return model;
    }
}

Post your SSCCE if you need more help. 如果需要更多帮助,请发布SSCCE。

为什么不简单地使TableCellListener,tcl,一个类字段,如果重建模型则将其删除,然后重新构建侦听器并重新添加它。

Just remember the TableCellListener instance in an instance variable: 只要记住实例变量中的TableCellListener实例即可:

// side effect: the tcl is added as PropertyChangeListener to the table 
// (bad design, IMHO)
this.tcl = new TableCellListener(table2, action);

// when the table data changes: 
if (this.tcl != null) {
    table2.removePropertyChangeListener(this.tcl);
}
this.tcl = new TableCellListener(table2, action);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM