bibliothek.gui.dock.util.DockProperties Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of docking-frames-core Show documentation
Show all versions of docking-frames-core Show documentation
${project.name} is base or core library
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.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import bibliothek.gui.DockController;
/**
* A set of properties that are used at different places all over the framework.
* The map uses a {@link Priority} based system, allowing clients to override
* behavior of themes or set default values in case a theme does not set one.
* @author Benjamin Sigg
*/
public class DockProperties {
/** the map of values */
private Map, Entry>> map = new HashMap, Entry>>();
/** the owner of this map */
private DockController controller;
/**
* Creates a new map.
* @param controller the owner of this map
*/
public DockProperties( DockController controller ){
if( controller == null ){
throw new IllegalArgumentException( "controller must not be null" );
}
this.controller = controller;
}
/**
* Gets the owner of this {@link DockProperties}.
* @return the owner, not null
*/
public DockController getController(){
return controller;
}
/**
* Sets a value. This is equivalent to calling set( key, value, Priority.CLIENT )
.
* @param the type of the value
* @param key the key to access the value
* @param value the value, can be null
*/
public void set( PropertyKey key, A value ){
set( key, value, Priority.CLIENT );
}
/**
* Sets a value.
* @param the type of the value
* @param key the key to access the value
* @param value the value, can be null
* @param priority the priority of the new value
*/
public void set( PropertyKey key, A value, Priority priority ){
Entry entry = getEntry( key, true );
entry.setValue( value, priority );
check( entry );
}
/**
* Ensures that the value behind key
will never be
* changed. Should be used with care: any attempt to set the value afterwards
* will be responded with an {@link IllegalStateException}. Most times it
* is much better to just use {@link Priority#CLIENT} to mark some setting
* as important.
* @param the type of the value
* @param key the key to protect
*/
public void finalize( PropertyKey key ){
Entry entry = getEntry( key, true );
entry.lock();
}
/**
* Either sets the property key
to value
or
* set the default value for key
.
* @param the type of the value
* @param key the key to access the value
* @param value the new value, if null
then the default
* value will be set
* @param priority the priority of the value to remove
*/
public void setOrRemove( PropertyKey key, A value, Priority priority ){
if( value == null )
unset( key, priority );
else
set( key, value, priority );
}
/**
* Tells the entry key
that the user has never set its value.
* This is equivalent to calling unset( key, Priority.CLIENT )
.
* @param key the key to access the entry
*/
public void unset( PropertyKey> key ){
unset( key, Priority.CLIENT );
}
/**
* Tells the entry key
that the user has never set its value.
* Also removes the old value of the entry.
* @param key the key to access the entry
* @param priority the priority for which to remove the value
*/
public void unset( PropertyKey> key, Priority priority ){
Entry> entry = getEntry( key, true );
entry.unsetValue( priority );
check( entry );
}
/**
* Gets the value accessed by key
. If the value in the
* properties is not set, then the {@link PropertyKey#getDefault(DockProperties) default}
* value is returned.
* @param the type of the value
* @param key the key to search
* @return the value or null
*/
public A get( PropertyKey key ){
Entry entry = getEntry( key, true );
return entry.getValue();
}
/**
* Gets the value of key
for the given priority
.
* @param the kind of value
* @param key some key, not null
* @param priority the priority, not null
* @return the value, might be null
even if {@link #get(PropertyKey)}
* returns a non-null
value
*/
public A get( PropertyKey key, Priority priority ){
Entry entry = getEntry( key, false );
if( entry == null )
return null;
return entry.getValue( priority );
}
/**
* Tells whether there is value set for key
with priority
.
* @param the kind of value
* @param key the key to check
* @param priority the priority for which something might be set
* @return true
if there is a value set
*/
public boolean isSet( PropertyKey key, Priority priority ){
Entry entry = getEntry( key, false );
if( entry == null )
return false;
return entry.value.isSet( priority );
}
/**
* Tells whether there is value set for key
.
* @param the kind of value
* @param key the key to check
* @return true
if there is a value set
*/
public boolean isSet( PropertyKey key ){
Entry entry = getEntry( key, false );
if( entry == null )
return false;
return entry.value.isSomethingSet();
}
/**
* Adds a listener that will be informed whenever the value accessed
* through key
changes.
* @param the type of the value
* @param key the key that accesses the value
* @param listener the new listener
*/
public void addListener( PropertyKey key, DockPropertyListener listener ){
if( listener == null )
throw new IllegalArgumentException( "Listener must not be null" );
getEntry( key, true ).addListener( listener );
}
/**
* Removes an earlier added listener.
* @param the type of value observed by the listener
* @param key the key to access the observed entry
* @param listener the listener to remove
*/
public void removeListener( PropertyKey key, DockPropertyListener listener ){
Entry entry = getEntry( key, false );
if( entry != null ){
entry.removeListener( listener );
check( entry );
}
}
/**
* Gets the entry for key
.
* @param the type of the entry
* @param key the name of the entry
* @param createIfNull true
if null
is not a valid
* result.
* @return the entry or null
, but only if createIfNull
* is false
*/
@SuppressWarnings( "unchecked" )
private Entry getEntry( PropertyKey key, boolean createIfNull ){
Entry> entry = map.get( key );
if( entry == null && createIfNull ){
entry = new Entry( key );
map.put( key, entry );
}
return (Entry)entry;
}
/**
* Checks whether entry
has to be stored any longer.
* @param entry the entry that may be deleted
*/
private void check( Entry> entry ){
if( entry.removeable() ){
map.remove( entry.getKey() );
}
}
/**
* An entry that contains key, listeners and a value.
* @author Benjamin Sigg
*
* @param the type of the value
*/
private class Entry{
/** the name of this entry */
private PropertyKey key;
/** listeners to this entry */
private List> listeners = new ArrayList>();
/** the value stored in this entry */
private NullPriorityValue value = new NullPriorityValue();
/** default value of this entry */
private A defaultValue;
/** whether the default value was ever needed and has been set */
private boolean defaultValueSet = false;
/** whether changes of this entry are allowed */
private boolean locked = false;
/**
* Creates a new entry.
* @param key the name of this entry
*/
public Entry( PropertyKey key ){
this.key = key;
}
/**
* If called makes this entry immutable.
*/
public void lock(){
locked = true;
}
/**
* Sets the new value of this entry.
* @param value the new value
* @param priority the priority of the new value
*/
@SuppressWarnings( "unchecked" )
public void setValue( A value, Priority priority ){
if( locked ){
throw new IllegalStateException( "this entry is immutable" );
}
A oldValue = getValue();
this.value.set( priority, value );
A newValue = getValue();
if( (oldValue == null && newValue != null) ||
(oldValue != null && newValue == null) ||
(oldValue != null && !oldValue.equals( newValue ))){
for( DockPropertyListener listener : (DockPropertyListener[])listeners.toArray( new DockPropertyListener>[ listeners.size() ] ))
listener.propertyChanged( DockProperties.this, key, oldValue, newValue );
}
}
/**
* Removes a value from this entry
* @param priority the priority of the value to unset
*/
@SuppressWarnings("unchecked")
public void unsetValue( Priority priority ){
if( locked ){
throw new IllegalStateException( "this entry is immutable" );
}
A oldValue = getValue();
this.value.unset( priority );
A newValue = getValue();
if( (oldValue == null && newValue != null) ||
(oldValue != null && newValue == null) ||
(oldValue != null && !oldValue.equals( newValue ))){
for( DockPropertyListener listener : (DockPropertyListener[])listeners.toArray( new DockPropertyListener>[ listeners.size() ] ))
listener.propertyChanged( DockProperties.this, key, oldValue, newValue );
}
}
/**
* Gets the value of this entry.
* @return the value
*/
public A getValue(){
A value = this.value.get();
if( value == null && (!this.value.isSomethingSet() || key.isNullValueReplacedByDefault()) ){
return getDefault();
}
return value;
}
/**
* Gets the value stored for priority
.
* @param priority the priority, not null
* @return the value, might be null
*/
public A getValue( Priority priority ){
return value.get( priority );
}
/**
* Gets the default value of this property.
* @return the default value, may be null
*/
public A getDefault(){
if( !defaultValueSet ){
defaultValue = key.getDefault( DockProperties.this );
defaultValueSet = true;
}
return defaultValue;
}
/**
* Gets the name of this entry.
* @return the name
*/
public PropertyKey getKey(){
return key;
}
/**
* Adds a new listener to this entry.
* @param listener the new listener
*/
public void addListener( DockPropertyListener listener ){
listeners.add( listener );
}
/**
* Removes a listener from this entry.
* @param listener the listener to remove
*/
public void removeListener( DockPropertyListener listener ){
listeners.remove( listener );
}
/**
* Tells whether this entry is needed any longer or not.
* @return true
if this entry can be deleted safely.
*/
public boolean removeable(){
if( locked )
return false;
if( !listeners.isEmpty() )
return false;
if( defaultValueSet || value.isSomethingSet() )
return false;
return true;
}
}
}