2011-11-25 94 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