Tooltips for DockingTitle

Hi Beni!
I am using an older version of DockingFrames (1.0.2 I believe) and am trying to set tooltips for the titles of my Dockables. So far I am not really succeeding. Do I have to get hold of a DockTitle? it seems a little bit like this is a internal method that is used by the station and should not be used by the client.

Many thanks,
Christopher

P.S.: A screenshot of the app in which I use DockingFrames can be found at www.mi.fu-berlin.de/w/SE.GmanDA

Hello

DF does not have any support for tooltips (another missing feature that lands on the todo-list, will be in version 1.0.6). So I guess you have to play around with the internal methods.

I suggest grabing all DockTitles and TabComponents when they are „bound“ (=put into use) and then set the tooltip. That could look like this (that was tested with 1.0.2, don’t know how/if other versions will work):

(btw: nice screenshot :stuck_out_tongue: )


import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.Border;

import bibliothek.extension.gui.dock.theme.EclipseTheme;
import bibliothek.extension.gui.dock.theme.eclipse.rex.RexTabbedComponent;
import bibliothek.extension.gui.dock.theme.eclipse.rex.tab.TabComponent;
import bibliothek.extension.gui.dock.theme.eclipse.rex.tab.TabPainter;
import bibliothek.gui.DockController;
import bibliothek.gui.DockFrontend;
import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.DefaultDockable;
import bibliothek.gui.dock.SplitDockStation;
import bibliothek.gui.dock.event.DockTitleBindingListener;
import bibliothek.gui.dock.station.split.SplitDockGrid;
import bibliothek.gui.dock.title.DockTitle;

public class Main {
    public static void main( String[] args ){
        JFrame frame = new JFrame( "Demo" );
        DockFrontend frontend = new DockFrontend( frame );
        DockController controller = frontend.getController();
        
        controller.setTheme( new EclipseTheme() );
        
        /*
         * Grab all DockTitles as soon as they are used, and set the
         * tooltip.
         * 
         * You might use "Dockable.listBoundTitles()" to change the tooltips
         * later.
         */
        controller.addDockTitleBindingListener( new DockTitleBindingListener(){
            public void titleBound( DockController controller, DockTitle title, Dockable dockable ) {                
                String text = dockable.getTitleText();
                Component component = title.getComponent();
                setTooltip( component, text );
            }

            public void titleUnbound( DockController controller, DockTitle title, Dockable dockable ) {
            }
        });
        
        /*
         * For the EclipseTheme: create a new TabPainter that sets the tooltip.
         */
        final TabPainter original = controller.getProperties().get( EclipseTheme.TAB_PAINTER );
        controller.getProperties().set( EclipseTheme.TAB_PAINTER, new TabPainter(){
            public TabComponent createTabComponent( DockController controller,
                    RexTabbedComponent component, final Dockable dockable, int index ) {
                
                final TabComponent comp = original.createTabComponent( controller, component, dockable, index );
                TabComponent result = new TabComponent(){
                    public void bind() {
                        comp.bind();
                        /* 
                         * here we could add some listener to dockable in order
                         * to be informed when the tooltip changes
                         * 
                         * "((MyDockable)dockable).addMyListener( ... );"
                         */
                        setTooltip( getComponent(), dockable.getTitleText() );
                    }
                    
                    public void unbind() {
                        /*
                         * And here we would remove the listener that was added 
                         * in "bind".
                         */
                        comp.unbind();
                    }
                    
                    public void addMouseListener( MouseListener listener ) {
                        comp.addMouseListener( listener );
                    }

                    public void addMouseMotionListener( MouseMotionListener listener ) {
                        comp.addMouseMotionListener( listener );
                    }

                    public Component getComponent() {
                        return comp.getComponent();
                    }

                    public Border getContentBorder() {
                        return comp.getContentBorder();
                    }

                    public int getOverlap() {
                        return comp.getOverlap();
                    }

                    public void removeMouseListener( MouseListener listener ) {
                        comp.removeMouseListener( listener );
                    }

                    public void removeMouseMotionListener( MouseMotionListener listener ) {
                        comp.removeMouseMotionListener( listener );
                    }

                    public void setFocused( boolean focused ) {
                        comp.setFocused( focused );
                    }

                    public void setIndex( int index ) {
                        comp.setIndex( index );
                    }

                    public void setPaintIconWhenInactive( boolean paint ) {
                        comp.setPaintIconWhenInactive( paint );
                    }

                    public void setSelected( boolean selected ) {
                        comp.setSelected( selected );
                    }

                    public void update() {
                        comp.update();
                    }
                };
                
                return result;
            }

            public Border getFullBorder( DockController controller,
                    Dockable dockable ) {
                return original.getFullBorder( controller, dockable );
            }

            public Border getFullBorder( DockController controller,
                    DockStation station, RexTabbedComponent component ) {
                return original.getFullBorder( controller, station, component );
            }

            public void paintTabStrip( RexTabbedComponent tabbedComponent,
                    Component tabStrip, Graphics g ) {
                original.paintTabStrip( tabbedComponent, tabStrip, g );
            }
            
        });
        
        SplitDockStation station = new SplitDockStation();

        frame.add( station.getComponent() );
        frontend.addRoot( station, "station" );

        SplitDockGrid grid = new SplitDockGrid();
        grid.addDockable( 0, 0, 1, 1, createDockable( "Red", Color.RED ) );
        grid.addDockable( 0, 1, 1, 1, createDockable( "Green", Color.GREEN ) );
        grid.addDockable( 1, 0, 1, 1, createDockable( "Blue", Color.BLUE ) );
        grid.addDockable( 1, 1, 1, 1, createDockable( "Yellow", Color.YELLOW ) );
        station.dropTree( grid.toTree() );

        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.setBounds( 20, 20, 400, 400 );
        frame.setVisible( true );
    }

    /*
     * Set the tooltip on component and on its children, that should spread
     * the tooltip wide enough such that it can be seen (note: that is a wild
     * guess that might not work in newer versions).
     */
    public static void setTooltip( Component component, String text ){
        if( component instanceof JComponent ){
            JComponent jcomp = (JComponent)component;
            jcomp.setToolTipText( text );
            
            for( int i = 0, n = jcomp.getComponentCount(); i<n; i++ ){
                Component child = jcomp.getComponent( i );
                if( child instanceof JComponent ){
                    ((JComponent)child).setToolTipText( text );
                }
            }
        }
    }
    
    public static Dockable createDockable( String title, Color color ){
        JPanel panel = new JPanel();
        panel.setOpaque( true );
        panel.setBackground( color );
        return new DefaultDockable( panel, title );
    }
}

Works like a charm!

Thanks,
Christopher