All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bibliothek.gui.dock.themes.BasicTheme Maven / Gradle / Ivy

The newest version!
/*
 * Bibliothek - DockingFrames
 * Library built on Java/Swing, allows the user to "drag and drop"
 * panels containing any Swing-Component the developer likes to add.
 * 
 * Copyright (C) 2007 Benjamin Sigg
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * 
 * Benjamin Sigg
 * [email protected]
 * CH - Switzerland
 */

package bibliothek.gui.dock.themes;

import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;

import bibliothek.gui.DockController;
import bibliothek.gui.DockStation;
import bibliothek.gui.DockTheme;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.StackDockStation;
import bibliothek.gui.dock.dockable.DockableMovingImageFactory;
import bibliothek.gui.dock.event.UIListener;
import bibliothek.gui.dock.focus.DockableSelection;
import bibliothek.gui.dock.station.Combiner;
import bibliothek.gui.dock.station.DisplayerFactory;
import bibliothek.gui.dock.station.DockableDisplayer;
import bibliothek.gui.dock.station.StationPaint;
import bibliothek.gui.dock.station.span.Span;
import bibliothek.gui.dock.station.span.SpanFactory;
import bibliothek.gui.dock.station.stack.StackDockComponent;
import bibliothek.gui.dock.station.stack.StackDockComponentFactory;
import bibliothek.gui.dock.station.stack.StackDockComponentParent;
import bibliothek.gui.dock.station.stack.tab.layouting.TabPlacement;
import bibliothek.gui.dock.themes.basic.BasicColorScheme;
import bibliothek.gui.dock.themes.basic.BasicCombiner;
import bibliothek.gui.dock.themes.basic.BasicDisplayerFactory;
import bibliothek.gui.dock.themes.basic.BasicDockTitleFactory;
import bibliothek.gui.dock.themes.basic.BasicDockableSelection;
import bibliothek.gui.dock.themes.basic.BasicMovingImageFactory;
import bibliothek.gui.dock.themes.basic.BasicSpanFactory;
import bibliothek.gui.dock.themes.basic.BasicStackDockComponent;
import bibliothek.gui.dock.themes.basic.BasicStationPaint;
import bibliothek.gui.dock.themes.color.ExtendingColorScheme;
import bibliothek.gui.dock.title.DockTitle;
import bibliothek.gui.dock.title.DockTitleFactory;
import bibliothek.gui.dock.title.DockTitleManager;
import bibliothek.gui.dock.util.DockProperties;
import bibliothek.gui.dock.util.NullPriorityValue;
import bibliothek.gui.dock.util.Priority;
import bibliothek.gui.dock.util.PropertyKey;
import bibliothek.gui.dock.util.PropertyValue;
import bibliothek.gui.dock.util.color.ColorManager;
import bibliothek.gui.dock.util.property.DynamicPropertyFactory;

/**
 * A {@link DockTheme theme} that does not install anything and uses the
 * default-implementations off all factories. It is possible to replace 
 * any of the factories.
 * @author Benjamin Sigg
 */
@ThemeProperties(
        nameBundle="theme.basic", 
        descriptionBundle="theme.basic.description",
        authors={"Benjamin Sigg"},
        webpages={})
public class BasicTheme implements DockTheme{
    /** combines several Dockables */
    private NullPriorityValue combiner = new NullPriorityValue();

    /** paints on stations */
    private NullPriorityValue paint = new NullPriorityValue();

    /** creates panels for Dockables */
    private NullPriorityValue displayerFactory = new NullPriorityValue();

    /** creates titles Dockables */
    private NullPriorityValue titleFactory = new NullPriorityValue();

    /** selects the image which should be displayed when moving a dockable*/
    private NullPriorityValue movingImage = new NullPriorityValue();

    /** the factory used to create components for {@link StackDockStation} */
    private NullPriorityValue stackDockComponentFactory = new NullPriorityValue();
    
    /** the side at which tabs are normally shown */
    private NullPriorityValue tabPlacement = new NullPriorityValue();

