Default dockable shortcut

Hi Beni,

I successfully “externalize” a dockable from the frame using ctrl+E but I wasn’t able to reconnect the detached dockable to the frame by using ctrl+N

Could you please help?


    public ShortcutExample() {
        final CControl control = new CControl();
        CContentArea contentArea = control.getContentArea();
        CGrid grid = new CGrid(control);
        control.setTheme(ThemeMap.KEY_ECLIPSE_THEME);
        
//        control.getController().getProperties().set( CControl.KEY_GOTO_EXTERNALIZED, KeyStroke.getKeyStroke( KeyEvent.VK_E, InputEvent.ALT_MASK ) );

        DefaultSingleCDockable southDockable = new DefaultSingleCDockable("south_dockable", "South", new JPanel());
        grid.add(0, 50, 50, 15, southDockable);
        southDockable.setMinimizable(true);
        southDockable.setMaximizable(true);
        southDockable.setExternalizable(true);
        contentArea.deploy(grid);

        CStack screensStack = new CStack("Top");
        screensStack.setHideIfEmpty(false);
        control.addStation(screensStack, true);
        DefaultSingleCDockable northDockable = new DefaultSingleCDockable("north_dockable", "North", new JPanel());
        northDockable.setMinimizable(true);
        northDockable.setMaximizable(true);
        northDockable.setExternalizable(true);
        control.addDockable(northDockable);
        screensStack.getStation().add(northDockable.intern(), 0);

        grid.add(40, 11, 48, 40, screensStack);
        contentArea.deploy(grid);

        JFrame frame = new JFrame();
        frame.setResizable(true);
        frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        frame.setSize(800, 800);
        frame.add(contentArea);
        control.setRootWindow(new DirectWindowProvider(frame));
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        new ShortcutExample();
    }


    class CStack extends AbstractDockableCStation<CStackDockStation> implements CNormalModeArea, SingleCDockable {
        private boolean hideIfEmpty;


        public CStack(String id) {
            CStackDockStation delegate = new CStackDockStation(this);
            CLocation stationLocation = new CLocation() {

                @Override
                public CLocation getParent() {
                    return null;
                }

                @Override
                public String findRoot() {
                    return getUniqueId();
                }

                @Override
                public DockableProperty findProperty(DockableProperty successor) {
                    return successor;
                }

                @Override
                public ExtendedMode findMode() {
                    return ExtendedMode.NORMALIZED;
                }

                @Override
                public CLocation aside() {
                    return this;
                }
            };
            init(delegate, id, stationLocation, delegate);
        }


        public void setHideIfEmpty(boolean hideIfEmpty) {
            this.hideIfEmpty = hideIfEmpty;
        }

        @Override
        public CStationPerspective createPerspective() {
            throw new IllegalStateException("not implemented");
        }

        @Override
        public boolean isNormalModeChild(Dockable dockable) {
            return isChild(dockable);
        }

        @Override
        public DockableProperty getLocation(Dockable child) {
            return DockUtilities.getPropertyChain(getStation(), child);
        }

        @Override
        public void setLocation(Dockable dockable, DockableProperty location, AffectedSet set) {
            set.add(dockable);
            if (isChild(dockable)) {
                getStation().move(dockable, location);
            } else {
                if (!getStation().drop(dockable, location)) {
                    getStation().drop(dockable);
                }
            }
        }

        @Override
        public void addModeAreaListener(ModeAreaListener listener) {
        }

        @Override
        public Path getTypeId() {
            return null;
        }

        @Override
        public boolean autoDefaultArea() {
            return true;
        }

        @Override
        public boolean isChild(Dockable dockable) {
            return dockable.getDockParent() == getStation();
        }

        @Override
        public void removeModeAreaListener(ModeAreaListener listener) {
        }

        @Override
        public void setController(DockController controller) {
        }

        @Override
        public void setMode(LocationMode mode) {
        }

        @Override
        public CLocation getCLocation(Dockable dockable) {
            DockableProperty property = DockUtilities.getPropertyChain(getStation(), dockable);
            return getStationLocation().expandProperty(property);
        }

        @Override
        public CLocation getCLocation(Dockable dockable, Location location) {
            DockableProperty property = location.getLocation();
            if (property == null) {
                return getStationLocation();
            }
            return getStationLocation().expandProperty(property);
        }

        @Override
        public boolean respectWorkingAreas() {
            return false;
        }

        @Override
        public boolean isCloseable() {
            return false;
        }

        @Override
        public boolean isExternalizable() {
            return false;
        }

        @Override
        public boolean isMaximizable() {
            return false;
        }

        @Override
        public boolean isMinimizable() {
            return false;
        }

        @Override
        public boolean isStackable() {
            return false;
        }

        @Override
        public boolean isWorkingArea() {
            return false;
        }

        public boolean hideIfEmpty() {
            return hideIfEmpty;
        }

        public DockActionSource[] getSources() {
            return new DockActionSource[] { getClose() };
        }

        @Override
        protected void install(CControlAccess access) {
            access.getLocationManager().getNormalMode().add(this);
        }

        @Override
        protected void uninstall(CControlAccess access) {
            access.getLocationManager().getNormalMode().remove(getUniqueId());
        }
    }

    class CStackDockStation extends StackDockStation implements CommonDockStation<StackDockStation, CStackDockStation>, CommonDockable {

        private CStack delegate;


        public CStackDockStation(CStack stack) {
            this.delegate = stack;
            final Runnable makeVisible = new Runnable() {
                @Override
                public void run() {
                    delegate.setVisible(true);
                }
            };
            DockUtilities.disableCheckLayoutLocked();
            addDockStationListener(new DockStationAdapter() {
                    @Override
                    public void dockableAdded(DockStation station, Dockable dockable) {
                        DockController controller = delegate.getControl().getController();
                        controller.getHierarchyLock().onRelease(makeVisible);
                    }
                });
        }


        @Override
        public CDockable getDockable() {
            return delegate;
        }

        @Override
        public DockActionSource[] getSources() {
            return delegate.getSources();
        }

        @Override
        public CStation<CStackDockStation> getStation() {
            return delegate;
        }

        @Override
        public StackDockStation getDockStation() {
            return this;
        }

        @Override
        public CStackDockStation asDockStation() {
            return this;
        }

        @Override
        public CommonDockable asDockable() {
            return this;
        }

        @Override
        public String getConverterID() {
            return super.getFactoryID();
        }

        @Override
        public String getFactoryID() {
            return CommonDockStationFactory.FACTORY_ID;
        }
    }

}```


Thanks

Your test-dockables need at least one Component that is focusable, e.g. a textfield, a button, etc… If you want you can just add some JPanel and call its “setFocusable” method to make it focusable. The issue is: without any focusable Component, Swing does not send the KeyEvent to the window with the floating Dockable.