Remove title from some dockables

Hi,

I am using defaultDockable and I need to have some dockables in my application without a title.
How can I customize those dockables and remove their titles?

Thx

If it is only this one Dockable, then overriding requestDockTitle (a method of Dockable) should do the trick. Like in the code below. In older versions this method was called “getDockTitle”.

    public void requestDockTitle( DockTitleRequest request ){
      	DockTitleVersion version = request.getVersion();
        	
        boolean hide = 
            version.getID().equals( SplitDockStation.TITLE_ID ) ||
            version.getID().equals( StackDockStation.TITLE_ID ) ||
            version.getID().equals( ScreenDockStation.TITLE_ID ) ||
            version.getID().equals( FlapDockStation.WINDOW_TITLE_ID );
	        
        if( hide ){
            request.answer( null );
        }
        else{
         	super.requestDockTitle( request );
        }
    }

Hi,

I override the requestDockTitle, but I still having the title of my second dockable. Could you please advice?


 
 
**[SIZE=2]public[/SIZE]**
[LEFT]**[SIZE=2]class[/SIZE]** HideTitleExample {[/LEFT]
 
 
[LEFT]**[SIZE=2]public[/SIZE]** HideTitleExample() {

JFrame frame = **[SIZE=2]new[/SIZE]** JFrame();
[LEFT]frame.setSize(700, 500);[/LEFT]
[/LEFT]

 
 
 
 
[LEFT]DockController controller = **[SIZE=2]new[/SIZE]** DockController();

controller.setTheme(**[SIZE=2]new[/SIZE]** EclipseTheme());[/LEFT]

 
 
 
 
[LEFT]SplitDockStation splitDockStation = **[SIZE=2]new[/SIZE]** SplitDockStation();

controller.add(splitDockStation);[/LEFT]

 
 
 
 
[LEFT][SIZE=2]//First [U]dockable[/U][/SIZE]

DefaultDockable firstDockable = [/LEFT]

 
 
 
[LEFT]**[SIZE=2]new[/SIZE]** DefaultDockable([SIZE=2]"First Dockable"[/SIZE]);[/LEFT]
 
[LEFT]splitDockStation.drop(firstDockable);[/LEFT]
 
 
 
[LEFT][SIZE=2]//Second [U]dockable[/U][/SIZE]

DefaultDockable secondDockable = [/LEFT]

 
 
 
[LEFT]**[SIZE=2]new[/SIZE]** DefaultDockable([SIZE=2]"Second Dockable"[/SIZE]) {[/LEFT]
 
[LEFT][SIZE=2]@Override[/SIZE]

**[SIZE=2]public[/SIZE]****[SIZE=2]void[/SIZE]** requestDockTitle(DockTitleRequest request) {
[LEFT]request.answer(**[SIZE=2]null[/SIZE]**);
}
};
splitDockStation.drop(secondDockable);[/LEFT]
[/LEFT]

 
 
 
 
[LEFT]frame.add(splitDockStation, BorderLayout.**[SIZE=2]CENTER[/SIZE]**);

frame.setVisible(**[SIZE=2]true[/SIZE]**);
[LEFT]}[/LEFT]
[/LEFT]

 
 
 
 
 
[LEFT]**[SIZE=2]public[/SIZE]****[SIZE=2]static[/SIZE]****[SIZE=2]void[/SIZE]** main(String[] args) {

**[SIZE=2]new[/SIZE]** HideTitleExample();
[LEFT]}[/LEFT]
[/LEFT]

 
 
[LEFT]}[/LEFT]
 

Well, this is not a title, it is a tab… (people seem never to understand that these are two totally different concepts).

What you are locking for is the code below. You should however realise that your user gets in big trouble if he starts to stack up Dockables as he can no longer select the one element with no tab… In general I really adwise against having a Dockable without title and icon.


import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;

import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.eclipse.stack.EclipseTabPane;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.ArchGradientPainter;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.BorderedComponent;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.InvisibleTab;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.InvisibleTabPane;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.TabComponent;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.TabPainter;
import bibliothek.extension.gui.dock.theme.eclipse.stack.tab.TabPanePainter;
import bibliothek.gui.DockController;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.DockElement;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.station.stack.tab.layouting.TabPlacement;

public class HideTitleExample {

