Can't find a way to achieve a specific layout

Hi !

This project seems to be able to do absolutely everything, but I can’t find a way to have the layout I want.

Basically, my window is made of 4 parts as you can see in the following image :

I used a CGrid and managed to do almost what I wanted.

What I can’t do :

  • although panel inside SimpleDock 1 has a max witdh of 300px, the docking frame is always about 400px
  • how to fix one and for all the size of panel 2 ?

Many thanks !

When I hear “fixed size” I usually think of cheap programms… (no offense intended) you are certain you need fixed sizes? Because the framework is all about not having fixed sizes. “Hard” fixed sizes are not implemented, in the basic version the user always has the ability to resize anything he wants. You can replace some of the code that is responsible for this behavior, but it will require some work to get a good loking solution (and a “fixed size feature” is a thing that has a very low priority on my todo list).

About 1: what is the minimum and the preferred size? Because these are the only two sizes that are respected by the framework, max-size is always ignored.

About 2: You do realize that the user can drag and drop the Dockables in such a way that the size of 2 must change? There is no easy solution, but you could start by extending one of the "SplitLayoutManager"s. This interface is responsible for the layout and also handles some changes in the layout. A simple solution might look like this:


import javax.swing.JFrame;

import bibliothek.gui.Dockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.common.CContentArea;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.intern.station.CLockedResizeLayoutManager;
import bibliothek.gui.dock.common.layout.RequestDimension;
import bibliothek.gui.dock.station.split.Leaf;
import bibliothek.gui.dock.station.split.Node;
import bibliothek.gui.dock.station.split.Root;


public class Dock66 {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        final CControl control = new CControl(frame);
        CContentArea contentArea = control.getContentArea();
        
        final DefaultSingleCDockable dockable1 = new DefaultSingleCDockable("1");
        final DefaultSingleCDockable dockable2 = new DefaultSingleCDockable("2");
        final DefaultSingleCDockable dockable3 = new DefaultSingleCDockable("3");
        final DefaultSingleCDockable dockable4 = new DefaultSingleCDockable("4");
        
        
        dockable2.setResizeLocked( true );
        control.putProperty( SplitDockStation.LAYOUT_MANAGER, new CLockedResizeLayoutManager( control ){
//        	@Override
//        	public double validateDivider( SplitDockStation station, double divider, Node node ){
//        		if( affectedByDividerDrag( node, dockable2.intern() )){
//        			return node.getDivider();
//        		}
//        		return super.validateDivider( station, divider, node );
//        	}
//        	
//        	private boolean affectedByDividerDrag( Node node, Dockable child ){
//        		return node.getLeaf( child ) != null;
//        	}
        	
// always trigger the code for resize events, because this code handles "resize requests".
        	@Override
        	protected boolean isResize( Root root ){
	        	return true;
        	}

// always create a "resize request" for the dockable that should have a fixed size.
        	@Override
        	public RequestDimension prepareResize( Leaf leaf ){
        		if( leaf.getDockable() == dockable2.intern() ){
        			return new RequestDimension( 100, 300 );
        		}
        		return super.prepareResize( leaf );
        	}
        });
        
        final CGrid grid = new CGrid(control);
        grid.add( 0, 0, 1, 1, dockable1 );
        grid.add( 1, 0, 1, 1, dockable2 );
        grid.add( 2, 0, 3, 1, dockable3 );
        grid.add( 5, 0, 1, 1, dockable4 );
        contentArea.deploy( grid );
        
