Check when component is removed from JTable
-
08-03-2021 - |
Question
I have a JTable that holds several JPanels using a custom renderer/editor. The JPanel listens to another object for changes. Now when I remove the rows from the JTable the JPanel still exists in the listener list in the object so the JPanel doesn't get destroyed.
Previously I displayed the JPanel in another JPanel so when the object got removed I could add some code to unregister the listener in its removeNotify() method.
The removeNotify() trick doesn't work when the JPanel is in a JTable because it is constantly removed and re-added to the table's renderer/editor. I tried using addNotify() to add the JPanel as a listener, but somehow it doesn't get removed from the listener list. So how can I do this as clean as possible?
How I add rows to the table:
public void fillTable()
{
DefaultTableModel model = (DefaultTableModel) table.getModel();
model.setRowCount(0);
CustomPanel panel = new CustomPanel(getSomeObject());
model.addRow(new Object[]{panel});
}
How the custom panel registers as a listener:
public class CustomPanel extends JPanel implements CustomObjectListener
{
public CustomPanel(CustomObjet obj)
{
obj.addListener(this);
}
@Override
public void CustomObjectEvent(Event evt)
{
handle event;
}
}
How the event is thrown:
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);
}
}
}
Solution 2
I fixed it by creating a new TableModel and overriding the setRowCount() method.
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);
}
}
OTHER TIPS
I have a JTable that holds several JPanels using a custom renderer/editor.
The DefaultCellEditor
has a stopCellEditing()
method you should be able to add your code to.
Or maybe you can add a PropertyChangeListener to the table:
public void propertyChange(PropertyChangeEvent e)
{
// A cell has started/stopped editing
if ("tableCellEditor".equals(e.getPropertyName()))
{
if (table.isEditing())
processEditingStarted();
else
processEditingStopped();
}
}