How to change background color of the right part of tabs

Hello again,

now I am looking for a way to modify the color of the right area of a tabbed pane. Obviously there are two different things involved:

Case 1: If „SingleTabShown“ is used (the „abc“ dockable), the area to the right of the tab is filled with the background color of the content area of the control, in my example set to „red“.

Case 2: If multiple tabs are shown (the right part), the area right of the tabs is filled with another color.

My goal is to set the background color of both areas to the same color.

Thanks for your attention,
Thilo

  public static void main(String[] args) {
        JFrame frame = new JFrame("title");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        CControl control = new CControl(frame);
        CContentArea contentarea = control.getContentArea();
        frame.add(contentarea);

        control.setTheme(ThemeMap.KEY_FLAT_THEME);
        contentarea.setBackground(Color.red);

        // decide which buttons to show directly on the tabs
        control.putProperty(FlatTheme.ACTION_DISTRIBUTOR,
                new DefaultDockActionDistributor() {
            @Override
            protected DockActionSource createInfoSource(DockActionSource source) {
                return new FilteredDockActionSource(source) {
                    @Override
                    protected boolean include(DockAction action) {
                        return true;
                    }
                };
            }

            @Override
            protected DockActionSource createTabSource(DockActionSource source) {
                return new FilteredDockActionSource(source) {
                    @Override
                    protected boolean include(DockAction action) {
                        return false;
                    }
                };
            }
        });

        // set custom colors
        ColorManager cm = control.getController().getColors();
        cm.put(Priority.CLIENT, "stack.tab.background.top", Color.cyan);
        cm.put(Priority.CLIENT, "stack.tab.background.top.selected", Color.yellow);
        cm.put(Priority.CLIENT, "stack.tab.background.top.focused", Color.yellow);

        // use single-tab-shown and title-shown to switch behavior
        DefaultSingleCDockable d1 = new DefaultSingleCDockable("d1", "abc");
        d1.setSingleTabShown(true);
        d1.setTitleShown(false);
        d1.getContentPane().setBackground(Color.ORANGE);

        DefaultSingleCDockable d2 = new DefaultSingleCDockable("d2", "def");
        d2.setSingleTabShown(true);
        d2.setTitleShown(false);
        d2.getContentPane().setBackground(Color.ORANGE);

        DefaultSingleCDockable d3 = new DefaultSingleCDockable("d3", "ghj");
        d3.setSingleTabShown(true);
        d3.setTitleShown(false);
        d3.getContentPane().setBackground(Color.ORANGE);

        // move tab to the top
        control.putProperty(StackDockStation.TAB_PLACEMENT, TabPlacement.TOP_OF_DOCKABLE);

        CGrid grid = new CGrid(control);
        grid.add(0, 0, 1, 1, d1);
        grid.add(1, 0, 1, 1, d2, d3);
        contentarea.deploy(grid);

        frame.setBounds(500, 250, 700, 300);
        frame.setVisible(true);
    }

side note: this forum has a litte spam problem, some postings have to be unlocked by moderators,
postings in this area in englisch (in german forum with english spam) by unregistered users are often affected,

if you (or other unregistered users here) would register, it might be less waiting time for you, and a little less work for moderators :wink:
beside other advantages like recognition/ search

in this case it was only minutes till i unlocked this new thread, which is easy to spot,
other postings, especially in running forum-threads, sometimes take hours to unlock

The “ThemeManager” offers some methods to modify the way backgrounds are painted, the easiest way is to implement a new “BackgroundPaint”.


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

import javax.swing.JFrame;

import bibliothek.extension.gui.dock.theme.FlatTheme;
import bibliothek.gui.dock.StackDockStation;
import bibliothek.gui.dock.action.DockAction;
import bibliothek.gui.dock.action.DockActionSource;
import bibliothek.gui.dock.action.FilteredDockActionSource;
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;
import bibliothek.gui.dock.facile.action.CloseAction;
import bibliothek.gui.dock.station.stack.action.DefaultDockActionDistributor;
import bibliothek.gui.dock.station.stack.tab.layouting.TabPlacement;
import bibliothek.gui.dock.themes.ThemeManager;
import bibliothek.gui.dock.util.BackgroundComponent;
import bibliothek.gui.dock.util.BackgroundPaint;
import bibliothek.gui.dock.util.PaintableComponent;
import bibliothek.gui.dock.util.Transparency;

