2011-11-25 41 views
1

我有一个使用自定义渲染器/编辑器来保存多个JPanel的JTable。 JPanel监听另一个对象进行更改。现在,当我从JTable中删除行时,JPanel仍然存在于对象的侦听器列表中,因此JPanel不会被销毁。检查组件是否从JTable中删除

此前我在另一个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 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); 
     } 
    } 
} 
+2

你能展示一些代码吗? – Jonas

+0

不要将_components_添加到模型中。相反,添加由定制cellRenderers呈现/编辑的_data_ /编辑器 – kleopatra

回答

0

我通过创建一个新的TableModel并重写setRowCount()方法固定它。

public class CustomTableModel extends DefaultTableModel 
{ 
    @Override 
    public void setRowCount(int rowCount) 
    { 
     if (rowCount < getRowCount()) 
     { 
      for (int i = getRowCount()-1; i >= rowCount; i--) 
      { 
       ((CustomPanel)getValueAt(i, 0)).removeListeners(); 
      } 
     } 
     super.setRowCount(rowCount); 
    } 
} 
+2

:不要混合数据和查看领域!不要将CustomPanel存储在模型中。取而代之的是存储CustomObject,让模型监听(属性或自定义,无所谓)对象的变化,并根据需要触发tableModelEvents。 – kleopatra

+1

阅读此评论时,它给了我一些唤醒电话。我会相应做出调整,但不会发布它们,因为它与提问无关。 – siebz0r

+1

对于记录和主要是其他人可能会看到这篇文章:我做了一个自定义的TableCellRenderer /编辑器,从CustomPanel扩展。它从表格模型中取出一个CustomObject并显示它。这给了东西一个巨大的性能提升!事情现在加载速度非常快,我可以向大家推荐。谢谢kleopatra ;-) – siebz0r

1

我有一个使用自定义渲染器/编辑器来保存多个JPanel的JTable。

DefaultCellEditorstopCellEditing()方法,你应该能够在你的代码添加到。

或者,也许你可以添加一个PropertyChangeListener表:

public void propertyChange(PropertyChangeEvent e) 
{ 
    // A cell has started/stopped editing 

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

不,当JPanel从JTable中移除时,JPanel需要将其本身从对象的侦听器列表中移除。这样就没有引用留给JPanel,并且GC可以收集JPanel。 – siebz0r

+0

然后,您用作编辑器的CustomPanel需要保留对CustomObject的引用。当调用stopCellEditing()时,您可以删除侦听器。再次: – camickr