If it is possible to dock a floatable panel in a new window (frame) when disconnect it from a frame, similar with the function in MatLab or SciLab?
I don’t know how either of these applications work. But if you are using the common-framework, then you can create multiple “CContentAreas” by calling “CControl.createContentArea”, and you can put this CContentArea onto different frames. All these content-areas will be connected through the CControl, so moving a Dockable from one area to the other will be possible.
Thanks for your reply.
FlexDock was used in SciLab (flexdock - Java API for window docking). The dockable will be moved into a new window when ‘Undock’ (disconnect) action button was cliked.
I am thinking this may be possible in Docking Frames through override disconnect action. But I have no idea how to do it.
There is a property “ScreenDockStation.WINDOW_FACTORY”. You can use it to write your own factory that creates any kind of window for floating Dockables. I have to go to work now, but I’ll write a better explanation in the evening.
Here is an example, where the custom frame also contains a JMenuBar. The example is just reconfiguring the existing window, but you could write much more customized code.
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import bibliothek.gui.dock.ScreenDockStation;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.station.screen.ScreenDockWindow;
import bibliothek.gui.dock.station.screen.ScreenDockWindowFactory;
import bibliothek.gui.dock.station.screen.window.ScreenDockFrame;
import bibliothek.gui.dock.station.screen.window.WindowConfiguration;
public class CustomFrameTest {
public static void main( String[] args ) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
CControl control = new CControl( frame );
frame.add( control.getContentArea() );
control.putProperty( ScreenDockStation.WINDOW_FACTORY, new CustomWindowFactory() );
DefaultSingleCDockable dockable = new DefaultSingleCDockable( "id", "Title" );
control.addDockable( dockable );
dockable.setVisible( true );
frame.setBounds( 20, 20, 800, 800 );
frame.setVisible( true );
}
private static class CustomWindowFactory implements ScreenDockWindowFactory {
@Override
public ScreenDockWindow updateWindow( ScreenDockWindow window, WindowConfiguration configuration, ScreenDockStation station ) {
return createWindow( station, configuration );
}
@Override
public ScreenDockWindow createWindow( ScreenDockStation station, WindowConfiguration configuration ) {
return new CustomWindow( station, configuration );
}
}
private static class CustomWindow extends ScreenDockFrame implements ScreenDockWindow {
protected CustomWindow( ScreenDockStation station, WindowConfiguration configuration ) {
super( station, configuration, false );
init();
}
private void init() {
JFrame window = getFrame();
JMenuBar menuBar = new JMenuBar();
menuBar.add( new JMenu( "File" ) );
menuBar.add( new JMenu( "Edit" ) );
window.setJMenuBar( menuBar );
}
}
}
Thanks a lot for your kindly help! There are 4 dockables in my program, and they should be showed in different custom windows. I think the dockable can be got before creating a custom window, so the different custom windows can be created depending on dockable types. I have tried the following code, but I can not get a dockable from the ScreenDockStation (station.getDockableCount() is 0). How to revise it?
@Override
public ScreenDockWindow createWindow(ScreenDockStation station, WindowConfiguration configuration) {
int n = station.getDockableCount();
Dockable dockable = station.getDockable(0);
String id = dockable.getFactoryID();
switch (id){
case "Figure":
return new FrmFigure(station, configuration);
case "Editor":
return new FrmEditor(station, configuration);
}
return new FrmFigure(station, configuration);
}
@Override
public ScreenDockWindow updateWindow(ScreenDockWindow window, WindowConfiguration configuration, ScreenDockStation station) {
return createWindow(station, configuration);
}
}```
The factory does not know for which Dockable its windows will be used, and it has no way to find out. I think the best solution would be to override the method “ScreenDockWindow.setDockable”, and update the content of the window there.
Excellent! The following code works well powered by Docking Frames.
public FrmCustom(ScreenDockStation station, WindowConfiguration configuration) {
super(station, configuration, false);
}
@Override
public void setDockable(Dockable dockable){
super.setDockable(dockable);
init(dockable);
}
private void init(Dockable dockable){
if (dockable != null){
String text = dockable.getTitleText();
switch(text){
case "Figures":
this.init_Figure();
break;
case "Editor":
this.init_Editor();
break;
}
}
}
private void init_Figure() {
JFrame window = getFrame();
JMenuBar menuBar = new JMenuBar();
menuBar.add(new JMenu("File"));
menuBar.add(new JMenu("Figure"));
window.setJMenuBar(menuBar);
}
private void init_Editor() {
JFrame window = getFrame();
JMenuBar menuBar = new JMenuBar();
menuBar.add(new JMenu("File"));
menuBar.add(new JMenu("Editor"));
window.setJMenuBar(menuBar);
}
}```
Still has a problem for adding toolbar. How to add a toolbar at the north of the dockable?
My current code and result (the toolbar can only be added at right side):
JFrame window = getFrame();
JMenuBar menuBar = new JMenuBar();
menuBar.add(new JMenu("File"));
menuBar.add(new JMenu("Figure"));
window.setJMenuBar(menuBar);
JToolBar toolBar = new JToolBar();
JButton jButton_ZoomIn = new JButton();
jButton_ZoomIn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/meteoinfo/laboratory/resources/TSB_ZoomIn.Image.png"))); // NOI18N
jButton_ZoomIn.setToolTipText("Zoom In"); // NOI18N
jButton_ZoomIn.setFocusable(false);
jButton_ZoomIn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
jButton_ZoomIn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
jButton_ZoomIn.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
//jButton_ZoomInActionPerformed(evt);
}
});
toolBar.add(jButton_ZoomIn);
window.getContentPane().add(toolBar, BorderLayout.PAGE_START);
}```
GridLayout was used in ScreenDockFrame. I have tried to change the layout manager to BorderLayout in AbstractScreenDockWindow class:
if( window == null )
throw new IllegalArgumentException( "window must not be null" );
if( contentParent == null )
throw new IllegalArgumentException( "contentParent must not be null" );
this.window = window;
content = createContent( configuration );
content.setController( getController() );
if( configuration.isResizeable() ){
//contentParent.setLayout( new GridLayout( 1, 1 ) );
contentParent.setLayout(new BorderLayout());
}
else{
contentParent.setLayout( new ResizingLayoutManager( this, window ) );
}
contentParent.add( content );
Container parent = getDisplayerParent();
//parent.setLayout( new GridLayout( 1, 1 ));
parent.setLayout(new BorderLayout());
if( (configuration.isResizeable() || configuration.isMoveOnBorder()) && borderAllowed ){
if( parent instanceof JComponent && configuration.getBorderFactory() != null ){
border = configuration.getBorderFactory().create( this, (JComponent)parent );
border.setController( getController() );
borderModifier = new WindowBorder( (JComponent)parent );
borderModifier.setBorder( border );
borderModifier.setController( getController() );
}
Listener listener = new Listener();
parent.addMouseListener( listener );
parent.addMouseMotionListener( listener );
parent.addComponentListener( listener );
}
window.addComponentListener( new ComponentAdapter() {
@Override
public void componentResized( ComponentEvent e ) {
fireShapeChanged();
}
@Override
public void componentMoved( ComponentEvent e ) {
fireShapeChanged();
}
});
addScreenDockWindowListener( windowListener );
}```
```protected void showDisplayer( DockableDisplayer displayer ) {
if( this.displayer != displayer ){
if( this.displayer != null ){
getDisplayerParent().remove( this.displayer.getComponent() );
}
this.displayer = displayer;
if( displayer != null ){
getDisplayerParent().add( displayer.getComponent(), BorderLayout.CENTER);
}
}
validate();
}```
Then I can get the desired result:
But the jar file size compiled from the source code in "docking-frames-core" and "docking-frames-core-j6" is 5,595kb whick is much bigger than original docking-frames-core.jar file. Why?
Did you perhaps add the source code to the jar as well?
I would advice against repacking the framework, because every future update will be painful. Even making a copy of the classes you want to change would be better. I’ll look into the code too, perhaps there is an easy way to make the LayoutManager customizeable (but I won’t have an answer before the weekend).
Hello Beni,
Did you find an easy way to make the LayoutManager customizeable?
I did not yet work on the framework - summer was too hot, and I was too lazy.