Java 检查组件何时从JTable中移除

Java 检查组件何时从JTable中移除,java,swing,jtable,tablecellrenderer,Java,Swing,Jtable,Tablecellrenderer,我有一个JTable,它使用一个定制的渲染器/编辑器保存几个jpanel。JPanel侦听另一个对象以获取更改。现在,当我从JTable中删除行时,JPanel仍然存在于对象的侦听器列表中,这样JPanel就不会被破坏 之前,我在另一个JPanel中显示了JPanel,因此当对象被删除时,我可以添加一些代码以在其removeNotify()方法中注销侦听器 当JPanel位于JTable中时,removeNotify()技巧不起作用,因为它会不断被删除并重新添加到表的呈现器/编辑器中。我尝试使用

我有一个JTable,它使用一个定制的渲染器/编辑器保存几个jpanel。JPanel侦听另一个对象以获取更改。现在,当我从JTable中删除行时,JPanel仍然存在于对象的侦听器列表中,这样JPanel就不会被破坏

之前,我在另一个JPanel中显示了JPanel,因此当对象被删除时,我可以添加一些代码以在其removeNotify()方法中注销侦听器

当JPanel位于JTable中时,removeNotify()技巧不起作用,因为它会不断被删除并重新添加到表的呈现器/编辑器中。我尝试使用addNotify()将JPanel添加为侦听器,但不知何故它没有从侦听器列表中删除。 那么我怎样才能做到尽可能干净呢

如何向表中添加行:

public void fillTable()
{
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.setRowCount(0);
    CustomPanel panel = new CustomPanel(getSomeObject());
    model.addRow(new Object[]{panel});
}
public void propertyChange(PropertyChangeEvent e)
{
    //  A cell has started/stopped editing

    if ("tableCellEditor".equals(e.getPropertyName()))
    {
        if (table.isEditing())
            processEditingStarted();
        else
            processEditingStopped();
    }
}
自定义面板如何注册为侦听器:

public class CustomPanel extends JPanel implements CustomObjectListener
{
    public CustomPanel(CustomObjet obj)
    {
        obj.addListener(this);
    }

    @Override
    public void CustomObjectEvent(Event evt)
    {
        handle event;
    }
}
事件的抛出方式:

public class CustomObject
{
    ArrayList<CustomObjectListener> listeners = new ArrayList<CustomObjectListener>();

    public CustomObject()
    {
    }

    public void addListener(CustomObjectListener listener)
    {
        listeners.add(listener);
    }

    public void removeListener(CustomObjectListener listener)
    {
        listeners.remove(listener);
    }

    public void fireEvent(Event evt)
    {
        for (CustomObjectListener listener : listeners)
        {
            listener.CustomObjectEvent(evt);
        }
    }
}
公共类CustomObject
{
ArrayList侦听器=新的ArrayList();
公共自定义对象()
{
}
public void addListener(CustomObjectListener侦听器)
{
添加(侦听器);
}
公共void RemovelListener(CustomObjectListener侦听器)
{
删除(侦听器);
}
公共火灾事件(事件evt)
{
for(CustomObjectListener:侦听器)
{
CustomObjectEvent(evt);
}
}
}
我有一个JTable,它使用一个定制的渲染器/编辑器保存几个jpanel

DefaultCellEditor
有一个
stopCellEditing()
方法,您应该能够将代码添加到其中

或者,您可以将PropertyChangeListener添加到表中:

public void fillTable()
{
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.setRowCount(0);
    CustomPanel panel = new CustomPanel(getSomeObject());
    model.addRow(new Object[]{panel});
}
public void propertyChange(PropertyChangeEvent e)
{
    //  A cell has started/stopped editing

    if ("tableCellEditor".equals(e.getPropertyName()))
    {
        if (table.isEditing())
            processEditingStarted();
        else
            processEditingStopped();
    }
}
我有一个JTable,它使用一个定制的渲染器/编辑器保存几个jpanel

DefaultCellEditor
有一个
stopCellEditing()
方法,您应该能够将代码添加到其中

或者,您可以将PropertyChangeListener添加到表中:

public void fillTable()
{
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.setRowCount(0);
    CustomPanel panel = new CustomPanel(getSomeObject());
    model.addRow(new Object[]{panel});
}
public void propertyChange(PropertyChangeEvent e)
{
    //  A cell has started/stopped editing

    if ("tableCellEditor".equals(e.getPropertyName()))
    {
        if (table.isEditing())
            processEditingStarted();
        else
            processEditingStopped();
    }
}

我通过创建一个新的TableModel并重写setRowCount()方法修复了它

公共类CustomTableModel扩展了DefaultTableModel
{
@凌驾
公共void setRowCount(int rowCount)
{
if(rowCount=rowCount;i--)
{
((CustomPanel)getValueAt(i,0)).RemovelListeners();
}
}
super.setRowCount(rowCount);
}
}

我通过创建一个新的TableModel并重写setRowCount()方法修复了它

公共类CustomTableModel扩展了DefaultTableModel
{
@凌驾
公共void setRowCount(int rowCount)
{
if(rowCount=rowCount;i--)
{
((CustomPanel)getValueAt(i,0)).RemovelListeners();
}
}
super.setRowCount(rowCount);
}
}

No,当从JTable中删除JPanel时,JPanel需要从对象的侦听器列表中删除自己。这样就没有对JPanel的引用,GC可以收集JPanel。然后,作为编辑器使用的CustomPanel需要保留对CustomObject的引用。调用stopCellEditing()时,您可以删除侦听器。否,从JTable中删除JPanel时,JPanel需要从对象的侦听器列表中删除自身。这样就没有对JPanel的引用,GC可以收集JPanel。然后,作为编辑器使用的CustomPanel需要保留对CustomObject的引用。调用stopCellEditing()时,可以删除侦听器。不要向模型中添加组件。相反,添加由自定义CellRenders/-Editors渲染/编辑的数据不向模型添加组件。相反,添加由自定义CellRenders/-Editors呈现/编辑的数据。请再次说明:不要将数据和视图域混合使用!不要在模型中存储CustomPanel。取而代之的是存储CustomObject,让模型监听对象的更改(属性或自定义,无所谓),并根据需要触发tableModelEvents。在阅读此评论时,它给了我某种唤醒。我会做出相应的调整,但不会发布,因为这与所问的问题并不相关。对于记录和可能查看此帖子的其他人:我已经制作了一个自定义TableCellRenderer/编辑器,它从CustomPanel扩展而来。它从表模型中获取一个CustomObject并显示它。这大大提高了性能!现在加载速度非常快,我可以向大家推荐。谢谢克利奥帕特拉;-)再次强调:不要混合使用数据和视图领域!不要在模型中存储CustomPanel。取而代之的是存储CustomObject,让模型监听对象的更改(属性或自定义,无所谓),并根据需要触发tableModelEvents。在阅读此评论时,它给了我某种唤醒。我会做出相应的调整,但不会发布,因为这与所问的问题并不相关。对于记录和可能查看此帖子的其他人:我已经制作了一个自定义TableCellRenderer/编辑器,它从CustomPanel扩展而来。它从表模型中获取一个CustomObject并显示它。这大大提高了性能!现在加载速度非常快,我可以向大家推荐。谢谢克利奥帕特拉;-)