public class TabExample {
	public static void main( String[] args ) {
		JFrame frame = new JFrame( "title" );
		frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

		CControl control = new CControl( frame );
		frame.add( control.getContentArea() );

		control.setTheme( ThemeMap.KEY_FLAT_THEME );

		ThemeManager themeManager = control.getController().getThemeManager();
		themeManager.setBackgroundPaint( "dock.background.tabPane", background(Color.GREEN) );
		
		// use single-tab-shown and title-shown to switch behavior
		DefaultSingleCDockable d1 = new DefaultSingleCDockable( "d1", "abc" );
		d1.setSingleTabShown( true );
		d1.setTitleShown( false );
		d1.setCloseable( true );

		DefaultSingleCDockable d2 = new DefaultSingleCDockable( "d2", "def" );
		d2.setSingleTabShown( true );
		d2.setTitleShown( false );
		d2.setCloseable( true );

		DefaultSingleCDockable d3 = new DefaultSingleCDockable( "d3", "ghj" );
		d3.setSingleTabShown( true );
		d3.setTitleShown( false );
		d3.setCloseable( true );

		// move tab to the top
		control.putProperty( StackDockStation.TAB_PLACEMENT, TabPlacement.TOP_OF_DOCKABLE );

		// decide which buttons to show directly on the tabs
		control.putProperty( FlatTheme.ACTION_DISTRIBUTOR,
				new DefaultDockActionDistributor() {
					@Override
					protected DockActionSource createInfoSource( DockActionSource source ) {
						return new FilteredDockActionSource( source ) {
							@Override
							protected boolean include( DockAction action ) {
								return !isCloseAction( action );
							}
						};
					}

					@Override
					protected DockActionSource createTabSource( DockActionSource source ) {
						return new FilteredDockActionSource( source ) {
							@Override
							protected boolean include( DockAction action ) {
								return isCloseAction( action );
							}
						};
					}

					private boolean isCloseAction( DockAction action ) {
						// that is a bit of a hack, but it works
						return action instanceof CloseAction;
					}
				} );

		CGrid grid = new CGrid( control );
		grid.add( 0, 0, 1, 1, d1 );
		grid.add( 1, 0, 1, 1, d2, d3 );
		control.getContentArea().deploy( grid );

		frame.setBounds( 50, 50, 800, 800 );
		frame.setVisible( true );
	}
	
	private static BackgroundPaint background( Color color ){
		return new BackgroundPaint() {
			@Override
			public void uninstall( BackgroundComponent component ) {
				// ignore
			}
			
			@Override
			public void paint( BackgroundComponent background, PaintableComponent paintable, Graphics g ) {
				// do not paint default background
				paintable.paintBackground( null );
				
				if(background.getTransparency() != Transparency.TRANSPARENT){
					g.setColor( color );
					Component c = paintable.getComponent();
					
					g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
				}
			}
			
			@Override
			public void install( BackgroundComponent component ) {
				// ignore
			}
		};
	}
}

Btw. Instead of accessing the ColorManager you can also use the ColorMap to define different colors for each CDockable:

ColorMap map = dockable.getColorMap();
map.put( ColorMap.COLOR_KEY_TAB_BACKGROUND, Color.RED );

Hi Beni,

thanks again for the quick answer. Again it hits the bull’s eye.

It includes a very interesting detail to understand how components are stacked and inheriting properties from their ancestors:

           // do not paint default background
            paintable.paintBackground( null );

Btw. Instead of accessing the ColorManager you can also use the ColorMap to define different colors for each CDockable:
Yes, I know, but my main goal is to achieve an overall consistent look, so all my docks should use the same colors/fonts/borders etc. independent of their state or function.

Have a great day.