Skip to content
Snippets Groups Projects
Commit 5ec5380c authored by Matthias Arzt's avatar Matthias Arzt Committed by tpietzsch
Browse files

BdvDefaultCards: fix memory leak

Using KeybordFocusManager.addPropertyChangeListener(...) adds
a permanent listener, that want be garbage collected until it is
removed. The listener in BdvDefaultCards now uses weak references
and removes itself if no longer needed.
parent 7ca29c86
No related branches found
No related tags found
No related merge requests found
...@@ -42,6 +42,7 @@ import java.awt.Insets; ...@@ -42,6 +42,7 @@ import java.awt.Insets;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
...@@ -104,64 +105,98 @@ public class BdvDefaultCards ...@@ -104,64 +105,98 @@ public class BdvDefaultCards
treePanel.setPreferredSize( new Dimension( 300, 225 ) ); treePanel.setPreferredSize( new Dimension( 300, 225 ) );
// -- handle focus -- // -- handle focus --
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener( "focusOwner", new PropertyChangeListener() new FocusListener( tablePanel, table, treePanel, tree );
cards.addCard( DEFAULT_VIEWERMODES_CARD, "Display Modes", new DisplaySettingsPanel( viewer.state() ), true, new Insets( 0, 4, 4, 0 ) );
cards.addCard( DEFAULT_SOURCES_CARD, "Sources", tablePanel, true, new Insets( 0, 4, 0, 0 ) );
cards.addCard( DEFAULT_SOURCEGROUPS_CARD, "Groups", treePanel, true, new Insets( 0, 4, 0, 0 ) );
}
private static class FocusListener implements PropertyChangeListener
{
private final KeyboardFocusManager currentKeyboardFocusManager;
private final WeakReference< JPanel > tablePanel;
private final WeakReference< SourceTable > table;
private final WeakReference< JPanel > treePanel;
private final WeakReference< SourceGroupTree > tree;
static final int MAX_DEPTH = 8;
boolean tableFocused;
boolean treeFocused;
FocusListener( JPanel tablePanel, SourceTable table, JPanel treePanel, SourceGroupTree tree )
{ {
static final int MAX_DEPTH = 8; this.tablePanel = new WeakReference<>( tablePanel );
boolean tableFocused; this.table = new WeakReference<>( table );
boolean treeFocused; this.treePanel = new WeakReference<>( treePanel );
this.tree = new WeakReference<>( tree );
currentKeyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
currentKeyboardFocusManager.addPropertyChangeListener( "focusOwner", this );
}
void focusTable( boolean focus ) void focusTable( final boolean focus )
{
if ( focus != tableFocused )
{ {
if ( focus != tableFocused ) tableFocused = focus;
{ SourceTable table = this.table.get();
tableFocused = focus; if ( table != null )
table.setSelectionBackground( focus ); table.setSelectionBackground( focus );
}
} }
}
void focusTree( boolean focus ) void focusTree( final boolean focus )
{
if ( focus != treeFocused )
{ {
if ( focus != treeFocused ) treeFocused = focus;
{ SourceGroupTree tree = this.tree.get();
treeFocused = focus; if ( tree != null )
tree.setSelectionBackground( focus ); tree.setSelectionBackground( focus );
} }
}
@Override
public void propertyChange( final PropertyChangeEvent evt )
{
if ( tablePanel.get() == null && treePanel.get() == null )
{
currentKeyboardFocusManager.removePropertyChangeListener( "focusOwner", this );
return;
} }
@Override if ( evt.getNewValue() instanceof JComponent )
public void propertyChange( final PropertyChangeEvent evt )
{ {
if ( evt.getNewValue() instanceof JComponent ) JComponent component = ( JComponent ) evt.getNewValue();
for ( int i = 0; i < MAX_DEPTH; ++i )
{ {
JComponent component = ( JComponent ) evt.getNewValue(); Container parent = component.getParent();
for ( int i = 0; i < MAX_DEPTH; ++i ) if ( !( parent instanceof JComponent ) )
break;
if ( component == treePanel.get() )
{
focusTable( false );
focusTree( true );
return;
}
else if ( component == tablePanel.get() )
{ {
Container parent = component.getParent(); focusTable( true );
if ( ! ( parent instanceof JComponent ) ) focusTree( false );
break; return;
component = ( JComponent ) parent;
if ( component == treePanel )
{
focusTable( false );
focusTree( true );
return;
}
else if ( component == tablePanel )
{
focusTable( true );
focusTree( false );
return;
}
} }
focusTable( false );
focusTree( false );
} }
focusTable( false );
focusTree( false );
} }
} ); }
cards.addCard( DEFAULT_VIEWERMODES_CARD, "Display Modes", new DisplaySettingsPanel( viewer.state() ), true, new Insets( 0, 4, 4, 0 ) );
cards.addCard( DEFAULT_SOURCES_CARD, "Sources", tablePanel, true, new Insets( 0, 4, 0, 0 ) );
cards.addCard( DEFAULT_SOURCEGROUPS_CARD, "Groups", treePanel, true, new Insets( 0, 4, 0, 0 ) );
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment