package tutorial.dockFrontend.basics; import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JCheckBoxMenuItem; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import tutorial.support.ColorDockable; import tutorial.support.JTutorialFrame; import tutorial.support.Tutorial; import bibliothek.extension.gui.dock.theme.SmoothTheme; import bibliothek.gui.DockFrontend; import bibliothek.gui.DockStation; import bibliothek.gui.Dockable; import bibliothek.gui.dock.SplitDockStation; import bibliothek.gui.dock.event.DockFrontendAdapter; import bibliothek.gui.dock.station.split.SplitDockGrid; import bibliothek.gui.dock.station.support.PlaceholderStrategy; import bibliothek.gui.dock.station.support.PlaceholderStrategyListener; import bibliothek.gui.dock.themes.NoStackTheme; import bibliothek.util.Path; @Tutorial(title="Close-Button", id="DFCloseButton") public class DockFrontendExample { public static void main( String[] args ){ /* You can do a lot of things using the DockController. But some features are really * missing, for example there is no button to just close a Dockable. * * This is where DockFrontend enters the game. DockFrontend is a small wrapper around * DockController, adding some often needed features. * * This examples demonstrates how to setup a DockFrontend and how to use its * close-Dockable feature. */ /* We start by creating a frame to display content */ JTutorialFrame frame = new JTutorialFrame( DockFrontendExample.class ); /* The framework needs to know what parent window to use for its dialogs and windows. * We can set this window directly during construction of DockFrontend */ DockFrontend frontend = new DockFrontend( frame ); frame.destroyOnClose( frontend ); frontend.getController().setTheme( new NoStackTheme( new SmoothTheme() )); /* Let's create a DockStation for our Dockables */ SplitDockStation station = new SplitDockStation(); frame.add( station ); /* We need to register "station" at "frontend". We also need to provide a * unique identifier for "station", this identifier is used for persistently * storing the layout. */ frontend.addRoot( "split", station ); /* Let's create some Dockables */ ColorDockable red = new ColorDockable( "Red", Color.RED ); ColorDockable green = new ColorDockable( "Green", Color.GREEN ); ColorDockable blue = new ColorDockable( "Blue", Color.BLUE ); /* We need to register our Dockables. Each Dockable gets associated with a * unique identifier. */ frontend.addDockable( "red", red ); frontend.addDockable( "green", green ); frontend.addDockable( "blue", blue ); /* We want to use the close-button, so we ensure it is actually enabled */ frontend.setShowHideAction( true ); /* Now we tell the framework that our Dockables can be closed */ frontend.setHideable( red, true ); frontend.setHideable( green, true ); frontend.setHideable( blue, true ); /* This step is optional. By telling the framework to use placeholders * for our Dockables it can better track their location. In Core placeholders * are normally disabled, only Common activates them. * Our custom strategy cannot do much, it will only track ColorDockables. */ frontend.getController().getProperties().set( PlaceholderStrategy.PLACEHOLDER_STRATEGY, new ExamplePlaceholderStrategy() ); /* Now we prepare an initial layout, like we did in all the previous examples. */ SplitDockGrid grid = new SplitDockGrid(); grid.addDockable( 0, 0, 40, 100, red ); grid.addDockable( 40, 0, 60, 50, green ); grid.addDockable( 40, 50, 60, 50, blue ); station.dropTree( grid.toTree() ); /* A menu, with one entry per Dockable, will allow us to reopen closed Dockables */ JMenu menu = new JMenu( "Panels" ); menu.add( createMenuItem( red, frontend )); menu.add( createMenuItem( green, frontend )); menu.add( createMenuItem( blue, frontend )); JMenuBar menuBar = new JMenuBar(); menuBar.add( menu ); frame.setJMenuBar( menuBar ); frame.setVisible( true ); } private static JMenuItem createMenuItem( final ColorDockable observed, final DockFrontend frontend ){ /* Here we create a JCheckBoxMenuItem that is selected only if "observed" is visible. */ final JCheckBoxMenuItem item = new JCheckBoxMenuItem( observed.getTitleText() ); /* We add a DockFrontendListener to "frontend" to be informed whenever a Dockable * is opened or closed (shown and hidden in the terminology of DockFrontend) */ frontend.addFrontendListener( new DockFrontendAdapter(){ @Override public void shown( DockFrontend frontend, Dockable dockable ){ if( dockable == observed ){ item.setSelected( true ); } } @Override public void hidden( DockFrontend fronend, Dockable dockable ){ if( dockable == observed ){ item.setSelected( false ); } } }); /* And an ActionListener added to "item" will tell us when the user clicks * on the menu item. */ item.addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent e ){ if( item.isSelected() ){ frontend.show( observed ); } else{ frontend.hide( observed ); } } }); /* Be sure the initial state of "item" is the correct one */ item.setSelected( frontend.isShown( observed )); return item; } /* This is a PlaceholderStrategy that handles our ColorDockables. It is a * very simple implementation and not intended for real applications. */ private static class ExamplePlaceholderStrategy implements PlaceholderStrategy{ public void addListener( PlaceholderStrategyListener listener ){ // ignore } public Path getPlaceholderFor( Dockable dockable ){ /* The placeholder for a ColorDockable is the unique identifier used * in our DockFrontend */ if( dockable instanceof ColorDockable ){ return new Path( ((ColorDockable)dockable).getTitleText() ); } else{ return null; } } public void install( DockStation station ){ // ignore } public boolean isValidPlaceholder( Path placeholder ){ /* Any placeholder is valid, we do not care about old placeholders that * are no longer used. */ return true; } public void removeListener( PlaceholderStrategyListener listener ){ // ignore } public void uninstall( DockStation station ){ // ignore } } }