    /** how spans are created */
    private NullPriorityValue spanFactory = new NullPriorityValue();
    
    /** extensions used by this theme */
    private DockThemeExtension[] extensions;
    
    /** the key to set the {@link ColorScheme} of this theme */
    public static final PropertyKey BASIC_COLOR_SCHEME = 
        new PropertyKey( "dock.ui.BasicTheme.ColorScheme",
        		new DynamicPropertyFactory(){
        			public ColorScheme getDefault( PropertyKey key, DockProperties properties ){
        				return new BasicColorScheme();
        			}
        		}, true );

    /** the color scheme used in this theme */
    private PropertyValue colorScheme = new PropertyValue( BASIC_COLOR_SCHEME ){
        @Override
        protected void valueChanged( ColorScheme oldValue, ColorScheme newValue ) {
            updateColors();
        }
    };

    /** how to select a new focused dockable */
    private NullPriorityValue< DockableSelection> selection = new NullPriorityValue();

    /** the controller which is installed */
    private DockController controller;
    
    /** a listener waiting for changed {@link LookAndFeel}s */
    private UIListener uiListener = new UIListener(){
        public void updateUI( DockController controller ){
            BasicTheme.this.updateUI();
        }
        public void themeChanged(DockController controller, DockTheme oldTheme, DockTheme newTheme) {
            // ignore
        }
        public void themeWillChange(DockController controller, DockTheme oldTheme, DockTheme newTheme) {
            // ignore
        }
    };

    /**
     * Creates a new BasicTheme.
     */
    public BasicTheme() {
        setCombiner( new BasicCombiner(), Priority.DEFAULT );
        setPaint( new BasicStationPaint(), Priority.DEFAULT );
        setDisplayerFactory( new BasicDisplayerFactory(), Priority.DEFAULT );
        setTitleFactory( new BasicDockTitleFactory(), Priority.DEFAULT );
        setMovingImageFactory( new BasicMovingImageFactory(), Priority.DEFAULT );
        setStackDockComponentFactory( new StackDockComponentFactory(){
            public StackDockComponent create( StackDockComponentParent station ) {
                return new BasicStackDockComponent( station );
            }
        }, Priority.DEFAULT );
        setDockableSelection( new BasicDockableSelection(), Priority.DEFAULT );
        setTabPlacement( TabPlacement.BOTTOM_OF_DOCKABLE, Priority.DEFAULT );
        setSpanFactory( new BasicSpanFactory( 250, 250 ), Priority.DEFAULT );
    }

    public void install( DockController controller, DockThemeExtension[] extensions ){
    	this.extensions = extensions;
    	for( DockThemeExtension extension : extensions ){
    		extension.install( controller, this );
    	}
    	install( controller );
    	for( DockThemeExtension extension : extensions ){
    		extension.installed( controller, this );
    	}
    }
    
    /**
     * Installs the basic items of this theme, ignoring any {@link DockThemeExtension}.
     * @param controller the new owner of this theme
     */
    protected void install( DockController controller ){
        if( this.controller != null )
            throw new IllegalStateException( "Theme is already in use" );

        this.controller = controller;

        controller.getThemeManager().addUIListener( uiListener );
        updateUI();

        controller.getProperties().set( StackDockStation.COMPONENT_FACTORY, stackDockComponentFactory.get(), Priority.THEME );
        controller.getProperties().set( StackDockStation.TAB_PLACEMENT, tabPlacement.get(), Priority.THEME );
        controller.getProperties().set( DockTheme.SPAN_FACTORY, spanFactory.get(), Priority.THEME );
        
        colorScheme.setProperties( controller );

        updateColors();
    }

    public void uninstall( DockController controller ){
        if( this.controller != controller )
            throw new IllegalArgumentException( "Trying to uninstall a controller which is not installed" );

        controller.getProperties().unset( StackDockStation.COMPONENT_FACTORY, Priority.THEME );
        controller.getProperties().unset( StackDockStation.TAB_PLACEMENT, Priority.THEME );
        controller.getProperties().unset( DockTheme.SPAN_FACTORY, Priority.THEME );
        controller.getColors().clear( Priority.THEME );
        controller.getThemeManager().removeUIListener( uiListener );

        colorScheme.setProperties( (DockProperties)null );
        
        for( DockThemeExtension extension : extensions ){
    		extension.uninstall( controller, this );
    	}
        
        this.controller = null;
    }

