/* * 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) 2008 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 * benjamin_sigg@gmx.ch * CH - Switzerland */ package bibliothek.extension.gui.dock.preference; import bibliothek.gui.dock.util.TextManager; import bibliothek.util.Path; /** * A generic {@link Preference} that can hold any value. This preference does not implement * the {@link #read()} or {@link #write()} method. If a {@link #setDefaultValue(Object) default-value} * is set, then this preference activates the operation {@link PreferenceOperation#DEFAULT}, otherwise * it shows no operations.<br> * This preference is set to be an {@link #isNatural() artificial} preference, subclasses may call * {@link #setNatural(boolean)} to change the behavior. * @author Benjamin Sigg * * @param <V> the kind of value this preference holds */ public abstract class DefaultPreference<V> extends AbstractPreference<V>{ private V value; private Object valueInfo; private Path type; private String label; private PreferenceText labelText; private String description; private PreferenceText descriptionText; private V defaultValue; private Path path; private boolean natural = false; private PreferenceModel model; /** * Creates a new preference. * @param type the type of value this preference uses * @param path a unique path for this preference, all paths starting with * "dock" are reserved for this framework */ public DefaultPreference( Path type, Path path ){ if( type == null ) throw new IllegalArgumentException( "type must not be null" ); if( path == null ) throw new IllegalArgumentException( "path must not be null" ); if( path.getSegmentCount() == 0 ) throw new IllegalArgumentException( "the root path is not a valid path for a preference" ); this.type = type; this.path = path; } /** * Creates a new preference. * @param label a short human readable label for this preference * @param type the type of value this preference uses * @param path a unique path for this preference, all paths starting with * "dock" are reserved for this framework */ public DefaultPreference( String label, Path type, Path path ){ this( type, path ); setLabel( label ); } @Override public void addPreferenceListener( PreferenceListener<V> listener ){ if( !hasListeners() ){ if( model != null ){ if( labelText != null ){ labelText.setController( model.getController() ); } if( descriptionText != null ){ descriptionText.setController( model.getController() ); } } } super.addPreferenceListener( listener ); } @Override public void removePreferenceListener( PreferenceListener<V> listener ){ super.removePreferenceListener( listener ); if( !hasListeners() ){ if( labelText != null ){ labelText.setController( null ); } if( descriptionText != null ){ descriptionText.setController( null ); } } } public void setModel( PreferenceModel model ){ this.model = model; if( hasListeners() ){ if( labelText != null ){ labelText.setController( model == null ? null : model.getController() ); } if( descriptionText != null ){ descriptionText.setController( model == null ? null : model.getController() ); } } } public String getLabel() { if( labelText == null ){ return label; } if( !hasListeners() && model != null ){ labelText.update( model.getController().getTexts() ); } return labelText.value(); } /** * Sets a short human readable label for this preference. Note that * changes of the label are not propagated to any listener. * @param label the new label */ public void setLabel( String label ) { this.label = label; if( labelText != null ){ labelText.setValue( label ); } else{ fireChanged(); } } /** * Sets a unique identifier for the label text, the unique identifier will be used to read * a text from the current {@link TextManager}. * @param labelId the unique identifier, can be <code>null</code> */ public void setLabelId( String labelId ){ if( labelId == null ){ if( labelText != null ){ labelText.setController( null ); labelText = null; } } else{ if( labelText == null ){ labelText = new PreferenceText( labelId, this ){ protected void changed( String oldValue, String newValue ){ fireChanged(); } }; if( hasListeners() && model != null ){ labelText.setController( model.getController() ); } } else{ labelText.setId( labelId ); } } } public String getDescription() { if( descriptionText == null ){ return description; } if( !hasListeners() && model != null ){ descriptionText.update( model.getController().getTexts() ); } return descriptionText.value(); } /** * Sets a description of this preference. * @param description a human readable string, can be <code>null</code> and * can be formated in HTML */ public void setDescription( String description ) { this.description = description; if( descriptionText != null ){ descriptionText.setValue( description ); } else{ fireChanged(); } } /** * Sets a unique identifier for the description text, the unique identifier will be used to read * a text from the current {@link TextManager}. * @param descriptionId the unique identifier, can be <code>null</code> */ public void setDescriptionId( String descriptionId ){ if( descriptionId == null ){ if( descriptionText != null ){ descriptionText.setController( null ); descriptionText = null; } } else{ if( descriptionText == null ){ descriptionText = new PreferenceText( descriptionId, this ){ protected void changed( String oldValue, String newValue ){ fireChanged(); } }; if( hasListeners() && model != null ){ descriptionText.setController( model.getController() ); } } else{ descriptionText.setId( descriptionId ); } } } public Path getTypePath() { return type; } /** * Sets information about this preferences value. For example for * an integer that could be the upper and the lower bounds. The exact * meaning and type of this object depends on {@link #getTypePath()}. * @param valueInfo the new information or <code>null</code> */ public void setValueInfo(Object valueInfo) { this.valueInfo = valueInfo; } public Object getValueInfo() { return valueInfo; } public V getValue() { return value; } public void setValue( V value ) { if( this.value != value ){ this.value = value; fireChanged(); } } /** * Sets the default value of this preference * @param defaultValue the new default value */ public void setDefaultValue( V defaultValue ) { this.defaultValue = defaultValue; fireChanged(); } /** * Gets the default value of this preference * @return the default value, might be <code>null</code> */ public V getDefaultValue() { return defaultValue; } public Path getPath() { return path; } /** * Sets whether this preference is natural or artificial. * @param natural <code>true</code> if natural, <code>false</code> * if artificial * @see #isNatural() * @see PreferenceModel#isNatural(int) */ public void setNatural( boolean natural ) { this.natural = natural; } public boolean isNatural() { return natural; } @Override public PreferenceOperation[] getOperations() { if( defaultValue == null ) return null; else return new PreferenceOperation[]{ PreferenceOperation.DEFAULT }; } @Override public boolean isEnabled( PreferenceOperation operation ) { if( operation == PreferenceOperation.DEFAULT ){ if( defaultValue == null ) return false; return !defaultValue.equals( getValue() ); } return false; } @Override public void doOperation( PreferenceOperation operation ) { if( operation == PreferenceOperation.DEFAULT ){ if( defaultValue != null ){ setValue( defaultValue ); } } else{ super.doOperation( operation ); } } }