Looking for a MultipleCDockable sample

Hello all,

I’m looking for MultipleCDockable and MultipleCDockableFactory sample.
I plane to use this framework for my application.
How can I merge two SingleCDockable in the same location programmaticaly, like we can do it with mouse action, at the beginning.

Best regards
(Sorry for my english, I’m french :frowning: )

1.a. There is a demo-application “paint” included in the framework. It’s class “PictureDockable” is a MultipleCDockable, the classes “ViewManager.PictureFactory” and “ViewManager.PictureLayout” are factory and layout.

1.b. An example from an application I’m currently writing. The application is a map editor for same game and maps can be displayed in MultipleCDockable’s

The Dockable:

public class MapView extends DefaultMultipleCDockable{
    /** zoom factor where 100.000 means 100% */ 
    private int zoom = 100000;
    
    private MapPanel panel = new MapPanel();
    
    public MapView( MapViewFactory factory ){
        super( factory );
        setTitleText( "Map" );
    }

    
    public void setZoom( int zoom ) {
        if( zoom < 1000 )
            zoom = 1000;
        if( zoom > 100000000 )
            zoom = 100000000;
        
        this.zoom = zoom;
        panel.updateZoom();
    }
    
    public int getZoom() {
        return zoom;
    }
    
    private class MapPanel extends JPanel{  
        public void updateZoom(){
           // stuff
        }
        
        
        @Override
        protected void paintComponent( Graphics g ) {
           // stuff      
        }
    }
}

… and its factory…

public class MapViewFactory implements MultipleCDockableFactory<MapView, MapViewFactory.MapViewLayout>{
    
    public MapViewLayout create() {
        return new MapViewLayout();
    }

    public MapView read( MapViewLayout layout ) {
        MapView view = new MapView( this );
        view.setZoom( layout.getZoom() );
        return view;
    }

    public MapViewLayout write( MapView view ) {
        MapViewLayout layout = new MapViewLayout();
        layout.setZoom( view.getZoom() );
        return layout;
    }
    

    public static class MapViewLayout implements MultipleCDockableLayout{
        private int zoom;

        public void setZoom( int zoom ) {
            this.zoom = zoom;
        }
        
        public int getZoom() {
            return zoom;
        }
        
        public void readStream( DataInputStream in ) throws IOException {
            zoom = in.readInt();
        }

        public void readXML( XElement element ) {
            element.addElement( "zoom" ).setInt( zoom );
        }

        public void writeStream( DataOutputStream out ) throws IOException {
            out.writeInt( zoom );
        }

        public void writeXML( XElement element ) {
            zoom = element.getElement( "zoom" ).getInt();
        }
    }
    
}```

2.a 
You can do that with help of the location information:
```CDockable a = ...
CDockable b = ...
		
b.setLocation( a.getBaseLocation().aside() );```
The method "aside" should change the location a bit such that b is added "behind" (on the next tab).
P.S. it might be a good idea to make "b" invisible before changing its location, otherwise "a" can change its location just in the exact moment when you call "b.setLocation"...

2.b
Or if you use a CGrid to set the initial locations then just use the same coordinates for the Dockables (or assign many Dockables at once, the method "add" uses varargs).

Waow, very fast ! :wink:

We planed to make a new GUI for our aerodynamic software, with eclipse Style. After several research, it seems that your framework correspond to our requirements.
Perhaps I will can share experience to this new GUI development with you.

Thanks a lot, very great framework.

If you have some cool screenshots, I would be happy to put them onto my homepage :wink:

How can I attached image to show you my problem ?

For picture of the result, no problem.
I send that during conception phase.

On the “Quick Reply” click “Go Advanced”.

Then have a look in “Additional Options”, the second panel reads “Attach Files”. Click onto “Manage Attachements”.

All right, I want to have the Red and Blue Area (picture 1) in the same area (picture2).
picture 1 -> picture 2

Try something like this (I did not test this code, but it should work):


blue.setVisible( false );
CLocation redLocation = red.getBaseLocation();
blue.setLocation( redLocation.aside() );
blue.setVisible( true );
red.toFront();

TouchDown !!!

Thanks a lot. I just need to cast SingleCDockable to DefaultSingleCDockable to have acces to toFront().

Is there a way to manage location area, instead of put the BLUE in the RED location.

JFrame frame = new JFrame( "MCMS" );
CControl control = new CControl( frame );
	
frame.add( control.getContentArea() );
 	    
control.setTheme(ThemeMap.KEY_ECLIPSE_THEME);
CGrid grid = new CGrid( control );
SingleCDockable treeArea 	= createDockable("TreeView",Color.CYAN );
SingleCDockable modelArea 	= createDockable("Model",	Color.GREEN );
SingleCDockable processArea = createDockable("Search",	Color.RED ) ;		
SingleCDockable historyArea = createDockable("History",	Color.BLUE ) ;
		
grid.add( 0, 0, 1, 2, treeArea);
grid.add( 1, 0, 1, 1, modelArea );		
grid.add( 1, 1, 1, 1, processArea );
grid.add( 1, 1, 1, 1, historyArea );		
control.getContentArea().deploy( grid );

historyArea.setVisible( false );
CLocation redLocation = processArea.getBaseLocation();
historyArea.setLocation( redLocation.aside() );
historyArea.setVisible( true );
((DefaultSingleCDockable)processArea).toFront();

Now I’m not quite sure of what you mean. With the newest version lines 15/16 should already make sure that processArea and historyArea share the same location.

If you mean that processArea is selected (and historyArea hidden): CGrid doesn’t support this right now. I could and should add some little feature next weekend…

[Edit. New API Change for the next version:

  • API: CGrid/SplitDockGrid: new method select/setSelected to preselect a CDockable/Dockable in a stack of Dockables.
    This is already in the repository, and I compile the whole library sometime during the weekend.]

The previous piece of code give me what I want for beginning, see picture attached.

My goal is to declare :
(1) A Left Area, where there is the JTree( and/or GraphView) connected to a DataBase.
(2) A Top Right Area, where I display (like in eclipse) what node I select in the JTree.(several display at same time like source code in eclipse)
(3) A Bottom Right Area, where there are process results (search, history, etc…).

So I ask if there is an object to manage each Area, and say I put this in (1), that in (2), etc… instead of virtually say put historyArea in where I put processArea.
:frowning: I hope you understand.

If I remove lines 19-23, processArea and historyArea are not in the same place. CGrid seems to work like a 3x3 grid instead of a 2x2 like I expected.

Ah, now I understand.

  1. The answer is “no”. Because Dockables can be moved to any position putting them into some kind of group would soon become meaningless.

And to have some special grouping mechanism just for building the layout would be too much overhead.

In Eclipse you would use an “IFolderLayout” (if implementing an “IPerspectiveFactory”) but if you later look carefully at how Eclipse behaves it becomes obvious that this solution is not working properly at all (and there is no way to repair it).

  1. The trick that allows to remove lines 19-23 is relatively new, you would have to use version 1.0.7 preview 6b (it is not working in any other version).

:wink: So, my english is not so bad.

  1. In Eclipse, if you close all source code in the Top Right Area, it stay a void Area, have you the same things in your framework ? Actually, the Bottom Right Area fill the Top Right Area.

  2. Is there a way to programmatically place the vertical and horizontal splitter ?
    for example, put Vertical Splitter at 25% of the width.

The version 1.0.7 preview 6b is Beta or Release version ?
I must only use release version.

Thanks a lot for your reactivity. ::klatsch

  1. The “CWorkingArea” is written to do exactly that. New CWorkingAreas can be created through “CControl.createWorkingArea”. A CWorkingArea behaves like any other Single-CDockable.
    If you want a CDockable to become child of a CWorkingArea call “CDockable.setWorkingArea”. Afterwards it is not possible to move the dockable outside the working area (exception minimizing or maximizing). It is also not possible to drop some random Dockable onto the working-area.

2.a) If you are using CGrid: just play around with the widht and height of Dockables.
2.b) You can access the SplitDockStation which shows your elements. Then ask the station for its root “getRoot”, then search the node you want to change and call “setDivider”. But this can become really ugly…
2.c) You can order a size-request for some CDockables and hope the sort everything out like you want…

  1. To the whacky notion of “release” and “beta”.
    In the case of this framework the difference between “release” and “beta” is:
  • a release version contains an updated documentation

In the very special case of version 1.0.7p6b: it is a release candidate and only the documentation is incomplete. No catastrophic errors were found during the last weeks, so: 1.0.7p6b can be used as save as version 1.0.6.

Good Morning,

Version 1.0.7p6b Dowloaded and I replaced version 1.0.6.

So I tried to use CWorkingArea.
It displays fine and works like expected, but CDockable doesn’t appear in it… If I used setVisible() on CDockable, it appears under the workingArea, not in it. I surely missed something, I think.

You seem to have already found a solution to my problem… :wink:

...
// Create WorkingArea
CWorkingArea exploreArea = control.createWorkingArea("Explore");
CWorkingArea detailsArea = control.createWorkingArea("Details");
CWorkingArea processArea = control.createWorkingArea("Process");		

// Create CDockable
SingleCDockable treePanel 	 = createDockableTree("TreeView",  Color.CYAN );
SingleCDockable treePanel2 	 = createDockableTree("GraphView", Color.BLUE );		
SingleCDockable modelPanel 	 = createDockable("Model",	 Color.GREEN );
SingleCDockable searchPanel  = createDockable("Search",	 Color.RED ) ;		
SingleCDockable historyPanel = createDockable("History", Color.BLUE ) ;
		
// Add CDockable to CControl
control.add( treePanel );
control.add( treePanel2 );
control.add( modelPanel );
control.add( searchPanel );
control.add( historyPanel );
		
// Link CDockable to WorkingArea
treePanel.setWorkingArea(exploreArea);
treePanel2.setWorkingArea(exploreArea);		
modelPanel.setWorkingArea(detailsArea);
searchPanel.setWorkingArea(processArea);
historyPanel.setWorkingArea(processArea);		

// Place WorkingArea
grid.add( 0, 0, 1, 3, exploreArea);
grid.add( 1, 0, 3, 2, detailsArea );		
grid.add( 1, 1, 3, 1, processArea );
control.getContentArea().deploy( grid );
...

Sorry, my fault. The initial position must be set manually:

		CWorkingArea exploreArea = control.createWorkingArea("Explore");
		CWorkingArea detailsArea = control.createWorkingArea("Details");
		CWorkingArea processArea = control.createWorkingArea("Process");		

		// Create CDockable
		SingleCDockable treePanel 	 = createDockable("TreeView",  Color.CYAN );
		SingleCDockable treePanel2 	 = createDockable("GraphView", Color.BLUE );		
		SingleCDockable modelPanel 	 = createDockable("Model",	 Color.GREEN );
		SingleCDockable searchPanel  = createDockable("Search",	 Color.RED ) ;		
		SingleCDockable historyPanel = createDockable("History", Color.BLUE ) ;
				
		// Add CDockable to CControl
		control.add( treePanel );
		control.add( treePanel2 );
		control.add( modelPanel );
		control.add( searchPanel );
		control.add( historyPanel );
				
		// Link CDockable to WorkingArea
		treePanel.setWorkingArea(exploreArea);
		treePanel.setLocation( exploreArea.getStationLocation() );
		
		treePanel2.setWorkingArea(exploreArea);
		treePanel2.setLocation( exploreArea.getStationLocation() );
		
		modelPanel.setWorkingArea(detailsArea);
		modelPanel.setLocation( detailsArea.getStationLocation() );
		
		searchPanel.setWorkingArea(processArea);
		searchPanel.setLocation( processArea.getStationLocation() );
		
		historyPanel.setWorkingArea(processArea);		
		historyPanel.setLocation( processArea.getStationLocation() );

		// Place WorkingArea
		CGrid grid = new CGrid();
		grid.add( 0, 0, 1, 3, exploreArea);
		grid.add( 1, 0, 3, 2, detailsArea );		
		grid.add( 1, 1, 3, 1, processArea );
		control.getContentArea().deploy( grid );
		
		treePanel.setVisible( true );
		treePanel2.setVisible( true );
		modelPanel.setVisible( true );
		searchPanel.setVisible( true );
		historyPanel.setVisible( true );```

[Edit: The fact that the location has to be set manually is a bug... well, it is only one line of missing code. :mad: ]

::klatsch
Thanks a lot, it’s working now.

I have some client support to do now. :grr:

I hope to finish it rapidly to continue investigate this great framework.

to be continued…