	public HideTitleExample(){
		JFrame frame = new JFrame();
		frame.setSize( 700, 500 );

		DockController controller = new DockController();
		controller.setTheme( new EclipseTheme() );
		
		final DefaultDockable firstDockable = new DefaultDockable( "First Dockable" );
		final DefaultDockable secondDockable = new DefaultDockable( "Second Dockable" );
		
		TabPainter painter = new TabPainter() {
			public Border getFullBorder( BorderedComponent owner, DockController controller, Dockable dockable ){
				return ArchGradientPainter.FACTORY.getFullBorder( owner, controller, dockable );
			}
			
			public TabComponent createTabComponent( EclipseTabPane pane, Dockable dockable ){
				if( dockable == secondDockable ){
					return new Invisible( dockable );
				}
				else{
					return ArchGradientPainter.FACTORY.createTabComponent( pane, dockable );
				}
			}
			
			public InvisibleTab createInvisibleTab( InvisibleTabPane pane, Dockable dockable ){
				return ArchGradientPainter.FACTORY.createInvisibleTab( pane, dockable );
			}
			
			public TabPanePainter createDecorationPainter( EclipseTabPane pane ){
				return ArchGradientPainter.FACTORY.createDecorationPainter( pane );
			}
		};
		controller.getProperties().set( EclipseTheme.TAB_PAINTER, painter );

		SplitDockStation splitDockStation = new SplitDockStation();
		controller.add( splitDockStation );
		
		splitDockStation.drop( firstDockable );
		splitDockStation.drop( secondDockable );

		frame.add( splitDockStation, BorderLayout.CENTER );
		frame.setVisible( true );
	}

	public static void main( String[] args ){
		new HideTitleExample();
	}

	private class Invisible implements TabComponent{
		private JPanel panel;
		private DockElement element;
		
		public Invisible( DockElement element ){
			panel = new JPanel();
			panel.setPreferredSize( new Dimension( 0, 0 ) );
			this.element = element;
		}
		
		public void bind(){
			// ignore
		}

		public Component getComponent(){
			return panel;
		}

		public Dimension getMinimumSize( TabComponent[] tabs ){
			return new Dimension( 0, 0 );
		}

		public Insets getOverlap( TabComponent other ){
			return new Insets( 0, 0, 0, 0 );
		}

		public Dimension getPreferredSize( TabComponent[] tabs ){
			return new Dimension( 0, 0 );
		}

		public void setFocused( boolean focused ){
			// ignore
		}

		public void setIcon( Icon icon ){
			// ignore
		}

		public void setOrientation( TabPlacement orientation ){
			// ignore
		}

		public void setPaintIconWhenInactive( boolean paint ){
			// ignore
		}

		public void setSelected( boolean selected ){
			// ignore
		}

		public void setText( String text ){
			// ignore
		}

		public void setTooltip( String tooltip ){
			// ignore
		}

		public void unbind(){
			// ignore			
		}

		public void addMouseInputListener( MouseInputListener listener ){
			// ignore	
		}

		public DockElement getElement(){
			return element;
		}

		public Point getPopupLocation( Point click, boolean popupTrigger ){
			return null;
		}

		public boolean isUsedAsTitle(){
			return false;
		}

