Drag window to externalize?

I’m using the CControl. Is it possible to drag a window outside of it and trigger the externalize? Or perhaps with the combination of a hot key?

I tried with shift, as I saw that mentioned before http://forum.byte-welt.de/showpost.php?p=5473&postcount=8.

Also, I use 2 monitors. When moving the externalized window to screen #2 and maximizing, the window always moves back to original screen. Is this customizable?

thanks

You can drag a Dockable such that it externalizes, but the mouse has to be far away from any other DockStation (or your main-frame) to trigger that behavior (because the ScreenDockStation - which handles externalized items - has a very low priority).
[Edit: or use ctrl+e on a selected CDockable (this key combination only works in Common)]

How are your screens organised and what OS do you use? In theory (and in some configurations) the mechanism works correct, in some others not, it is a bit disheartening… (and taskbars are not handled correct either). But I promise to start the next attempt to get this working properly next week (vacations :slight_smile: ).

In any case, using the key „ScreenDockStation.FULL_SCREEN_STRATEGY“ you can set your own factory for a „ScreenDockFullscreenStrategy“. Currently there are no choices for the strategy other than a Default-strategy, but if you have a very good idea and are eager to test it, please do.

ctrl+e - works great. I’m also overriding the normalize action to be ctrl+e so that a user can toggle between the two with the same key.
control.putProperty( CControl.KEY_GOTO_NORMALIZED, KeyStroke.getKeyStroke( KeyEvent.VK_E, InputEvent.CTRL_MASK ) );

Is there a way to raise the priority for dragging to externalize? Where is the code that handles that? I’m using 2 monitors on Windows XP, but some users have 3 or 4 monitors.

Here is support for maximizing on other monitors.

import bibliothek.gui.dock.station.screen.DefaultScreenDockFullscreenStrategy;
import bibliothek.gui.dock.station.screen.ScreenDockWindow;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;

public class MultiScreenDockFullscreenStrategy extends DefaultScreenDockFullscreenStrategy {

    @Override
    public boolean isFullscreen( ScreenDockWindow wrapper, Window window ){
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

        if( ge == null ){
            return false;
        }

        GraphicsDevice[] gs = ge.getScreenDevices();
        for (GraphicsDevice device : gs) {
            GraphicsConfiguration configuration = device.getDefaultConfiguration();
            Rectangle fullscreen = configuration.getBounds();
            Rectangle current = window.getBounds();
            current = new Rectangle( current.x - 1, current.y - 1, current.width + 2, current.height + 2 );

            if (current.contains( fullscreen ) && wrapper.getNormalBounds() != null){
                return true;
            }

        }

        return false;
    }


    /**
     * Sets the fullscreen mode of <code>window</code>.
     * @param wrapper the wrapper around <code>window</code>
     * @param window the window whose state is to be changed
     * @param fullscreen the new state
     */
    @Override
    public void setFullscreen( ScreenDockWindow wrapper, Window window, boolean fullscreen ){
        if( isFullscreen( wrapper, window ) != fullscreen ){
            if( fullscreen ){
                GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
                if (ge != null){
                    GraphicsDevice[] gs = ge.getScreenDevices();
                    for (GraphicsDevice device : gs) {
                        GraphicsConfiguration configuration = device.getDefaultConfiguration();
                        Rectangle fullscreenBounds = configuration.getBounds();
                        Rectangle windowBounds = window.getBounds();
                        if (fullscreenBounds.contains(windowBounds)){
                            Rectangle bounds = configuration.getBounds();
                            wrapper.setNormalBounds( wrapper.getWindowBounds() );
                            window.setBounds( bounds.x-1, bounds.y-1, bounds.width+2, bounds.height+2 );
                            return;
                        }

                        // if the window is not fully contained in one screen, 
                        // use mouse location to determine which device to maximize on
                        Point mouseLocation = MouseInfo.getPointerInfo().getLocation();
                        if (fullscreenBounds.contains(mouseLocation)){
                            Rectangle bounds = configuration.getBounds();
                            wrapper.setNormalBounds( wrapper.getWindowBounds() );
                            window.setBounds( bounds.x-1, bounds.y-1, bounds.width+2, bounds.height+2 );
                            return;
                        }
                    }
                }
            }
            else{
                Rectangle bounds = wrapper.getNormalBounds();
                if( bounds != null ){
                    window.setBounds( bounds );
                    wrapper.setNormalBounds( null );
                }
            }
        }
    }
}

Thanks for the strategy, looks very good. I think I just copy most of the code :wink:

As for ctrl+e: What if the Dockable is minimized? Then ctrl+e means „normalize“ and „externalize“ at the same time… the winner will be random (actually the winner is the one action which added its key-listener first, which is quite random).

As for the priority. The main issue is, that as soon as the ScreenDockStation has a higher priority than another station, the ScreenDockStation always wins and the other stations becomes utterly useless as the user has now way to access it.
If you really want to experiment: override the methods „canCompare“ and „compare“ of ScreenDockStation and returns something else than always -1 OR subclass DefaultDockRelocator and override methods like „listStationsOrdered“. In the later case you’ll need to extend „DefaultDockControllerFactory“ to introduce your new relocator, the factory has to be given to the constructor of your DockController (in Common you also need to extend „EfficientControlFactory“ to get access to the constructor).

Found my mistake when trying to drag to externalize. I thought it might have something to do with the multi monitor issue, but I was using the CWorkingArea instead of CContentArea/CCGridArea!

Between CContentArea and CGridArea, is one preferred over the other? For my use functionality wise they are interchangeable.
Primary concern is performance - I read in the docs that CCGridArea is a lightweight version of CContentArea, and I can see that CContentArea contains a number more dock stations. Anything else to look out for?

re: ctrl+e - valid concern. but I’d say 95% of the time users will stack tabs over minimizing windows, and I’d like to have a hotkey combo they’ll remember.

Basically CContentArea = CGridArea + 4 * CMinimizeArea. So if you only use a CGridArea you can’t minimize Dockables (unless you start to create CMinimizeAreas too). Personally I would use the CContentArea, it is just more convenient.