        frame.add(contentArea);
        frame.setSize(500, 500);
        frame.setVisible(true);
    }
}```

Thanks for your reply !

You can have a look at the program here : http://videso3d.googlecode.com

What I would like to achieve is to have 2 “docking zones” : one left and one right.

About 1 : max=min=preferred=300px. So I don’t understand why panel 1 is always too large when the app starts up… Of course the user can change the size if he wants to, but it should not take too much place at startup.

About 2 :
Panel 2 is a special panel containing a specific widget that must have a fixed width (it’s a double slider to filter objects). I will embed it in the panel 3 : it should do the job.

I will try your tips tomorrow !

Well, a size of 300px is possible as the application below shows. Are you perhaps giving to much widht to the first panel in the CGrid? Because the framework just streches all the panels until there is no more space, and if a panel starts big it gets big.

Maybe you can show me how you build your initial layout?

About 2: ok.

About the two zones. You may already know that you can create the behavior of Eclipse using a CWorkingArea (CControl.createWorkingArea). That might be an easy solution.
Or you can combine CGridAreas/CMinimizeAreas in (almost) any way you like.


import javax.swing.JFrame;

import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CGrid;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.theme.ThemeMap;

public class Dock02 {
	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.setTheme(ThemeMap.KEY_ECLIPSE_THEME);
		
		int width = 600;
		
		CGrid grid = new CGrid(control);
		grid.add(0, 0, 300, 1, new DefaultSingleCDockable("a", "A"));
		grid.add(0, 0, 300, 1, new DefaultSingleCDockable("b", "B"));
		grid.add(300, 0, width-300-100, 1, new DefaultSingleCDockable("c", "C"));
		grid.add(width-300-100, 0, 100, 1, new DefaultSingleCDockable("d", "D"));
		control.getContentArea().deploy(grid);
		
		frame.setBounds(20, 20, width, 600);
		frame.setVisible(true);
	}
}

Thanks for all your tips !

I didn’t manage to have my panel 1 to begin at 300px, but I’ll ive with it :slight_smile:

I’ll commit my code and will tell you once done.

It seems there’s a bug with EclipseTheme.

How to reproduce : take a grid like you defined in your first post.
Tell the last element to be minimized at startup (I use setExtendedMode).
Launch the app, normalize this element : it disappears…

Sorry, I was not able to reproduce the bug. When exactly do you use “setExtendedMode”? What kind of element do you minimize? After you normalized it, what is the result of “dockable.getBaseLocation”? Can you modify the code from the first post to reproduce the bug?

Here is the code :

		this.setLayout(new BorderLayout());

		//Panneau contextuel
		context = new ContextPanel();
				
		control = new CControl(this);
		control.setTheme(ThemeMap.KEY_ECLIPSE_THEME);
		control.setGroupBehavior(CGroupBehavior.TOPMOST);
		this.add(control.getContentArea(), BorderLayout.CENTER);
		
		DefaultSingleCDockable dockableDatas = new DefaultSingleCDockable("dataExplorer");
		DefaultSingleCDockable dockableWWD = new DefaultSingleCDockable("wwd");
		DefaultSingleCDockable dockableContext = new DefaultSingleCDockable("context");
		
		CGrid grid = new CGrid(control);
		grid.add(0, 0, 1, 1, dockableDatas);
		grid.add(1, 0, 3, 1, dockableWWD);
		grid.add(3, 0, 1, 1, dockableContext);
		control.getContentArea().deploy(grid);
		
		AltitudeRangeSlider rangeSlider = new AltitudeRangeSlider(wwd);
		rangeSlider.setUI(new NimbusMultiSliderUI(rangeSlider));
		JPanel wwdContainer = new JPanel(new BorderLayout());
		wwdContainer.add(rangeSlider, BorderLayout.WEST);
		wwdContainer.add(wwd, BorderLayout.CENTER);
		dockableWWD.setTitleShown(false);
		dockableWWD.add(wwdContainer);
		
		dockableDatas.add(new JPanel());
		
		dockableContext.add(context);
		dockableContext.setTitleText("Informations");
		dockableContext.setDefaultLocation(ExtendedMode.MINIMIZED, CLocation.base().minimalEast());
		dockableContext.setExtendedMode(ExtendedMode.MINIMIZED);
		dockableContext.setCloseable(false);
		context.setDockable(dockableContext);```

Ok, most likely the issue is, that “dockableContext” does not have a location in the “normalized mode”.

  • A very easy solution: include “dockableContent” in the CGrid when creating the CGrid, deploy the CGrid, then set the extended mode. That is the solution I would choose. Basically you press the “minimize” button before making the application visible, instead of putting the dockable at its minimized location directly.
  • More sophisticated: use “dockableContext.setDefaultLocation( ExtendedMode.NORMALIZED, … )” to set a default location.

[QUOTE=Beni]Ok, most likely the issue is, that “dockableContext” does not have a location in the “normalized mode”.

  • A very easy solution: include “dockableContent” in the CGrid when creating the CGrid, deploy the CGrid, then set the extended mode. That is the solution I would choose. Basically you press the “minimize” button before making the application visible, instead of putting the dockable at its minimized location directly.[/QUOTE]

I don’t understand, how is it different from what I do ?

**include “dockableContent” in the CGrid when creating the CGrid, ** line 19
deploy the CGrid, line 20
then set the extended mode line 35

Ou, I did not see that. :frowning:

I’ll run your application and report back later (I’m currently at work, can’t do that before the evening).

Back from the dead… well the forum is no longer offline :slight_smile: Although I do not know what happened.

I did run your code, I replaced your content by some JPanels to compile the code. Unfortunately the bug did not appear. The last idea I have is that the Components on your Dockables have a too big minimum/preferred size (and the minimized Dockable gets pushed and has only a size of 0). I think a good step would be to print out the minimum and the preferred size and ensure it is not much bigger than 100 pixels in each direction.

