DefaultDockable - title bar (buttons and icons)

Hi,

beginner question, please be patient.

I am using a DefaultDockable along with SplitDockStation

[ol]
[li]Control the content of the top bar of DefaultDockabe (remove icon, add buttons etc…)
[/li]

First question, in the photo below, I have views (instances of JPanel) that contains buttons at the top (what’s in the green square in the screenshot below) , I am adding these views as a component to an instance of DefaultDockable each. I am ending up with an additional top bar (what’s in the red square), along with the maximize button and an icon.

I would like to get hold of the top bar container that DefaultDockable is using to put the maximize button, and add the swing controls I have to this container, and get rid of my tool bar (the green squre).
In brief move all the content of the green square to the red square.

Also, I’d like to get rid of the icon on the top left of DefaultDockable, and change the maximize icon, and add a close button.
One more thing, I want to control the colour of the title bar - I guess once I get hold of the container, I can control the colour, and add buttons to it.

[li]Control the tab panel when in tabbed view (remove icon, add text and a close button)
[/li]
When the dockable are dragged by users to make up a tabbed pane, I would like to be able to add text and get rid of the default icon.
Also, I would like to get ride of the left side bar (the one with the red square around it).


[/ol]

http://forum.byte-welt.de/showthread.php?t=3812 explains how I get rid of the icon, so don’t worry about that.

I have seen how we can add actions, which are eventually buttons - although I couldn’t tell if I can control behaviours, I saw that we can change the painting. Both are ok - but it would be much more straightforward to get hold of the JPanel that make up the top bar…

Using a DefaultSingleCDockable and a CContentArea (all these things are from the Common API) would give you some nice additional features - like a „minimize button“ and much better handling of layouts…

I would like to get hold of the top bar container that DefaultDockable is using to put the maximize button, and add the swing controls I have to this container, and get rid of my tool bar (the green squre).
In brief move all the content of the green square to the red square.

Assuming you change from using the Core API to using the Common API… there is a class called „TitleWithTextFieldExample“ which could be interesting for your. That example shows how a client can put a JTextField into the title - and of course instead of a JTextField you could use any JComponent.

If you just want to have additional buttons (and don’t care about their exact look), you can also use the method DefaultCDockable.addAction, where the „action“ is an instance of „CButton“.

If you refuse using the Common API, you should have a look at the class „ActionsExample“.

and add a close button

Oh, did I already mention that the Common API adds that button? There is even a method „setCloseable“ on each DefaultCDockable, so you can easily have Dockables with the close button and Dockables without the close button.

change the maximize icon

