It’s quite easy: the framework tracks the Component which has the focus, and searches the Dockable to which the focused Component belongs. If that Dockable is a child of the FlapDockStation (the station showing minimized Dockables), then the window stays open - if not, the window closes.
The issue in your application is, that the CWorkingArea is not actually a child of the FlapDockStation. Just because the Component of the CWorkingArea is put on a JPanel that belongs to a minimized Dockable, does not mean the CWorkingArea is registered as “minimized”. For the framework it looks like the CWorkingArea is “normalized”.
What you can do, is make a connection between CWorkingArea and FlapDockStation. For that you need to get rid of the DefaultSingleCDockable you created - you simply don’t need it. Instead you treat the CWorkingArea like any other SingleCDockable, you can do that because CWorkingArea implements the interface.
You can tell the CWorkingArea to show a title (it is not pretty), and you can tell it to allow minimization. You may wonder why you need to override a method for that… that’s because the framework does not officially support minimized CWorkingAreas. And you will notice some small issues, it really depends on your application whether these issues can be tolerated or not.
In the example below I’ve added some code to show the button outside the CWorkingArea, and to set up some nicer title than the default title. Feel free to delete everything you don’t need…
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import bibliothek.gui.dock.FlapDockStation;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.CLocation;
import bibliothek.gui.dock.common.CWorkingArea;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.intern.EfficientControlFactory;
import bibliothek.gui.dock.common.intern.station.CSplitDockStation;
import bibliothek.gui.dock.common.intern.station.CommonDockStation;
import bibliothek.gui.dock.common.intern.station.CommonStationDelegate;
import bibliothek.gui.dock.common.mode.ExtendedMode;
import bibliothek.gui.dock.station.DockableDisplayer.Location;
import bibliothek.gui.dock.themes.ThemeManager;
import bibliothek.gui.dock.themes.basic.BasicDisplayerFactory;
import bibliothek.gui.dock.themes.basic.BasicDockTitle;
import bibliothek.gui.dock.title.DockTitleFactory;
import bibliothek.gui.dock.title.DockTitleManager;
import bibliothek.gui.dock.title.DockTitleRequest;
public class DockTest {
public static void main( String[] args ){
// Starting up the application in the EDT, preventing any kind of multi-threading issue
SwingUtilities.invokeLater( new Runnable(){
@Override
public void run(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 800, 600 );
CControl control = new CControl( frame, new CustomizedFactory() );
setupTitle( control );
setupDisplayer( control );
frame.getContentPane().add( control.getContentArea() );
MinimizeableWorkingArea area = setUpArea( control );
area.setExtendedMode( ExtendedMode.NORMALIZED );
area.setVisible( true );
frame.setVisible( true );
}
} );
}
private static MinimizeableWorkingArea setUpArea( CControl control ){
// create and register the working-area
MinimizeableWorkingArea workArea = new MinimizeableWorkingArea( control, "internalArea" );
control.addStation( workArea, true );
control.addDockable( workArea );
// add some content to the area
DefaultSingleCDockable itab1 = new DefaultSingleCDockable( "itab1", "itab2" );
itab1.add( new JLabel( "text1" ) );
DefaultSingleCDockable itab2 = new DefaultSingleCDockable( "itab2", "itab2" );
itab2.add( new JLabel( "text2" ) );
CGrid internalGrid = new CGrid( control );
internalGrid.add( 0, 0, 1, 1, itab1 );
internalGrid.add( 0, 1, 1, 1, itab2 );
workArea.deploy( internalGrid );
itab1.setLocation( CLocation.base().minimalWest() );
itab1.setExtendedMode( ExtendedMode.NORMALIZED );
itab1.setDefaultLocation( ExtendedMode.NORMALIZED, itab1.getBaseLocation() );
itab1.setVisible( true );
itab2.setLocation( CLocation.base().minimalWest() );
itab2.setExtendedMode( ExtendedMode.NORMALIZED );
itab2.setDefaultLocation( ExtendedMode.NORMALIZED, itab1.getBaseLocation() );
itab2.setVisible( true );
return workArea;
}
/*
* CControl uses this factory to build various objects that are used everywhere.
*
* Our customized CWorkingArea will ask this factory for a new SplitDockStation, that station
* actually does all the heavy work while CWorkingArea only offers a nice API.
*/
private static class CustomizedFactory extends EfficientControlFactory {
@Override
public CommonDockStation<SplitDockStation, CSplitDockStation> createSplitDockStation( CommonStationDelegate<CSplitDockStation> delegate ){
if( delegate.getStation() instanceof MinimizeableWorkingArea ) {
return new MinimizeableSplitDockStation( delegate );
}
else {
return super.createSplitDockStation( delegate );
}
}
}
/*
* This SplitDockStation wrapps its content into a panel, allowing additional Components
* to show up around the "original" station.
*/
public static class MinimizeableSplitDockStation extends CSplitDockStation {
private JPanel panel;
public MinimizeableSplitDockStation( CommonStationDelegate<CSplitDockStation> delegate ){
super( delegate );
panel = new JPanel( new BorderLayout() );
panel.add( super.getComponent(), BorderLayout.CENTER );
}
public JPanel getPanel(){
return panel;
}
@Override
public Component getComponent(){
return panel;
}
}
public static class MinimizeableWorkingArea extends CWorkingArea {
public MinimizeableWorkingArea( CControl control, String uniqueId ){
super( control, uniqueId );
setTitleShown( true );
// the delegate has been created by our customized factory, we can now add additional
// components to the station
MinimizeableSplitDockStation delegate = (MinimizeableSplitDockStation) getStation();
delegate.getPanel().add( new JButton( "Not in MinimizeableWorkingArea" ), BorderLayout.NORTH );
}
@Override
public boolean isMinimizable(){
// enable minimization of this station
return true;
}
}
// since we are at it, you may want to replace the default title for DockStations. This is
// how you do it:
private static void setupTitle( CControl control ){
DockTitleFactory factory = new DockTitleFactory(){
@Override
public void uninstall( DockTitleRequest request ){
// ignore
}
@Override
public void request( DockTitleRequest request ){
request.answer( new BasicDockTitle( request.getTarget(), request.getVersion() ) );
}
@Override
public void install( DockTitleRequest request ){
// ignore
}
};
DockTitleManager titles = control.getController().getDockTitleManager();
titles.registerClient( SplitDockStation.TITLE_ID, factory );
titles.registerClient( FlapDockStation.WINDOW_TITLE_ID, factory );
}
// And maybe you want to control the position of the title as well, you can use this
// piece of code for that
private static void setupDisplayer( CControl control ){
BasicDisplayerFactory factory = new BasicDisplayerFactory();
factory.setStationLocation( Location.TOP );
ThemeManager manager = control.getController().getThemeManager();
manager.setDisplayerFactory( ThemeManager.DISPLAYER_FACTORY + ".flap", factory );
manager.setDisplayerFactory( ThemeManager.DISPLAYER_FACTORY + ".split", factory );
}
}```