package tutorial.core.guide; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Set; import javax.swing.Icon; import tutorial.support.JTutorialFrame; import tutorial.support.TextDockable; import tutorial.support.Tutorial; import bibliothek.extension.gui.dock.theme.SmoothTheme; import bibliothek.gui.DockController; import bibliothek.gui.Dockable; import bibliothek.gui.dock.SplitDockStation; import bibliothek.gui.dock.action.ActionContentModifier; import bibliothek.gui.dock.action.DefaultDockActionSource; import bibliothek.gui.dock.action.DockAction; import bibliothek.gui.dock.action.LocationHint; import bibliothek.gui.dock.action.SelectableDockAction; import bibliothek.gui.dock.action.actions.SelectableDockActionGroup; import bibliothek.gui.dock.action.actions.SimpleButtonAction; import bibliothek.gui.dock.action.actions.SimpleDropDownAction; import bibliothek.gui.dock.action.actions.SimpleMenuAction; import bibliothek.gui.dock.action.actions.SimpleSelectableAction; import bibliothek.gui.dock.event.SelectableDockActionListener; import bibliothek.gui.dock.themes.NoStackTheme; import bibliothek.util.Colors; @Tutorial(title="Actions", id="Actions") public class ActionsExample { public static void main( String[] args ){ /* You know what a toolbar is: a set of buttons located at the top of your application. In * some applications the contents of the toolbar change depending on what the user * currently does. * * In this framework there is the notion of a DockAction. DockActions are shown on the title * of a Dockable and can be used to fulfill a similar role than buttons in a toolbar. * * There are various implementations of DockActions, this example shows some of them. It * is possible to write custom actions, e.g. to show a JComboBox in the title, but that * will be explained in another example. */ /* Setting up frame, station, controller, ... as usual */ JTutorialFrame frame = new JTutorialFrame( ActionsExample.class ); DockController controller = new DockController(); controller.setRootWindow( frame ); controller.setTheme( new NoStackTheme( new SmoothTheme() )); frame.destroyOnClose( controller ); SplitDockStation station = new SplitDockStation(); controller.add( station ); frame.add( station ); /* We will print some text on this Dockable whenever we press some button. Also * we add different DockActions to this Dockable */ TextDockable dockable = new TextDockable( "Dockable" ); station.drop( dockable ); /* We cannot add actions directly to a Dockable, we add a group of actions. Any change * to that group will immediately be reflected in the user interface. * There are several sources for these group of actions and the framework must * somehow order them. For this the LocationHint is used. In our case we tell the * framework that the groups origin is a Dockable, and that the group should be displayed * on the left (compared to other groups). * The general notion is that actions on the left side are used by only one or few Dockables, * while the actions on the right side are used by many or all Dockables. */ DefaultDockActionSource actions = new DefaultDockActionSource( new LocationHint( LocationHint.DOCKABLE, LocationHint.LEFT )); /* We start by creating a simple button. This action much behaves like a JButton */ actions.add( setupButtonAction( "Top Button", dockable ) ); /* A separator is a line that visually separates some actions from each other. Basically a JSeparator. */ actions.addSeparator(); /* Now we add some radio-actions. These behave like a set of JRadioButtons. */ setupRadioActions( actions, dockable ); actions.addSeparator(); /* A menu behaves like a JButton that opens a JPopupMenu if clicked */ actions.add( setupMenuActions( dockable ) ); /* A drop-down menu shows several other actions. If the user clicks on * one of the actions the menu changes its icon and text and behaves like * that action. */ actions.add( setupDropDownMenu( dockable ) ); actions.addSeparator(); /* Finally we forward the group of actions to our Dockable */ dockable.setActionOffers( actions ); frame.setVisible( true ); } private static DockAction setupButtonAction( String text, TextDockable target ){ return setupButtonAction( text, target, Color.YELLOW ); } private static DockAction setupButtonAction( final String text, final TextDockable target, Color color ){ /* Creating a button: the SimpleButtonAction is used similar to a JButton */ SimpleButtonAction button = new SimpleButtonAction(); button.setText( text ); button.setIcon( new OvalIcon( color ) ); button.setIcon( ActionContentModifier.NONE_HOVER, new OvalIcon( Colors.darker( color, 0.1 ) ) ); button.setIcon( ActionContentModifier.NONE_PRESSED, new OvalIcon( Colors.darker( color, 0.2 ) ) ); button.addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent e ){ target.appendText( "You clicked button '" + text + "'\n" ); } }); return button; } private static void setupRadioActions( DefaultDockActionSource source, TextDockable target ){ /* SimpleSelectableAction.Radio behaves like a JRadioButton. */ SimpleSelectableAction radio1 = new SimpleSelectableAction.Radio(); SimpleSelectableAction radio2 = new SimpleSelectableAction.Radio(); SimpleSelectableAction radio3 = new SimpleSelectableAction.Radio(); /* Several radio actions can be grouped with a SelectableDockActionGroup. * Only one button in a group can be selected */ SelectableDockActionGroup group = new SelectableDockActionGroup(); setupRadioAction( 1, radio1, group, target ); setupRadioAction( 2, radio2, group, target ); setupRadioAction( 3, radio3, group, target ); source.add( radio1, radio2, radio3 ); } private static void setupRadioAction( final int index, final SimpleSelectableAction radio, SelectableDockActionGroup group, final TextDockable target ){ group.addAction( radio ); radio.setText( "Radio " + index ); radio.setTooltip( "This is radio-button Nr. " + index ); radio.setIcon( new OvalIcon( Color.RED )); radio.setIcon( ActionContentModifier.NONE_HOVER, new OvalIcon( new Color( 255, 150, 150 ) ) ); radio.setIcon( ActionContentModifier.NONE_PRESSED, new OvalIcon( new Color( 255, 200, 200 ) ) ); radio.setSelectedIcon( new OvalIcon( Color.GREEN )); radio.setSelectedIcon( ActionContentModifier.NONE_HOVER, new OvalIcon( new Color( 150, 255, 150 ) ) ); radio.setSelectedIcon( ActionContentModifier.NONE_PRESSED, new OvalIcon( new Color( 200, 255, 200 ) ) ); radio.addSelectableListener( new SelectableDockActionListener(){ /* A DockAction may be used by more than one Dockable. Hence this listener * gets a set containing all the Dockables which are affected by the new * selection state of the action. */ public void selectedChanged( SelectableDockAction action, Set<Dockable> dockables ){ target.appendText( "Selected " + index + ": " + radio.isSelected() + "\n" ); } }); } private static DockAction setupMenuActions( TextDockable target ){ /* A menu shows a group of actions, hence we need another * DefaultDockActionSource to collect the actions */ DefaultDockActionSource actions = new DefaultDockActionSource(); /* We just add some simple buttons */ actions.add( setupButtonAction( "Menu Button 1", target ) ); actions.add( setupButtonAction( "Menu Button 2", target ) ); actions.add( setupButtonAction( "Menu Button 3", target ) ); SimpleMenuAction menu = new SimpleMenuAction( actions ); menu.setIcon( new OvalIcon( Color.WHITE )); menu.setText( "Menu" ); return menu; } private static DockAction setupDropDownMenu( TextDockable target ){ SimpleDropDownAction menu = new SimpleDropDownAction(); /* A drop-down menu offers methods to add actions directly. */ menu.add( setupButtonAction( "Drop Down Button 1", target, Color.RED ) ); menu.add( setupButtonAction( "Drop Down Button 2", target, Color.GREEN ) ); menu.add( setupButtonAction( "Drop Down Button 3", target, new Color( 100, 100, 255 ) ) ); /* The default behavior of SimpleDropDownAction is to replace * icon and text if one of its actions is called. * If you do not like the behavior: * - Call "menu.setFilter" to set a filter that tells the action what to show * - Check the methods offered by "SimpleDropDownItemAction", most of the * actions shown in this example extend that class. */ menu.setIcon( new OvalIcon( Color.WHITE )); menu.setText( "Dropdown" ); return menu; } /* An icon to ensure that our actions are visible */ private static class OvalIcon implements Icon{ private Color color; public OvalIcon( Color color ){ this.color = color; } public int getIconHeight(){ return 16; } public int getIconWidth(){ return 16; } public void paintIcon( Component c, Graphics g, int x, int y ){ int w = getIconWidth(); int h = getIconHeight(); g.setColor( color ); g.fillOval( x, y, w, h ); g.setColor( Color.BLACK ); g.drawOval( x, y, w, h ); g.fillRect( x + w/4, y+h/4, w/6, h/4 ); g.fillRect( x + w - w/4 - w/6, y+h/4, w/6, h/4 ); g.drawLine( x+w/4, y+h/2+h/6, x+w/4+w/6, y+h/2+h/3 ); g.drawLine( x+w/4+w/6, y+h/2+h/3, x+w-w/4-w/6, y+h/2+h/3 ); g.drawLine( x+w-w/4, y+h/2+h/6, x+w-w/4-w/6, y+h/2+h/3 ); } } }