DockController controller = control.getController();
controller.getIcons().setIconClient( "close", yourIcon );```


> One more thing, I want to control the colour of the title bar - I guess once I get hold of the container, I can control the colour, and add buttons to it.

The DefaultCDockable from the Common API offers a method "getColors" with which you access a set of default colors.

Then there is the option to replace the title with a custom implementation, have a look at "TitleExample".

And don't forget, that there are different "themes", you can switch them with "CControl.setTheme".



> When the dockable are dragged by users to make up a tabbed pane, I would like to be able to add text and get rid of the default icon.

Search for a method called "setTitleText" on your Dockable, there you can set the text.


> Also, I would like to get ride of the left side bar (the one with the red square around it).

Will not be present when using the Common API.

Hi again,

sorry I didn’t manage to have a look at this till now, I may be blind, but I couldn’t find any occurence of TitleWithTextFieldExample

I tried to grep through the source etc… nothing. Is that the exact spelling?

If you can point me at the relevant examples it would be great. I read the documentation Common.pdf. There is quite a lot of digest, I’ll need to go through it again, and try to spend a little bit more time looking into the examples - but if you could point me to relevant ones, (and how I can find them) that could save me a lot of time.

Thanks a lot
Charbel

[QUOTE=charbel]Hi again,

sorry I didn’t manage to have a look at this till now, I may be blind, but I couldn’t find any occurence of TitleWithTextFieldExample

I tried to grep through the source etc… nothing. Is that the exact spelling?
[/quote]
I am very certain these class exists, as this link shows

If you can point me at the relevant examples it would be great. I read the documentation Common.pdf. There is quite a lot of digest, I’ll need to go through it again, and try to spend a little bit more time looking into the examples - but if you could point me to relevant ones, (and how I can find them) that could save me a lot of time.

Most examples are in the project „docking-frames-demo-tutorial“, make sure to include it in your workspace.

Ask if you need information about a specific issue, but I cannot answer philosophical questions like „where are the relevant examples“…

I read the documentation Common.pdf.

I hope you do not go insane when reading that document. :eek: It’s an intro, but I guess the examples from the tutorial-project can help more than that document.

oh, now I can see how this is done. mmmm I’ll try to implment something similar, where instead of doing it for each of my components, I’m considering only “wrapping” the JPanel like you show in the example, and since I already have all my component’s actions managed etc, I just pass a reference to JPanel instance that I have, and it should work.

that’s the plan, I’ll try to implement this now

after a long day of refactoring… I get this: “the factory for a MultipleCDockable is not registered”

How do I register my factory?

There is a method called CControl.addMultipleDockableFactory, it has to be called with every factory that you are using (before registering any MultipleCDockables).

Does the factory’s createDockable() method ever get called from within the framework itself?

with my design and my needs, I’m ending up with creating one factory for each Dockable.

What I am doing at the moment is: create a factory with every MultipleCDockable instance I create, because I’m trying to hide away the complexity of creating a custom action from the user, and the custom action in my case is a JComponent which incidently happen to be a JPanel that contain many other JButtons and other components that I need - that are already created and managed outside of the Docking Framework side - and I didn’t want to couple with the frame work.
The only way I could do it was to pass it on the constructor for the factory, and as every Dockable has a different JPanel instance, I ended up with this awkward design…

I still think, it would be much cleaner, to be able to get hold of the JPanel instance that make up the top bar of the Dockable. This way the client app can add whatever swing components on there without relying on the framework’s action mechanism.

The factory is used when writing or reading a layout (usually from a file), or when using the perspective API, or when using the methods CControl.save and load.

Do you have a limited or an unlimited amount of Dockables?

If limited, and if you have a factory to dockable ratio of 1:1, then you could use SingleCDockables instead. They do not need to be associated with a factory (they can, for lazy loading). If using SingleCDockables it is the clients job to make sure each of them has a unique id, and that all of them are registered at the CControl.

And I cannot agree about the cleanliness of access the “top bar” (it is a “DockTitle”), especially since it is replaced during drag and drop operations, and since a Dockable can have more than one “top bar” at the same time.

more questions, how do I control the position of the action I add?

Usually the methods of DefaultCDockable should be enough, for example “insertAction” allows you to set the index of a new action.

The actions added to a CDockable will always appear on the left side of actions like “minimize”, “close”, etc… if you need actions on the right side you are going to need some trickery:


import javax.swing.JFrame;

import bibliothek.gui.dock.action.DefaultDockActionSource;
import bibliothek.gui.dock.action.LocationHint;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.action.CAction;
import bibliothek.gui.dock.common.action.CButton;
import bibliothek.gui.dock.common.intern.DefaultCommonDockable;

public class OrderOfActions {
	public static void main( String[] args ){
		JFrame frame = new JFrame();
		CControl control = new CControl(frame);
		
		frame.setBounds( 20, 20, 400, 200 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.add( control.getContentArea() );
		
		CustomDockable dockable = new CustomDockable( "id", "Title" );
		CButton button = new CButton( "Hello", null );
		button.setShowTextOnButtons( true );
		dockable.addSpecialAction( button );
		
		control.addDockable( dockable );
		dockable.setVisible( true );
		
		frame.setVisible( true );
	}
	
	private static class CustomDockable extends DefaultSingleCDockable{
		private DefaultDockActionSource specialGroupOfActions;
		
		public CustomDockable( String id, String title ){
			super( id, title );
			System.out.println(specialGroupOfActions);
		}
		
		@Override
		protected DefaultCommonDockable createCommonDockable(){
			// this is the location of our special group of actions
			LocationHint location = new LocationHint( LocationHint.DOCKABLE, LocationHint.VERY_RIGHT );
			
			// this method is called from the super constructor, hence we need to initialize
			// specialGroupOfActions here.
			specialGroupOfActions = new DefaultDockActionSource( location );
			
			return new DefaultCommonDockable( this, getClose(), specialGroupOfActions);
		}
		
		public void addSpecialAction( CAction action ){
			specialGroupOfActions.add( action.intern() );
		}
	}
}

ah thanks a lot!

now I’m adding a JPanel as a CAction,
1- how can I get the JPanel to take the whole space?
2- how can I decide to remove or include the minimize, disconnect, and maximize buttons
3- how can I change the icons of the minimize, disconnect, maximize buttons
4- how can I add a close button, and how can I add an action listener to all those buttons.
5- how can I change the colours of the top bar

Please describe the issue, not what you think is the solution.

What is the final goal? Is the final goal to completely replace the DockTitle? Because there is a big difference between “showing some buttons” and “replacing the entire DockTitle”. A mockup may help.

About the questions like “how to add a close button”, I may redirect you to here, where some questions were already answered.

[QUOTE=Beni]Please describe the issue, not what you think is the solution.

What is the final goal? Is the final goal to completely replace the DockTitle? Because there is a big difference between “showing some buttons” and “replacing the entire DockTitle”. A mockup may help.[/QUOTE]

Sorry, I’ll rephrase.
There are a few questions above, I’ll expand on 1- (thanks for referring me to an answer for 4-).

So, from previous discussions, I assumed that replacing the DockTitle is not really possible, or at least getting hold of a JPanel that I could use to modify the components that are shown on the title bar is not possible.

So, I created a CAction class CPanelAction extends CAction with a JPanel as the component.

1- The question is, how can I expand this CAction (which is a JPanel) to fill the whole space.

the other questions as per above:

2- how can I decide to remove or include the minimize, disconnect, and maximize buttons
3- how can I change the icons of the minimize, disconnect, maximize buttons
4- how can I add a close button, and how can I add an action listener to all those buttons. I’ll have a look at the solution you referred me to
5- how can I change the colours of the top bar <-- the colour currently changes between selected and not selected, I would like to control both those colours!

thank you for your time!

[QUOTE=charbel][
So, from previous discussions, I assumed that replacing the DockTitle is not really possible, or at least getting hold of a JPanel that I could use to modify the components that are shown on the title bar is not possible.[/quote]

Ok, I guess there was some bad communication. I’m sorry about that. Replacing a DockTitle is possible, accessing not. And for replacing you should have a look at the class “TitleExample” which is also in the tutorial project (In a few words: implement the interface DockTitle and DockTitleFactory, register the factory at the DockTitleManager).

I’ll wait with answering the other questions, while you decide whether replacing is an option for you.

[QUOTE=Beni]Usually the methods of DefaultCDockable should be enough, for example “insertAction” allows you to set the index of a new action.

The actions added to a CDockable will always appear on the left side of actions like “minimize”, “close”, etc… if you need actions on the right side you are going to need some trickery:


import javax.swing.JFrame;

import bibliothek.gui.dock.action.DefaultDockActionSource;
import bibliothek.gui.dock.action.LocationHint;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.common.action.CAction;
import bibliothek.gui.dock.common.action.CButton;
import bibliothek.gui.dock.common.intern.DefaultCommonDockable;

public class OrderOfActions {
	public static void main( String[] args ){
		JFrame frame = new JFrame();
		CControl control = new CControl(frame);
		
		frame.setBounds( 20, 20, 400, 200 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		frame.add( control.getContentArea() );
		
		CustomDockable dockable = new CustomDockable( "id", "Title" );
		CButton button = new CButton( "Hello", null );
		button.setShowTextOnButtons( true );
		dockable.addSpecialAction( button );
		
		control.addDockable( dockable );
		dockable.setVisible( true );
		
		frame.setVisible( true );
	}
	
	private static class CustomDockable extends DefaultSingleCDockable{
		private DefaultDockActionSource specialGroupOfActions;
		
		public CustomDockable( String id, String title ){
			super( id, title );
			System.out.println(specialGroupOfActions);
		}
		
		@Override
		protected DefaultCommonDockable createCommonDockable(){
			// this is the location of our special group of actions
			LocationHint location = new LocationHint( LocationHint.DOCKABLE, LocationHint.VERY_RIGHT );
			
			// this method is called from the super constructor, hence we need to initialize
			// specialGroupOfActions here.
			specialGroupOfActions = new DefaultDockActionSource( location );
			
			return new DefaultCommonDockable( this, getClose(), specialGroupOfActions);
		}
		
		public void addSpecialAction( CAction action ){
			specialGroupOfActions.add( action.intern() );
		}
	}
}
```[/QUOTE]

I tried the example above with  L LocationHint.VERY_LEFT and it didn't seem to have any effect.. is that normal?

I cannot answer that question unless you tell me what you effect you did expect :wink:

he he he - I expected my Action to be shown on the left hand side :slight_smile:
it’s appearing on the right hand side!

let me try to extract a simple example and upload. (might take a while)
I’m sure I’m doing something wrong.

All the actions are put on one JPanel, and that JPanel is always as the right end of the title. The LocationHint only orderes the actions on that action-panel. Actions will never show up on left side of the title-text.

More control over the placement of the actions can only be achieved by implementing a custom DockTitle.