package tutorial.core.guide;
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.gui.DockController;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.layout.DockableProperty;
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.util.DockUtilities;
import bibliothek.util.Path;
@Tutorial( id="Placeholders", title="Persistent Layout: Placeholders" )
public class PlaceholderExample {
/* Placeholders allow the framework to mark the location of a Dockable even if the Dockable is not
* known to a DockController.
*
* This example shows how a primitive mechanism to close and reopen Dockables can be implemented using
* a PlaceholderStrategy and using local layout data (in form of a DockableProperty).
*/
public static void main( String[] args ){
/* Setting up a frame, a station and a controller */
JTutorialFrame frame = new JTutorialFrame( PlaceholderExample.class );
DockController controller = new DockController();
controller.setRootWindow( frame );
frame.destroyOnClose( controller );
SplitDockStation station = new SplitDockStation();
controller.add( station );
frame.add( station );
/* At this point we register our custom PlaceholderStrategy. PlaceholderStrategies should always
* be installed early on, that way no placeholders are lost. */
controller.getProperties().set( PlaceholderStrategy.PLACEHOLDER_STRATEGY, new CustomPlaceholderStrategy() );
/* Creating some custom Dockables and adding them to the tree */
CustomDockable red = new CustomDockable( new Path( "red" ), "Red", Color.RED );
CustomDockable green = new CustomDockable( new Path( "green" ), "Green", Color.GREEN );
CustomDockable blue = new CustomDockable( new Path( "blue" ), "Blue", Color.BLUE );
CustomDockable yellow = new CustomDockable( new Path( "yelow" ), "Yellow", Color.YELLOW );
SplitDockGrid grid = new SplitDockGrid();
grid.addDockable( 0, 0, 1, 1, red );
grid.addDockable( 0, 1, 1, 1, green );
grid.addDockable( 1, 0, 1, 1, blue );
grid.addDockable( 1, 1, 1, 1, yellow );
station.dropTree( grid.toTree() );
/* And here we create a menu containing checkboxes to open and close our custom Dockables */
JMenu menu = new JMenu( "Dockables" );
menu.add( red.createMenuItem() );
menu.add( green.createMenuItem() );
menu.add( blue.createMenuItem() );
menu.add( yellow.createMenuItem() );
JMenuBar bar = new JMenuBar();
bar.add( menu );
frame.setJMenuBar( bar );
frame.setVisible( true );
}
/* This dockable remembers its location if it is closed and can open itself at the former location */
private static class CustomDockable extends ColorDockable{
private Path placeholder;
private DockableProperty location;
private DockStation root;
public CustomDockable( Path placeholder, String title, Color color ){
super( title, color );
this.placeholder = placeholder;
}
public Path getPlaceholder(){
return placeholder;
}
/* creates a checkbox for opening/closing this dockable */
public JMenuItem createMenuItem(){
final JCheckBoxMenuItem item = new JCheckBoxMenuItem( getTitleText(), getTitleIcon() );
item.setSelected( getDockParent() != null );
item.addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent e ){
if( item.isSelected() ){
doShow();
}
else{
doClose();
}
}
});
return item;
}
public void doClose(){
DockStation parent = getDockParent();
if( parent != null ){
/* remember the old location... */
root = DockUtilities.getRoot( this );
location = DockUtilities.getPropertyChain( this );
/* ... then close */
parent.drag( this );
}
}
public void doShow(){
if( getDockParent() == null ){
/* drop this at the former location */
if( !root.drop( this, location ) ){
root.drop( this );
}
location = null;
}
}
}
/* This is our very simple PlaceholderStrategy. It only recognizes our custom Dockable and
* returns its placeholder. */
private static class CustomPlaceholderStrategy implements PlaceholderStrategy{
public void addListener( PlaceholderStrategyListener listener ){
// ignore
}
public Path getPlaceholderFor( Dockable dockable ){
if( dockable instanceof CustomDockable ){
return ((CustomDockable) dockable).getPlaceholder();
}
return null;
}
public void install( DockStation station ){
// ignore
}
public boolean isValidPlaceholder( Path placeholder ){
return true;
}
public void removeListener( PlaceholderStrategyListener listener ){
// ignore
}
public void uninstall( DockStation station ){
// ignore
}
}
}