Custom dockable title


#1

Hi,

I was wondering if you could help me with the following :

I have a couple of dockables for which I want to have a custom painter in the dockable’s title bar ( use some fancy gradients ).
However I am doing something wrong and some functionality is missing ( please read my comments in the following barebones working example )

Many thanks in advance for your time,

Kind regards,
George

import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.CLocation;
import bibliothek.gui.dock.common.DefaultSingleCDockable;
import bibliothek.gui.dock.title.AbstractDockTitle;
import bibliothek.gui.dock.title.DockTitleFactory;
import bibliothek.gui.dock.title.DockTitleManager;
import bibliothek.gui.dock.title.DockTitleRequest;
import bibliothek.gui.dock.title.DockTitleVersion;
import bibliothek.gui.dock.util.Priority;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class TEMP_FRAME extends JFrame
{
    public static void main(String[] args)
    {
         TEMP_FRAME frame=new TEMP_FRAME();
         frame.setLayout(new BorderLayout());
         
         CControl control=new CControl(frame);
         frame.add(control.getContentArea(),BorderLayout.CENTER);
         
         DefaultSingleCDockable dock1=new DefaultSingleCDockable("Dock1");
         dock1.setTitleText("Dock 1");
         dock1.setLocation(CLocation.base());
         
         DefaultSingleCDockable dock2=new DefaultSingleCDockable("Dock2");
         dock2.setTitleText("Dock 2");
         dock2.setLocation(CLocation.base().normalSouth(0.5f));
         
         control.addDockable(dock1);
         dock1.setVisible(true);
         
         control.addDockable(dock2);
         dock2.setVisible(true);

         /* If the following block of code - line XXX in particular - is commented out then :
         *  Clicking inside a dockable or inside a dockable's title bar , selects/focuses the dockable ( GOOD )
         * 
         *  If the following block of code - line XXX in particular - is not commented out then :
         *  Clicking inside a dockable or inside a dockable's title bar , has no effect ( NOT GOOD )
         *  But if you first click inside a dockable or inside the dockable's title bar and then :
         *    a) left-drag the horizontal "divider" line to resize the dockables 
         *    or
         *    b) resize the whole frame
         *  then it works.
         *  It seems like a repaint event is needed but does n't happen
         */
         {
            DockTitleManager titles=control.getController().getDockTitleManager();
            DockTitleVersion version=titles.getVersion(SplitDockStation.TITLE_ID,null);
            DockTitleFactory factory=new DockableTitleFactory();
            version.setFactory(factory,Priority.CLIENT);  // LINE XXX
         }
         
         frame.setSize(new Dimension(500,500));
         frame.setVisible(true);
    }
    
    
    static class DockableTitleFactory implements DockTitleFactory
    {
        public void install( DockTitleRequest request ){}
        public void request( DockTitleRequest request )
        {
            request.answer(new CustomTitle(request.getTarget(),request.getVersion()));
        }
        public void uninstall( DockTitleRequest request ){}

        class CustomTitle extends AbstractDockTitle
        {
            public CustomTitle( Dockable dockable, DockTitleVersion origin )
            {
                super(dockable,origin);
            }

            @SuppressWarnings("unchecked")
            [MENTION=2741]Override[/MENTION]
            protected void paintBackground( Graphics g, JComponent component )
            {
                final boolean isCurrentlySelectedDockable=getDockable().getController().getFocusedDockable()==getDockable();
                final Color color=isCurrentlySelectedDockable?Color.blue:Color.orange;
                g.setColor(color);
                g.fillRect(0,0,getWidth(),getHeight());
            }
        }
    }
}```

#2

Instead of using [inline]getDockable().getController().getFocusedDockable()==getDockable();[/inline] you should better call [inline]this.isActive()[/inline]. You can override [inline]setActive[/inline] and fire a [inline]repaint[/inline] event there. [inline]setActive[/inline] is called everytime when the focused [inline]Dockable[/inline] changes. You may want to have a look at [inline]BasicDockTitle[/inline] and use it as an example of how a title can be implemented.


#3

Yes! Thanks Beni!
Using isActive and overriding [inline]setActive(boolean isActive)[/inline] as in :

public void setActive(boolean isActive){
   super.setActive(isActive);
   repaint();
}```

did the trick!!

Many thanks!
George