You can replace the action that is responsible for minimizing Dockables. This way you can implement any behavior you like. The example below should explain everything.
import java.awt.Color;
import java.awt.Component;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.CLocation;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.action.predefined.CMinimizeAction;
import bibliothek.gui.dock.common.intern.CDockable;
import bibliothek.gui.dock.common.mode.ExtendedMode;
import bibliothek.gui.dock.common.theme.ThemeMap;
public class Dock44 {
public static final boolean MOVE_DOCKABLE_ALONE = false;
public static void main(String[] args) {
//Setting up a test frame
JFrame frame = new JFrame("Demo");
CControl control = new CControl( );
control.setTheme( ThemeMap.KEY_ECLIPSE_THEME );
frame.add(control.getContentArea());
// this is a special action that will replace the normal minimize action
CustomButton button = new CustomButton( control, control.getContentArea().getCenter().getComponent() );
CGrid grid = new CGrid( control );
grid.add(0, 0, 1, 1, createDockable( "Red", Color.RED, button ));
grid.add(0, 1, 1, 1, createDockable( "Blue", Color.BLUE, button ));
grid.add(1, 0, 1, 1, createDockable( "Green", Color.GREEN, button ));
grid.add(1, 1, 1, 1, createDockable( "Yellow", Color.YELLOW, button ));
control.getContentArea().deploy( grid );
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBounds(20, 20, 400, 400);
frame.setVisible(true);
}
public static CDockable createDockable(String title, Color color, CustomButton minimize ) {
JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(color);
DefaultSingleCDockable dockable = new DefaultSingleCDockable( title );
dockable.setTitleText( title );
dockable.add( panel );
dockable.setCloseable( false );
// at this point we tell the dockable to use our customized minimize action
dockable.putAction( CDockable.ACTION_KEY_MINIMIZE, minimize );
return dockable;
}
// our customized minimize action will minimize the dockables in a new way
private static class CustomButton extends CMinimizeAction{
private CControl control;
private Component base;
public CustomButton( CControl control, Component base ){
super( control );
this.control = control;
this.base = base;
}
@Override
public void action( CDockable dockable ){
CLocation location = bestDestination( dockable );
if( location == null ){
super.action( dockable );
}
else if( MOVE_DOCKABLE_ALONE ){
// the easy solution, moves only this dockable
dockable.setLocation( location );
}
else{
// the more advanced solution, if there is a stack of dockables then the entire stack
// of dockables is moved. Here we just change the default position of "dockable".
control.getLocationManager().setLocation( dockable.intern(), ExtendedMode.MINIMIZED, location );
super.action( dockable );
}
}
// find the nearest edge for a given dockable
private CLocation bestDestination( CDockable dockable ){
Component dock = dockable.intern().getComponent();
if( !SwingUtilities.isDescendingFrom( dock, base )){
return null;
}
Point middle = new Point( dock.getWidth()/2, dock.getHeight()/2 );
middle = SwingUtilities.convertPoint( dock, middle, base );
boolean topleft = above( 0, base.getHeight(), base.getWidth(), 0, middle.x, middle.y );
boolean topright = above( 0, 0, base.getWidth(), base.getHeight(), middle.x, middle.y );
if( topleft && topright ){
return CLocation.base().minimalNorth();
}
else if( topleft && !topright ){
return CLocation.base().minimalWest();
}
else if( !topleft && topright ){
return CLocation.base().minimalEast();
}
else{
return CLocation.base().minimalSouth();
}
}
public static boolean above( double x1, double y1, double x2, double y2, double x, double y ){
double a = y1 - y2;
double b = x2 - x1;
if( b == 0 )
return false;
double c = a*x1 + b*y1;
double sy = (c - a*x) / b;
return y < sy;
}
}
}