    /**
     * Called when the {@link LookAndFeel} changed, should update colors, fonts, ...
     */
    public void updateUI(){
    	if( selection != null ){
            SwingUtilities.updateComponentTreeUI( selection.get().getComponent() );
        }
    }

    /**
     * Called when the the colors of the {@link ColorManager} have to be updated. This method reads
     * the current {@link ColorScheme} and installs it using
     * {@link ColorManager#setScheme(Priority, bibliothek.gui.dock.util.UIScheme)} with a priority
     * of {@link Priority#CLIENT}.
* This method changed its behavior in version 1.1.0p3, subclasses no longer need to override it. All colors * can now be created lazily and automatically in exactly the moment when they are needed. */ protected void updateColors(){ if( controller != null ){ ColorScheme scheme = colorScheme.getValue(); if( scheme != null ){ scheme = new ExtendingColorScheme( scheme, controller ); } controller.getColors().setScheme( Priority.THEME, scheme ); } } /** * Gets the currently installed controller * @return the controller */ public DockController getController(){ return controller; } /** * Sets the key that will be used to read the {@link ColorScheme} of this * theme from the {@link DockProperties}. * @param key the new key, not null * @see #setColorScheme(ColorScheme) */ protected void setColorSchemeKey( PropertyKey key ){ if( key == null ) throw new IllegalArgumentException( "key must not be null" ); colorScheme.setKey( key ); } /** * Sets the currently used set of colors. The colors of all {@link DockController}s * will change immediately. * @param colorScheme the new scheme, null will * activate the default color scheme. */ public void setColorScheme( ColorScheme colorScheme ) { this.colorScheme.setValue( colorScheme ); } /** * Gets the currently used color scheme * @return the scheme */ public ColorScheme getColorScheme() { return colorScheme.getValue(); } /** * Sets the factory which will be used to create components for * {@link StackDockStation}. Note that this property has to be set * before the theme is installed. Otherwise it will take no effect. * @param stackDockComponentFactory the factory or null */ public void setStackDockComponentFactory( StackDockComponentFactory stackDockComponentFactory ) { setStackDockComponentFactory( stackDockComponentFactory, Priority.CLIENT ); } /** * Sets the factory which will be used to create components for * {@link StackDockStation}. Note that this property has to be set * before the theme is installed. Otherwise it will take no effect. * @param stackDockComponentFactory the factory or null * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setStackDockComponentFactory( StackDockComponentFactory stackDockComponentFactory, Priority priority ) { this.stackDockComponentFactory.set( priority, stackDockComponentFactory ); } /** * Sets the factory which will be used to create new {@link Span}s. Note that this property * has to be set before the theme is installed, otherwise it will take not effect. * @param factory the new factory, can be null */ public void setSpanFactory( SpanFactory factory ){ setSpanFactory( factory, Priority.CLIENT ); } /** * Sets the factory which will be used to create new {@link Span}s. Note that this property * has to be set before the theme is installed. Otherwise it will take no effect. * @param factory the factory or null * @param priority the imprtance of the new setting (whether it should override existing settings or not). */ public void setSpanFactory( SpanFactory factory, Priority priority ){ this.spanFactory.set( priority, factory ); } /** * Sets the movingImage-property. The movignImage is needed to show an * image when the user grabs a {@link Dockable} * @param movingImage the new factory */ public void setMovingImageFactory( DockableMovingImageFactory movingImage ) { setMovingImageFactory( movingImage, Priority.CLIENT ); } /** * Sets the movingImage-property. The movignImage is needed to show an * image when the user grabs a {@link Dockable} * @param movingImage the new factory * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setMovingImageFactory( DockableMovingImageFactory movingImage, Priority priority ) { this.movingImage.set( priority, movingImage ); } /** * Sets the {@link Combiner} of this theme. The combiner is used to * merge two Dockables. * @param combiner the combiner */ public void setCombiner( Combiner combiner ) { setCombiner( combiner, Priority.CLIENT ); } /** * Sets the {@link Combiner} of this theme. The combiner is used to * merge two Dockables. * @param combiner the combiner * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setCombiner( Combiner combiner, Priority priority ) { this.combiner.set( priority, combiner ); } /** * Sets the {@link StationPaint} of this theme. The paint is used to * draw markings on stations. * @param paint the paint */ public void setPaint( StationPaint paint ) { setPaint( paint, Priority.CLIENT ); } /** * Sets the {@link StationPaint} of this theme. The paint is used to * draw markings on stations. * @param paint the paint * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setPaint( StationPaint paint, Priority priority ) { this.paint.set( priority, paint ); } /** * Sets the {@link DisplayerFactory} of this theme. The factory is needed * to create {@link DockableDisplayer}. * @param factory the factory */ public void setDisplayerFactory( DisplayerFactory factory ) { setDisplayerFactory( factory, Priority.CLIENT ); } /** * Sets the {@link DisplayerFactory} of this theme. The factory is needed * to create {@link DockableDisplayer}. * @param factory the factory * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setDisplayerFactory( DisplayerFactory factory, Priority priority ) { displayerFactory.set( priority, factory ); } /** * Sets the {@link DockTitleFactory} of this theme. The factory is * used to create {@link DockTitle DockTitles} for some Dockables. * @param titleFactory the factory */ public void setTitleFactory( DockTitleFactory titleFactory ) { setTitleFactory( titleFactory, Priority.CLIENT ); } /** * Sets the {@link DockTitleFactory} of this station. The factory is * used to create {@link DockTitle DockTitles} for some Dockables. * @param titleFactory the factory * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setTitleFactory( DockTitleFactory titleFactory, Priority priority ) { this.titleFactory.set( priority, titleFactory ); if( controller != null ){ controller.getDockTitleManager().registerTheme( DockTitleManager.THEME_FACTORY_ID, this.titleFactory.get() ); } } /** * Sets how the user can select the focused {@link Dockable}. * @param selection the new selector */ public void setDockableSelection( DockableSelection selection ){ setDockableSelection( selection, Priority.CLIENT ); } /** * Sets how the user can select the focused {@link Dockable}. * @param selection the new selector * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setDockableSelection( DockableSelection selection, Priority priority ){ this.selection.set( priority, selection ); } /** * Sets the side at which tabs are to be displayed. This method has to * be called before a {@link DockController} is installed, otherwise the * settings has no effect. * @param tabPlacement the side at which to show tabs, may be null to * use the default value */ public void setTabPlacement( TabPlacement tabPlacement ){ setTabPlacement( tabPlacement, Priority.CLIENT ); } /** * Sets the side at which tabs are to be displayed. This method has to * be called before a {@link DockController} is installed, otherwise the * settings has no effect. * @param tabPlacement the side at which to show tabs, may be null to * use the default value * @param priority the importance of the new setting (whether it should override existing settings or not). */ public void setTabPlacement( TabPlacement tabPlacement, Priority priority ){ this.tabPlacement.set( priority, tabPlacement ); } /** * Gets the side at which tabs are displayed. * @return the side with the tabs, may be null */ public TabPlacement getTabPlacement(){ return tabPlacement.get(); } public DockableMovingImageFactory getMovingImageFactory( DockController controller ) { return movingImage.get(); } public Combiner getCombiner( DockStation station ) { return combiner.get(); } public StationPaint getPaint( DockStation station ) { return paint.get(); } public DisplayerFactory getDisplayFactory( DockStation station ) { return displayerFactory.get(); } public DockTitleFactory getTitleFactory( DockController controller ) { return titleFactory.get(); } public DockableSelection getDockableSelection( DockController controller ) { return selection.get(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy