From: Frederick W. <fre...@us...> - 2012-02-05 10:26:18
|
rails/ui/swing/ORWindow.java | 126 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) New commits: commit 9b2b2d123eee75c646a4e0159f8420b672865504 Author: Frederick Weld <fre...@gm...> Date: Sun Feb 5 11:16:10 2012 +0100 Added support for docking externalized panels to each other Solution consists of adding a SplitDockStation in between and fine tuning the default dockable options (maximize button). Based on http://forum.byte-welt.de/showthread.php?t=3097&page=2 diff --git a/rails/ui/swing/ORWindow.java b/rails/ui/swing/ORWindow.java index 5f75ad9..b35bc3e 100644 --- a/rails/ui/swing/ORWindow.java +++ b/rails/ui/swing/ORWindow.java @@ -12,13 +12,28 @@ import java.util.Locale; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; import org.apache.log4j.Logger; +import bibliothek.gui.DockController; +import bibliothek.gui.Dockable; +import bibliothek.gui.DockStation; +import bibliothek.gui.dock.ScreenDockStation; +import bibliothek.gui.dock.SplitDockStation; import bibliothek.gui.dock.common.CControl; import bibliothek.gui.dock.common.CGrid; +import bibliothek.gui.dock.common.CStation; import bibliothek.gui.dock.common.DefaultSingleCDockable; +import bibliothek.gui.dock.common.action.predefined.CBlank; +import bibliothek.gui.dock.common.event.CDockableStateListener; +import bibliothek.gui.dock.common.intern.CDockable; +import bibliothek.gui.dock.common.intern.DefaultCDockable; +import bibliothek.gui.dock.common.intern.ui.CSingleParentRemover; +import bibliothek.gui.dock.common.mode.ExtendedMode; import bibliothek.gui.dock.common.theme.ThemeMap; +import bibliothek.gui.dock.event.DockStationAdapter; +import bibliothek.gui.dock.station.LayoutLocked; import rails.common.GuiDef; import rails.common.LocalText; @@ -92,7 +107,11 @@ public class ORWindow extends JFrame implements ActionPerformer { orWindowControl.setTheme( ThemeMap.KEY_SMOOTH_THEME ); add( orWindowControl.getContentArea() ); CGrid orWindowLayout = new CGrid( orWindowControl ); - + + //ensure that externalized dockables get a split station as parent + //necessary, otherwise externalized dockables cannot be docked together + alwaysAddStationsToExternalizedDockables(orWindowControl); + //set docks tooltip language if ("en_us".equalsIgnoreCase(Config.get("locale"))) { //hard setting to default in case of US as this is DockingFrames default language @@ -350,6 +369,111 @@ public class ORWindow extends JFrame implements ActionPerformer { orWindowControl.load(getLayoutName()); } catch (Exception e) {} //skip if layout not found } + + //ensure that all dockables that are externalized according to layout + //information don't have the deault maximize button (as it won't work + //for the adjusted externalization setup) + for (int i = 0 ; i < orWindowControl.getCDockableCount() ; i++ ) { + CDockable d = orWindowControl.getCDockable(i); + if (d instanceof DefaultCDockable) { + DefaultCDockable dd = (DefaultCDockable)d; + if (ExtendedMode.EXTERNALIZED.equals(d.getExtendedMode())) { + dd.putAction( CDockable.ACTION_KEY_MAXIMIZE, CBlank.BLANK ); + } + } + } + } + + /** + * The behavior of the specified CControl is altered by the following: + * If a dockable is detached / externalized, it would normally put directly + * under the ScreenDockStation - thus inhibiting any docking to/from this + * dockable. This is changed such that a split station (that would allow for + * that) is put in between the ScreenDockStation and the Dockable. + */ + private void alwaysAddStationsToExternalizedDockables(CControl cc) { + + // access the DockStation which shows our detached (externalized) items + CStation<?> screen = (CStation<?>) + cc.getStation( CControl.EXTERNALIZED_STATION_ID ); + + // remove the standard maximize action when externalizing + // and adds it back when unexternalizing + // (as maximize won't work for the adjusted externalization setup) + cc.addStateListener( new CDockableStateListener() { + public void visibilityChanged( CDockable cd ){ + // ignore + } + + public void extendedModeChanged( CDockable cd, ExtendedMode mode ){ + if( cd instanceof DefaultCDockable ) { + DefaultCDockable dockable = (DefaultCDockable) cd; + if( mode.equals( ExtendedMode.EXTERNALIZED ) ) { + dockable.putAction( CDockable.ACTION_KEY_MAXIMIZE, CBlank.BLANK ); + } + else { + dockable.putAction( CDockable.ACTION_KEY_MAXIMIZE, null ); + } + } + } + }); + + // if a Dockable is added to that station... + screen.getStation().addDockStationListener( new ScreenDockStationListener()); + + // make sure a SplitDockStation with one child and a parent + // that is a ScreenDockStation does not get removed + cc.intern().getController().setSingleParentRemover( + new CSingleParentRemover( cc ){ + @Override + protected boolean shouldTest( DockStation station ){ + if( station instanceof SplitDockStation ) { + SplitDockStation split = (SplitDockStation) station; + if( split.getDockParent() instanceof ScreenDockStation ) { + // but we want to remove the station if it does + // not have any children at all + return split.getDockableCount() == 0; + } + } + return super.shouldTest( station ); + } + } ); } + @LayoutLocked(locked = false) + private class ScreenDockStationListener extends DockStationAdapter { + public void dockableAdded( DockStation station, final Dockable dockable ){ + // ... and the new child is not a SplitDockStation ... + if( !(dockable instanceof SplitDockStation) ) { + SwingUtilities.invokeLater( new Runnable(){ + public void run(){ + checkAndReplace( dockable ); + } + } ); + } + } + private void checkAndReplace( Dockable dockable ){ + DockStation station = dockable.getDockParent(); + if( !(station instanceof ScreenDockStation) ) { + // cancel + return; + } + + // .. then we just insert a SplitDockStation + SplitDockStation split = new SplitDockStation(); + DockController controller = station.getController(); + + try { + // disable events while rearranging our layout + controller.freezeLayout(); + + station.replace( dockable, split ); + split.drop( dockable ); + } + finally { + // and enable events after we finished + controller.meltLayout(); + } + } + } } |