/docking-frames-core/src/bibliothek/extension/gui/dock/preference/MergedPreferenceModel.java
https://github.com/paranoia25/DockingFrames · Java · 423 lines · 252 code · 61 blank · 110 comment · 57 complexity · 64cc5a8f64f1bdd9a1621e3db0a358c9 MD5 · raw file
- /*
- * 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 java.util.ArrayList;
- import java.util.List;
-
- import bibliothek.gui.DockController;
- import bibliothek.util.Path;
- import bibliothek.util.PathCombiner;
-
- /**
- * A preference model that envelops other models and uses their preferences. This model
- * makes use of a {@link PathCombiner} to create unique identifiers for all preferences of its
- * sub-models.
- * @author Benjamin Sigg
- */
- public class MergedPreferenceModel extends AbstractPreferenceModel{
- private List<Model> models = new ArrayList<Model>();
-
- /** how to create the result of {@link #getPath(int)} */
- private PathCombiner combiner = PathCombiner.UNIQUE;
-
- private PreferenceModelListener listener = new PreferenceModelListener(){
- public void preferenceAdded( PreferenceModel model, int beginIndex, int endIndex ){
- int begin = indexAt( model, beginIndex );
- int end = begin + (endIndex - beginIndex);
- firePreferenceAdded( begin, end );
- }
-
- public void preferenceChanged( PreferenceModel model, int beginIndex, int endIndex ){
- int begin = indexAt( model, beginIndex );
- int end = begin + (endIndex - beginIndex);
- firePreferenceChanged( begin, end );
- }
-
- public void preferenceRemoved( PreferenceModel model, int beginIndex, int endIndex ){
- int begin = indexAt( model, beginIndex );
- int end = begin + (endIndex - beginIndex);
- firePreferenceRemoved( begin, end );
- }
- };
-
- /**
- * Creates a new model
- * @param controller the controller in whose realm this model is used
- */
- public MergedPreferenceModel( DockController controller ){
- super( controller );
- }
-
- /**
- * Creates a new path.
- * @param combiner tells how to combine the path of a model and of
- * its preferences in {@link #getPath(int)}. Not <code>null</code>.
- * @param controller the controller in whose realm this model is used
- */
- public MergedPreferenceModel( PathCombiner combiner, DockController controller ){
- super( controller );
- if( combiner == null )
- throw new IllegalArgumentException( "combiner must not be null" );
-
- this.combiner = combiner;
- }
-
- /**
- * Adds <code>model</code> at the end of this model.
- * @param model the additional model
- * @param path the location of the new model
- * @see #insert(int, PreferenceModel, Path)
- */
- public void add( PreferenceModel model, Path path ){
- insert( models.size(), model, path );
- }
-
- /**
- * Inserts a new submodel into this model.
- * @param index the location of the new model
- * @param model the new model
- * @param path the path of the new model, the path must be unique compared
- * to the paths of any other model.
- */
- public void insert( int index, PreferenceModel model, Path path ){
- if( this == model )
- throw new IllegalArgumentException( "model must not be this" );
-
- for( Model check : models ){
- if( check.model == model )
- throw new IllegalArgumentException( "can't add a model twice" );
-
- if( check.path.equals( path ))
- throw new IllegalArgumentException( "there is already a model with the path " + path );
- }
-
- Model insert = new Model();
- insert.model = model;
- insert.path = path;
-
- models.add( index, insert );
- if( hasListeners() )
- model.addPreferenceModelListener( listener );
-
- int size = model.getSize();
-
- if( size > 0 ){
- int begin = 0;
- for( int i = 0; i < index; i++ ){
- begin += models.get( i ).model.getSize();
- }
- firePreferenceAdded( begin, begin+size-1 );
- }
- }
-
- /**
- * Removes the <code>index'th</code> model of this merged model.
- * @param index the location of a child
- */
- public void remove( int index ){
- Model model = models.remove( index );
- if( hasListeners() )
- model.model.removePreferenceModelListener( listener );
-
- int size = model.model.getSize();
- if( size > 0 ){
- int begin = 0;
- for( int i = 0; i < index; i++ ){
- begin += models.get( i ).model.getSize();
- }
- firePreferenceRemoved( begin, begin+size-1 );
- }
- }
-
- /**
- * Removes <code>model</code> from this merged model.
- * @param model the model to remove
- */
- public void remove( MergedPreferenceModel model ){
- int index = indexOf( model );
- if( index >= 0 )
- remove( index );
- }
-
- /**
- * Removes the model with the path <code>path</code>.
- * @param path some path
- */
- public void remove( Path path ){
- int index = indexOf( path );
- if( index >= 0 )
- remove( index );
- }
-
- /**
- * Removes all children from this model.
- */
- public void clear(){
- int size = getSize();
- if( hasListeners() ){
- for( Model model : models ){
- model.model.removePreferenceModelListener( listener );
- }
- }
- models.clear();
- if( size > 0 ){
- firePreferenceRemoved( 0, size-1 );
- }
- }
-
- /**
- * Gets the index of <code>model</code>.
- * @param model some model to search
- * @return the index or -1 if not found
- */
- public int indexOf( PreferenceModel model ){
- int i = 0;
- for( Model check : models ){
- if( check.model == model )
- return i;
-
- i++;
- }
-
- return -1;
- }
-
- /**
- * Gets the index of <code>path</code>.
- * @param path the path of some model
- * @return the index or -1 if not found
- */
- public int indexOf( Path path ){
- int i = 0;
- for( Model check : models ){
- if( check.path.equals( path ) )
- return i;
-
- i++;
- }
-
- return -1;
- }
-
- /**
- * Gets the <code>index</code>'th model of this merged model.
- * @param index some index
- * @return a child of this model
- */
- public PreferenceModel getModel( int index ){
- return models.get( index ).model;
- }
-
- /**
- * Gets the model which was stored using the key <code>path</code>.
- * @param path the path of the model
- * @return the model or <code>null</code> if not found
- */
- public PreferenceModel getModel( Path path ){
- int index = indexOf( path );
- if( index < 0 ){
- return null;
- }
- return getModel( index );
- }
-
- @Override
- public void read() {
- for( Model model : models ){
- model.model.read();
- }
- }
-
- @Override
- public void write() {
- for( Model model : models ){
- model.model.write();
- }
- }
-
- @Override
- public void addPreferenceModelListener( PreferenceModelListener listener ) {
- boolean hadListeners = hasListeners();
- super.addPreferenceModelListener( listener );
- if( hasListeners() && !hadListeners ){
- for( Model model : models ){
- model.model.addPreferenceModelListener( this.listener );
- }
- }
- }
-
- @Override
- public void removePreferenceModelListener( PreferenceModelListener listener ) {
- boolean hadListeners = hasListeners();
- super.removePreferenceModelListener( listener );
- if( !hasListeners() && hadListeners ){
- for( Model model : models ){
- model.model.removePreferenceModelListener( this.listener );
- }
- }
- }
-
- public int getSize() {
- int size = 0;
- for( Model model : models ){
- size += model.model.getSize();
- }
- return size;
- }
-
- public String getLabel( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return local.model.model.getLabel( local.index );
- }
-
- @Override
- public String getDescription( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return local.model.model.getDescription( local.index );
- }
-
- public Object getValueInfo(int index) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return local.model.model.getValueInfo( local.index );
- }
-
- public Object getValue( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return local.model.model.getValue( local.index );
- }
-
- public void setValue( int index, Object value ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- local.model.model.setValue( local.index, value );
- }
-
- public Path getTypePath( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return local.model.model.getTypePath( local.index );
- }
-
- public Path getPath( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return combiner.combine( local.model.path, local.model.model.getPath( local.index ) );
- }
-
- @Override
- public boolean isNatural( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- return local.model.model.isNatural( local.index );
- }
-
- @Override
- public void setValueNatural( int index ) {
- Index local = indexAt( index );
- if( local == null )
- throw new ArrayIndexOutOfBoundsException( index );
-
- local.model.model.setValueNatural( local.index );
- }
-
- /**
- * Gets the model and the index that <code>globalIndex</code> describe in
- * this model.
- * @param globalIndex some global index
- * @return the local index
- */
- protected Index indexAt( int globalIndex ){
- for( Model model : models ){
- int size = model.model.getSize();
- if( globalIndex < size )
- return new Index( model, globalIndex );
- else
- globalIndex -= size;
- }
- return null;
- }
-
- /**
- * Finds the global index if <code>index</code> is part of <code>model</code>.
- * @param model a child of this model
- * @param index an index in <code>model</code>
- * @return the global index
- */
- protected int indexAt( PreferenceModel model, int index ){
- for( Model check : models ){
- if( check.model == model )
- return index;
-
- index += check.model.getSize();
- }
-
- return index;
- }
-
- /**
- * Describes an index in one of the childen of a {@link MergedPreferenceModel}.
- * @author Benjamin Sigg
- */
- protected static class Index{
- public Model model;
- public int index;
-
- public Index( Model model, int index ){
- this.model = model;
- this.index = index;
- }
- }
-
- /**
- * A sub-model entry of a {@link MergedPreferenceModel}.
- * @author Benjamin Sigg
- */
- private static class Model{
- public PreferenceModel model;
- public Path path;
- }
- }