This is how I tested your code, including too big minimum/preferred size:

[Edit

One more thing, please execute this piece of code after you normalized the minimized Dockable.
System.out.println(control.getContentArea().getCenter());
This should print out a detailed description of the layout, and if there are any hidden elements or not.
/Edit]


import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

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.group.CGroupBehavior;
import bibliothek.gui.dock.common.mode.ExtendedMode;
import bibliothek.gui.dock.common.theme.ThemeMap;

public class Dock84 extends JFrame{
	public static void main( String[] args ){
		Dock84 d = new Dock84();
		d.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		d.setBounds( 20, 20, 400, 400 );
		d.setVisible( true );
	}
	
	private CControl control;
	private JPanel context;
	
	public Dock84(){
		control = new CControl(this);
		
		//Layout
		this.setLayout(new BorderLayout());

		//Panneau contextuel
		context = new JPanel();
				
		control = new CControl(this);
		control.setTheme(ThemeMap.KEY_ECLIPSE_THEME);
		control.setGroupBehavior(CGroupBehavior.TOPMOST);
		this.add(control.getContentArea(), BorderLayout.CENTER);
		
		DefaultSingleCDockable dockableDatas = new DefaultSingleCDockable("dataExplorer");
		DefaultSingleCDockable dockableWWD = new DefaultSingleCDockable("wwd");
		DefaultSingleCDockable dockableContext = new DefaultSingleCDockable("context");
		
		CGrid grid = new CGrid(control);
		grid.add(0, 0, 1, 1, dockableDatas);
		grid.add(1, 0, 3, 1, dockableWWD);
		grid.add(3, 0, 1, 1, dockableContext);
		control.getContentArea().deploy(grid);
		
//		AltitudeRangeSlider rangeSlider = new AltitudeRangeSlider(wwd);
//		rangeSlider.setUI(new NimbusMultiSliderUI(rangeSlider));
		JPanel wwdContainer = new JPanel(new BorderLayout());
//		wwdContainer.add(rangeSlider, BorderLayout.WEST);
//		wwdContainer.add(wwd, BorderLayout.CENTER);
		
		wwdContainer.setPreferredSize( new Dimension( 800, 400 ) );
		wwdContainer.setMinimumSize( new Dimension( 800, 400 ) );
		dockableWWD.setTitleShown(false);
		dockableWWD.add(wwdContainer);
		
		JPanel dataPanel = new JPanel();
		dataPanel.setPreferredSize( new Dimension( 400, 400 ) );
		dataPanel.setMinimumSize( new Dimension( 400, 400 ) );
		dockableDatas.add(dataPanel);
		
		dockableContext.add(context);
		dockableContext.setTitleText("Informations");
		dockableContext.setDefaultLocation(ExtendedMode.MINIMIZED, CLocation.base().minimalEast());
		dockableContext.setExtendedMode(ExtendedMode.MINIMIZED);
		dockableContext.setCloseable(false);
//		context.setDockable(dockableContext);
	}
}```

This is what I get after the panel is normalized :

	Node[ HORIZONTAL , id=1310368561015, placeholders={}]
		Leaf[ , placeholders={dock.single.dataExplorer, dock.single.STIP, dock.single.Edimap, dock.single.KML}, id=1310368561017 ]
		Node[ HORIZONTAL , id=1310368561019, placeholders={}]
			Leaf[ , placeholders={}, id=1310368561021 ]
			Leaf[ Informations, placeholders={dock.single.context}, id=1310368561023 ]

I also tried to remove minimumsize and preferred size of this panel, but it doesn’t change anything…

Ok, I think I found the guilty line :

this.setExtendedState(JFrame.MAXIMIZED_BOTH);

When I delete this line, it works great.

This line is placed at the end of the method.

I don’t know why this line causes the bug, it shouldn’t react differently than a “setSize”. I’ll certainly add this line to my applications and see if it happens there as well.

Something that often helps: You might try and call “this.validate()” before calling “setExtendedState”.

I already do that…

The code is now avalaible at http://code.google.com/p/videso3d/source/browse/trunk/src/fr/crnan/videso3d/ihm/MainWindow.java

I currently have my hands full with work (deadline is approaching…), but I’ll check your code out on the weekend.

Thanks !
Don’t worry, there’s no matter of urgency !

Ok, I checked out, then installed a 32 bit system :slight_smile: , then started your application. I did print out the minimum size of the „wwdContainer“, which was „width=964,height=622“ (which is rather big). I forced a smaller size onto wwdContainer (using „setMinimumSize“). I also removed the line „control.removeDockable(dockableDatas)“ to have more than one Dockable. That already seemed to be enough, all Dockables got a reasonable size.