Ok, this is a different approach. Instead of creating a SplitDockStation when combining items, we create the station in any case as soon as a Dockable is dropped on the ScreenDockStation. This needs a bit more setting up, because we have to make sure that the SplitDockStation is not automatically removed.
I think you’ll have to update the framework, the line “… = control.getStation( CControl.EXTERNALIZED_STATION_ID );” will probably not work in an older version.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import bibliothek.gui.DockController;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.ScreenDockStation;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.StackDockStation;
import bibliothek.gui.dock.action.ListeningDockAction;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.CMaximizeBehavior;
import bibliothek.gui.dock.common.CStation;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.action.CPanelPopup;
import bibliothek.gui.dock.common.intern.CDockable;
import bibliothek.gui.dock.common.intern.CommonDockable;
import bibliothek.gui.dock.common.intern.ui.CSingleParentRemover;
import bibliothek.gui.dock.event.DockStationAdapter;
import bibliothek.gui.dock.station.split.SplitDockStationFactory;
import bibliothek.gui.dock.util.DockUtilities;
public class Dock34 {
@SuppressWarnings("unchecked")
public static void main( String[] args ){
// setting up frame and controller
JFrame frame = new JFrame();
CControl control = new CControl( frame );
control.setMaximizeBehavior( new CustomCMaximizeBehavior() );
// if we ever want to work with layouts, we have install a factory for our specialized SplitDockStation
control.intern().registerFactory( new CustomSplitDockStationFactory() );
// now access the DockStation which shows our detached (externalized) items
CStation<ScreenDockStation> screen = (CStation<ScreenDockStation>) control.getStation( CControl.EXTERNALIZED_STATION_ID );
// if a Dockable is added to that station...
screen.getStation().addDockStationListener( new DockStationAdapter(){
@Override
public void dockableAdded( DockStation station, Dockable dockable ){
// ... and the new child is not a SplitDockStation ...
if( !(dockable instanceof SplitDockStation )){
// .. then we just insert a SplitDockStation
SplitDockStation split = new CustomSplitDockStation();
DockController controller = station.getController();
try{
// disable events while rearanging our layout
controller.freezeLayout();
station.replace( dockable, split );
split.drop( dockable );
}
finally{
// and enable events after we finished
controller.meltLayout();
}
}
}
});
// make sure a SplitDockStation with one child and a parent that is a ScreenDockStation does not get removed
control.intern().getController().setSingleParentRemover( new CSingleParentRemover( control ){
@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 );
}
});
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 700, 700 );
DefaultSingleCDockable red = create( control, "Red", Color.RED );
DefaultSingleCDockable green = create( control, "Green", Color.GREEN );
DefaultSingleCDockable blue = create( control, "Blue", Color.BLUE );
CGrid grid = new CGrid( control );
grid.add( 0, 0, 10, 10, red );
grid.add( 10, 0, 5, 5, green );
grid.add( 10, 5, 5, 5, blue );
control.getContentArea().deploy( grid );
frame.getContentPane().add( control.getContentArea(), BorderLayout.CENTER );
frame.setSize( new Dimension( 600, 600 ) );
frame.setVisible( true );
}
public static DefaultSingleCDockable create( CControl control, String title, Color color ){
JPanel panel = new JPanel();
panel.setOpaque( true );
panel.setBackground( color );
final DefaultSingleCDockable singleDockable = new DefaultSingleCDockable( title, title, panel );
CPanelPopup popup = new CPanelPopup();
JButton button = new JButton( "Button" );
button.setPreferredSize( new Dimension( 400, 300 ) );
popup.setContent( button );
singleDockable.addAction( popup );
return singleDockable;
}
// we write a custom factory for our SplitDockStation
private static class CustomSplitDockStationFactory extends SplitDockStationFactory{
public static final String ID = "custom split dock station";
protected SplitDockStation createStation(){
return new CustomSplitDockStation();
}
@Override
public String getID(){
return ID;
}
}
// we use a custom type for the SplitDockStation, in this case the station will not show
// a fullscreen-action
private static class CustomSplitDockStation extends SplitDockStation{
public String getFactoryID(){
return CustomSplitDockStationFactory.ID;
}
protected ListeningDockAction createFullScreenAction(){
return null;
}
}
// maximization of a floating SplitDockStation: this behavior will maximize the station too
private static class CustomCMaximizeBehavior implements CMaximizeBehavior {
public Dockable getMaximizingElement( Dockable dockable ){
DockStation parent = dockable.getDockParent();
if( parent instanceof StackDockStation || (parent instanceof SplitDockStation && parent.asDockable().getDockParent() instanceof ScreenDockStation) ) {
for( int i = 0, n = parent.getDockableCount(); i < n; i++ ) {
Dockable check = parent.getDockable( i );
if( check != dockable ) {
if( check instanceof CommonDockable ) {
CDockable fdock = ((CommonDockable) check).getDockable();
if( !fdock.isMaximizable() )
return dockable;
}
}
}
return parent.asDockable();
}
return dockable;
}
public Dockable getMaximizingElement( Dockable old, Dockable dockable ){
if( old == dockable )
return null;
if( !DockUtilities.isAncestor( old, dockable ) )
return null;
DockStation station = old.asDockStation();
if( station == null )
return old;
if( station.getDockableCount() == 2 ) {
if( station.getDockable( 0 ) == dockable )
return station.getDockable( 1 );
if( station.getDockable( 1 ) == dockable )
return station.getDockable( 0 );
}
return old;
}
};
}```