package tutorial.core.basics; import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.HashSet; import java.util.Set; import javax.swing.BorderFactory; import javax.swing.Timer; import javax.swing.border.Border; import tutorial.support.ColorDockable; import tutorial.support.JTutorialFrame; import tutorial.support.Tutorial; import bibliothek.gui.DockController; import bibliothek.gui.dock.FlapDockStation; import bibliothek.gui.dock.ScreenDockStation; import bibliothek.gui.dock.SplitDockStation; import bibliothek.gui.dock.displayer.DisplayerDockBorder; import bibliothek.gui.dock.station.split.SplitDockGrid; import bibliothek.gui.dock.themes.ThemeManager; import bibliothek.gui.dock.themes.basic.action.buttons.MiniButton; import bibliothek.gui.dock.themes.border.BorderModifier; import bibliothek.gui.dock.util.Priority; import bibliothek.gui.dock.util.UIBridge; import bibliothek.gui.dock.util.UIValue; @Tutorial( id="BorderModifier", title="Border" ) public class BorderModifierExample { /* Clients can install "BorderModifiers" to modify any Border used by the framework. Basically a BorderModifier * gets the original border, and can decide what to do with that border. The border may be replaced, it may * be modified, or it may be just used as it is. */ public static void main( String[] args ) throws IOException{ /* setting up frame and controller as usual */ JTutorialFrame frame = new JTutorialFrame( BorderModifierExample.class ); DockController controller = new DockController(); controller.setRootWindow( frame ); frame.destroyOnClose( controller ); /* We now install our modifier. In this example we create an UIBridge of type "AlteringBridge" to apply the * border to only a subset of components. */ final AlteringBridge bridge = new AlteringBridge(); /* The priority "CLIENT" means that we override any other setting. The "kind" tells us that we will only * receive listeners of type "DisplayerDockBorder". The "BORDER_MODIFIER_TYPE" ensure type safety, and * "bridge" is the object we install. */ controller.getThemeManager().publish( Priority.CLIENT, DisplayerDockBorder.KIND, ThemeManager.BORDER_MODIFIER_TYPE, bridge ); /* We may also set a modifier directly using a key. The modifier is then applied to all places which use the key. */ controller.getThemeManager().setBorderModifier( MiniButton.BORDER_KEY_MOUSE_OVER, new BorderModifier(){ public Border modify( Border border ){ return BorderFactory.createEtchedBorder( new Color( 150, 255, 150 ), new Color( 0, 150, 0 ) ); } }); /* As this application runs together with other applications, we have to make sure it * is cleaned up if closed. */ frame.runOnClose( new Runnable(){ public void run(){ bridge.destroy(); } }); /* And now we set up different DockStations and Dockables */ SplitDockStation splitDockStation = new SplitDockStation(); controller.add( splitDockStation ); frame.add( splitDockStation ); SplitDockGrid grid = new SplitDockGrid(); grid.addDockable( 0, 0, 100, 20, new ColorDockable( "Red", Color.RED )); grid.addDockable( 0, 20, 30, 50, new ColorDockable( "Blue", Color.BLUE )); grid.addDockable( 0, 70, 30, 30, new ColorDockable( "Yellow", Color.YELLOW )); grid.addDockable( 30, 20, 80, 80, new ColorDockable( "White", Color.WHITE )); grid.addDockable( 30, 20, 80, 80, new ColorDockable( "Black", Color.BLACK )); splitDockStation.dropTree( grid.toTree() ); FlapDockStation flapDockStation = new FlapDockStation(); controller.add( flapDockStation ); flapDockStation.add( new ColorDockable( "Green", Color.GREEN )); frame.add( flapDockStation.getComponent(), BorderLayout.NORTH ); ScreenDockStation screenDockStation = new ScreenDockStation( controller.getRootWindowProvider() ); controller.add( screenDockStation ); /* Now we make all frames and windows visible. */ frame.setVisible( true ); screenDockStation.setShowing( true ); } /* This "UIBridge" is responsible for installing our BorderModifier. In this example * we create a Timer and alter the BorderModifier each second. This means that the * application blinks in various colors. It also shows that a client can alter the * modifier at any time and the framework will react immediately. */ private static class AlteringBridge implements UIBridge<BorderModifier, UIValue<BorderModifier>>, ActionListener{ /* our first modifier creates a red border */ private BorderModifier redModifier = new BorderModifier(){ public Border modify( Border border ){ return BorderFactory.createEtchedBorder( new Color( 255, 150, 150 ), new Color( 150, 0, 0 ) ); } }; /* our second modifier creates a blue border */ private BorderModifier blueModifier = new BorderModifier(){ public Border modify( Border border ){ return BorderFactory.createEtchedBorder( new Color( 150, 150, 255 ), new Color( 0, 0, 150 ) ); } }; /* UIValues are listeners, and we use these listeners to inform the framework * about new BorderModifiers to use */ private Set<UIValue<BorderModifier>> listeners = new HashSet<UIValue<BorderModifier>>(); /* The timer triggering a change of the modifier */ private Timer timer; /* Whether to use the red or the blue borders */ private boolean state = true; public AlteringBridge(){ timer = new Timer( 1000, this ); timer.start(); } public void destroy(){ timer.stop(); timer.removeActionListener( this ); } public void actionPerformed( ActionEvent e ){ state = !state; /* For changing the modifier we just iterate over all listeners and install * the new modifier with "set". */ for( UIValue<BorderModifier> border : listeners ){ if( state ){ border.set( redModifier ); } else{ border.set( blueModifier ); } } } /* Tells whether we should pay attention to some border. We only pay attention * to those borders which are shown directly on a SplitDockStation. * Note that we can cast uiValue to DisplayerDockBorder because of the restrictions * we applied when "publishing" the bridge on line 50. */ private boolean shouldManage( UIValue<BorderModifier> uiValue ){ DisplayerDockBorder displayer = (DisplayerDockBorder)uiValue; return displayer.getDisplayer().getStation() instanceof SplitDockStation; } public void add( String id, UIValue<BorderModifier> uiValue ){ if( shouldManage( uiValue )){ listeners.add( (DisplayerDockBorder)uiValue ); } } public void remove( String id, UIValue<BorderModifier> uiValue ){ listeners.remove( uiValue ); } /* This method may be called any time for installed listeners. */ public void set( String id, BorderModifier value, UIValue<BorderModifier> uiValue ){ if( shouldManage( uiValue )){ if( state ){ uiValue.set( redModifier ); } else{ uiValue.set( blueModifier ); } } else{ uiValue.set( value ); } } } }