		public void removeMouseInputListener( MouseInputListener listener ){
			// ignore			
		}
	}
}```

Hi Beni,

Thank you very much for your answer…
As I understood, that each dockable has a TITLE BAR which can contains a title(as text), an icon and a set of actions.
Please let me know if I’m missing something in the concept of title bar

I have a case where I have nested dockable and I need to hide [remove] the TITLE BAR for some dockables.
I want to remove the content of the red rectangle as in the attached image.
Could you please advice how is the best way to make that?

Thank you

Ok, in the hope of avoiding further misunderstandings between us :wink:

A Dockable…
… can be associated with 0 to infinite many „DockTitles“. A DockTitle may (there are a few exceptions) show icon, text and actions. Normally a title is shown at the top of the Dockable and has the same width as the Dockable itself. In the EclipseTheme DockTitles are almost never used.

… is always embedded in exactly one „displayer“. The displayer may paint things like a DockTitle or a border.

… can be associated with 0 to infinite may tabs. A tab may show icon and text. Some tabs do show special actions, like „close“, as well. Only „stack components“ have the ability to paint tabs. If using the EclipseTheme you frequently see tabs (e.g. in the image you posted).

If using the EclipseTheme…
… then most „displayers“ are also „stack components“ and thus paint tabs.

… the area of the „displayer“ in which tabs and actions are painted is called „title bar“ (in some methods the border also counts as being part of the title bar, but you can ignore that).

How a displayer actually looks is decided by the EclipseThemeConnector. The standard way to remove a bar is to write a subclass of EclipseThemeConnector (or better: extend one that already exists like „DefaultEclipseThemeConnector“) and override the method „getTitleBarKind“. Returning „NONE_BORDERED“ will inform the displayer not to paint tabs nor actions, but to paint a border.

Using DockController.getProperties().set(…) and the key EclipseTheme.THEME_CONNECTOR one can globally set the current EclipseThemeConnector.

I’ll put some code when I’m back from work.

Hi Beni,

Is it possible to customize the displayer of each dockable? For example if I want to keep the default behavior for some dockables but customize others?

Thank you

Sorry for not answering yesterday. The code to remove the titlebar is below.

As for your other question: yes, that is possible. A “DockTheme” has a method “getDisplayFactory” which returns a “DisplayerFactory”. This factory has only one method: “create”. “create” already knows for which Dockable the displayer will be used. Replace this factory and you can use any kind of displayer for any Dockable.

The EclipseTheme has a method “setDisplayerFactory” which replaces the factory (already created displayers are not affected from this change).


import java.awt.BorderLayout;

import javax.swing.JFrame;

import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.eclipse.DefaultEclipseThemeConnector;
import bibliothek.extension.gui.dock.theme.eclipse.EclipseThemeConnector;
import bibliothek.gui.DockController;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.StackDockStation;

public class HideTitleExample {

	public HideTitleExample(){
		JFrame frame = new JFrame();
		frame.setSize( 700, 500 );

		DockController controller = new DockController();
		controller.setTheme( new EclipseTheme() );
		
		final DefaultDockable firstDockable = new DefaultDockable( "First Dockable" );
		final DefaultDockable secondDockable = new DefaultDockable( "Second Dockable" );
		
		EclipseThemeConnector connector = new DefaultEclipseThemeConnector(){
			@Override
			public TitleBar getTitleBarKind( Dockable dockable ){
				if( dockable == secondDockable && !(dockable.getDockParent() instanceof StackDockStation )){
					return TitleBar.NONE_BORDERED;
				}
				
				return super.getTitleBarKind( dockable );
			}
		};
		
		controller.getProperties().set( EclipseTheme.THEME_CONNECTOR, connector );
		
		SplitDockStation splitDockStation = new SplitDockStation();
		controller.add( splitDockStation );
		
		splitDockStation.drop( firstDockable );
		splitDockStation.drop( secondDockable );

		frame.add( splitDockStation, BorderLayout.CENTER );
		frame.setVisible( true );
	}

	public static void main( String[] args ){
		new HideTitleExample();
	}
}```

Hi Beni,

Thank you for you reply

Could you please provide me with an example on how to customize the displayer of each dockable?

Another question, Is it possible to customize the border thickness when using NONE_HINTED_BORDERED?

Thank you,
Saba

Here an example for both your questions. If you want to use this in your application you might have to check what the parent of the Dockable is (e.g. if the parent is a StackDockStation another border is required).


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.border.Border;

import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.eclipse.EclipseBorder;
import bibliothek.extension.gui.dock.theme.eclipse.EclipseThemeConnector.TitleBar;
import bibliothek.extension.gui.dock.theme.eclipse.displayer.EclipseDisplayerFactory;
import bibliothek.extension.gui.dock.theme.eclipse.displayer.NoTitleDisplayer;
import bibliothek.gui.DockController;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.station.DockableDisplayer;
import bibliothek.gui.dock.station.split.SplitDockProperty;
import bibliothek.gui.dock.themes.basic.BasicDockableDisplayer;
import bibliothek.gui.dock.title.DockTitle;

public class HideTitleExample {

	public HideTitleExample(){
		JFrame frame = new JFrame();
		frame.setSize( 700, 500 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

		final DockController controller = new DockController();
		
		final DefaultDockable firstDockable = new DefaultDockable( "First Dockable" );
		final DefaultDockable secondDockable = new DefaultDockable( "Second Dockable" );
		final DefaultDockable thirdDockable = new DefaultDockable( "Third Dockable" );
		
		EclipseTheme theme = new EclipseTheme();
		theme.setDisplayerFactory( new EclipseDisplayerFactory( theme ){
			@Override
			public DockableDisplayer create( DockStation station, Dockable dockable, DockTitle title ){
				if( dockable == firstDockable ){
					return new ThickBorderDisplayer( controller, station, dockable );
				}
				if( dockable == secondDockable ){
					return new CustomDisplayer( station, dockable, title );
				}
				return super.create( station, dockable, title );
			}
		});
		controller.setTheme( theme );
		
		SplitDockStation splitDockStation = new SplitDockStation();
		controller.add( splitDockStation );
		
		splitDockStation.drop( firstDockable );
		splitDockStation.drop( secondDockable, SplitDockProperty.SOUTH );
		splitDockStation.drop( thirdDockable, SplitDockProperty.EAST );

		frame.add( splitDockStation, BorderLayout.CENTER );
		frame.setVisible( true );
	}

	public static void main( String[] args ){
		new HideTitleExample();
	}
	
	private static class CustomDisplayer extends BasicDockableDisplayer{
		public CustomDisplayer( DockStation station, Dockable dockable, DockTitle title ){
			super( station, dockable, title );
			setRespectBorderHint( false );
			setDefaultBorderHint( true );
			updateBorder();
		}
		
		@Override
		protected Border getDefaultBorder(){
			Border inner = BorderFactory.createLineBorder( Color.GREEN, 3 );
			return BorderFactory.createTitledBorder( inner, "Custom Displayer" );
		}
	}
	
	private static class ThickBorderDisplayer extends NoTitleDisplayer{
		public ThickBorderDisplayer( DockController controller, DockStation station, Dockable dockable ){
			super( station, dockable, TitleBar.NONE );
			ThickEclipseBorder border = new ThickEclipseBorder( controller );
			setBorder( border );
		}
		
		@Override
		public void updateFullBorder(){
			// ignore
		}
	}
	
	private static class ThickEclipseBorder extends EclipseBorder{
		public ThickEclipseBorder( DockController controller ){
			super( controller, false );
		}

		@Override
		public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ){
			g.translate( 1, 0 );
			super.paintBorder( c, g, 0, 0, width-1, height-1 );
			g.translate( 0, 1 );
			super.paintBorder( c, g, 0, 0, width-1, height-1 );
			g.translate( -1, 0 );
			super.paintBorder( c, g, 0, 0, width-1, height-1 );
			g.translate( 0, -1 );
			super.paintBorder( c, g, 0, 0, width-1, height-1 );
		}
	}
}```

Hello,

Thank you very much, I’m doing great things with it :slight_smile:

Still have a question :), is it possible to change at runtime the displayer.
I want to show the title/ hide the title bar at runtime. For example at time t=0 I want to show the title bar after certain action I want to hide it

Thank you,

A displayer gets a DockableDisplayerListener. The displayer can call the “discard” method of that listener, this will (most times) destroy the displayer. Afterwards the factory is asked to provide a new displayer.

Hi,

Could you please tell me how can I retrieve the displayer of a dockable at runtime?

Thank you

A Dockable has no knowledge about its displayer. All implementations of DockStation have a method “getDisplayers” which returns a list of displayers used by that station. But this method is not described in any interface.

In general displayers should look out for themselves and no-one knows or tells about their existence. E.g. a displayer

Hi Beni,

I’m a little bit confused…

I want to show/hide the title bar of a dockable at runtime. So you suggest to call the discard() of the DockableDisplayerListener. So how can I call it?

Thank you

I’ll write an example tomorrow.

Basically: your custom displayer tells your custom dockable that it is present. If the properties of the custom dockable change it tells your custom displayer. The custom displayer discards itself. This tells the framework to create a new custom displayer reflecting the new properties.

Any news about the example?

Thank you

Sorry, I completely forgot this…

I wrote the example in the train and did not have the old examples, so you’ll have to copy them together… and there is a bug: it does not work on a StackDockStation. But that will change in the next release.


import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JToggleButton;

import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.eclipse.displayer.EclipseDisplayerFactory;
import bibliothek.extension.gui.dock.theme.eclipse.displayer.EclipseDockableDisplayer;
import bibliothek.gui.DockController;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.station.DockableDisplayer;
import bibliothek.gui.dock.station.DockableDisplayerListener;
import bibliothek.gui.dock.station.split.SplitDockProperty;
import bibliothek.gui.dock.themes.basic.BasicDockableDisplayer;
import bibliothek.gui.dock.title.DockTitle;

public class HideTitleExample {

	public HideTitleExample(){
		
		/*
		 * Note: there is a bug in CombinedStackDockComponent preventing this code
		 * from working properly on a StackDockStation.
		 * 
		 * This bug is already repaired but not yet publicly available. This bug will
		 * disappear in the next release.
		 */
		
		JFrame frame = new JFrame();
		frame.setSize( 700, 500 );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

		final DockController controller = new DockController();
		
		final DefaultDockable firstDockable = new CustomDockable( "First Dockable" );
		final DefaultDockable secondDockable = new CustomDockable( "Second Dockable" );
		final DefaultDockable thirdDockable = new DefaultDockable( "Third Dockable" );
		
		EclipseTheme theme = new EclipseTheme();
		theme.setDisplayerFactory( new CustomDisplayerFactory( theme ) );
		
		controller.setTheme( theme );
		
		
		SplitDockStation splitDockStation = new SplitDockStation();
		controller.add( splitDockStation );
		
		splitDockStation.drop( firstDockable );
		splitDockStation.drop( secondDockable, SplitDockProperty.SOUTH );
		splitDockStation.drop( thirdDockable, SplitDockProperty.EAST );

		frame.add( splitDockStation, BorderLayout.CENTER );
		frame.setVisible( true );
	}

	public static void main( String[] args ){
		new HideTitleExample();
	}
	
	private static class CustomDockable extends DefaultDockable{
		private CustomDisplayer displayer;
		private JToggleButton button;
		
		public CustomDockable( String title ){
			super( title );
			button = new JToggleButton( "Switch" );
			button.addActionListener( new ActionListener() {
				public void actionPerformed( ActionEvent e ){
					if( displayer != null ){
						displayer.discard();
					}
				}
			});
			add( button );
		}
		
		public void setDisplayer( CustomDisplayer displayer ){
			this.displayer = displayer;
		}
		
		public boolean isDown(){
			return button.isSelected();
		}
	}
	
	private static class CustomDisplayerFactory extends EclipseDisplayerFactory{
		private EclipseTheme theme;
		
		public CustomDisplayerFactory( EclipseTheme theme ){
			super( theme );
			this.theme = theme;
		}
		
		@Override
		public DockableDisplayer create( DockStation station, Dockable dockable, DockTitle title ){
			if( dockable instanceof CustomDockable ){
				if( ((CustomDockable)dockable).isDown() ){
					return new DisplayerOne( station, dockable, title );
				}
				else{
					return new DisplayerTwo( theme, station, dockable );
				}
			}
			return super.create( station, dockable, title );
		}
	}
	
	private static interface CustomDisplayer extends DockableDisplayer{
		public void discard();
	}
	
	private static class DisplayerOne extends BasicDockableDisplayer implements CustomDisplayer{
		public DisplayerOne( DockStation station, Dockable dockable, DockTitle title ){
			super( station, dockable, title );
			setDockable( dockable );
		}
		
		@Override
		public void setDockable( Dockable dockable ){
			if( dockable instanceof CustomDockable && this != null ){
				((CustomDockable)dockable).setDisplayer( this );
			}
			super.setDockable( dockable );
		}
		
		public void discard(){
			for( DockableDisplayerListener listener : listeners() ){
				listener.discard( this );
			}
		}
	}
	
	private static class DisplayerTwo extends EclipseDockableDisplayer implements CustomDisplayer{
		public DisplayerTwo( EclipseTheme theme, DockStation station, Dockable dockable ){
			super( theme, station, dockable );
			setDockable( dockable );
		}
		
		@Override
		public void setDockable( Dockable dockable ){
			if( dockable instanceof CustomDockable && this != null ){
				((CustomDockable)dockable).setDisplayer( this );
			}
			super.setDockable( dockable );
		}

		public void discard(){
			for( DockableDisplayerListener listener : displayerListeners() ){
				listener.discard( this );
			}
		}
	}
}```