Package bibliothek.gui.dock.common.intern

Source Code of bibliothek.gui.dock.common.intern.CPlaceholderStrategy

/*
* 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) 2010 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.gui.dock.common.intern;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import bibliothek.gui.DockStation;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.common.CControl;
import bibliothek.gui.dock.common.MultipleCDockable;
import bibliothek.gui.dock.common.SingleCDockable;
import bibliothek.gui.dock.common.event.CControlListener;
import bibliothek.gui.dock.station.support.PlaceholderStrategy;
import bibliothek.gui.dock.station.support.PlaceholderStrategyListener;
import bibliothek.util.Path;

/**
* This strategy assigns a unique identifier to all {@link CDockable}s that
* are registered at a {@link CControl}.
* @author Benjamin Sigg
*/
public class CPlaceholderStrategy implements PlaceholderStrategy {
  /**
   * Gets the placeholder that is used for the {@link SingleCDockable} with
   * unique identifier <code>id</code>.
   * @param id the unique identifer of a {@link SingleCDockable}
   * @return the placeholder for that dockable
   */
  public static Path getSingleDockablePlaceholder( String id ){
    return new Path( "dock", "single", id );
  }
 
  /**
   * Gets the placeholder that is used for the {@link MultipleCDockable} with
   * unique identifier <code>id</code>.
   * @param id the unique identifer of a {@link MultipleCDockable}
   * @return the placeholder for that dockable
   */
  public static Path getMultipleDockablePlaceholder( String id ){
    return new Path( "dock", "multi", id );
  }
 
  /** the owner of this strategy */
  private CControl control;
 
  /** all the listeners that are registered */
  private List<PlaceholderStrategyListener> listeners = new ArrayList<PlaceholderStrategyListener>();
 
  /** a map containing placeholders for various {@link MultipleCDockable}s */
  private Map<MultipleCDockable, Path> multiplePlaceholders = new HashMap<MultipleCDockable, Path>();
 
  private CControlListener controlListener = new CControlListener() {
    public void removed( CControl control, CDockable dockable ){
      if( dockable instanceof SingleCDockable ){
        String id = ((SingleCDockable)dockable).getUniqueId();
        Path check = getSingleDockablePlaceholder( id );
        if( !isValidPlaceholder( check )){
          fireInvalidated( check );
        }
      }
      else if( dockable instanceof MultipleCDockable ){
        Path check = multiplePlaceholders.remove( dockable );
        if( check != null ){
          if( !isValidPlaceholder( check )){
            fireInvalidated( check );
          }
        }
      }
    }
   
    public void opened( CControl control, CDockable dockable ){
      // ignore
    }
   
    public void closed( CControl control, CDockable dockable ){
      // ignore
    }
   
    public void added( CControl control, CDockable dockable ){
      // ignore
    }
  };
 
  /** placeholders of {@link MultipleCDockable}s that need to be checked */
  private Set<Path> pendingChecks = null;
 
  private CDockFrontendListener frontendListener = new CDockFrontendListener(){
    public void loading( CDockFrontend frontend, CSetting setting ){
      pendingChecks = new HashSet<Path>();
    }
   
    public void loaded( CDockFrontend frontend, CSetting setting ){
      if( pendingChecks != null ){
        Set<Path> pendingChecks = CPlaceholderStrategy.this.pendingChecks;
        CPlaceholderStrategy.this.pendingChecks = null;
       
        for( Path check : pendingChecks ){
          if( !isValidPlaceholder( check )){
            fireInvalidated( check );
          }
        }
      }
    }
  };
 
  /**
   * Creates a new strategy
   * @param control the control in whose realm this strategy operates
   */
  public CPlaceholderStrategy( CControl control ){
    this.control = control;
  }
 
  public void addListener( PlaceholderStrategyListener listener ){
    if( listener == null ){
      throw new IllegalArgumentException( "listener must not be null" );
    }
    if( listeners.isEmpty() ){
      control.addControlListener( this.controlListener );
      control.intern().addListener( this.frontendListener );
    }
    listeners.add( listener );
  }

  public void removeListener( PlaceholderStrategyListener listener ){
    listeners.remove( listener );
    if( listeners.isEmpty() ){
      control.removeControlListener( this.controlListener );
      control.intern().removeListener( frontendListener );
      frontendListener.loaded( null, null );
    }
  }
 
  protected void fireInvalidated( Path placeholder ){
    Set<Path> placeholders = new HashSet<Path>();
    placeholders.add( placeholder );
    placeholders = Collections.unmodifiableSet( placeholders );
    for( PlaceholderStrategyListener listener : listeners.toArray( new PlaceholderStrategyListener[ listeners.size() ] )){
      listener.placeholderInvalidated( placeholders );
    }
  }
 
  public Path getPlaceholderFor( Dockable dockable ){
    if( !(dockable instanceof CommonDockable) ){
      return null;
    }
   
    CDockable cdockable = ((CommonDockable)dockable).getDockable();
    CControlAccess controlAccess = cdockable.getControlAccess();
    if( controlAccess == null || controlAccess.getOwner() != control ){
      return null;
    }
   
    if( cdockable instanceof SingleCDockable ){
      String id = ((SingleCDockable)cdockable).getUniqueId();
      return getSingleDockablePlaceholder( id );
    }
    if( cdockable instanceof MultipleCDockable ){
      CDockableAccess access = controlAccess.access( cdockable );
      if( access != null ){
        Path result = getMultipleDockablePlaceholder( controlAccess.getRegister().multiToNormalId( access.getUniqueId() ) );
        multiplePlaceholders.put( (MultipleCDockable)cdockable, result );
        return result;
      }
    }
    return null;
  }
 
  public boolean isValidPlaceholder( Path placeholder ){
    if( placeholder.getSegmentCount() != 3 ){
      return false;
    }
   
    if( !placeholder.getSegment( 0 ).equals( "dock" ) ){
      return false;
    }
   
    if( placeholder.getSegment( 1 ).equals( "single" )){
      String id = placeholder.getSegment( 2 );
     
      // if the element is registered, then it is available...
      if( control.getSingleDockable( id ) != null ){
        return true;
      }
     
      // if there is a backup factory, then the client expects this element to exist
      if( control.getSingleDockableFactory( id ) != null ){
        return true;
      }
     
      // maybe the client installed a strategy for handling missing dockables
      if( control.getMissingStrategy().shouldStoreSingle( id ) ){
        return true;
      }
    }

    if( placeholder.getSegment( 1 ).equals( "multi" ) ){
      if( pendingChecks != null ){
        pendingChecks.add( placeholder );
        return true;
      }
     
      String id = placeholder.getSegment( 2 );
     
      // if the element exists, then the placeholder can remain
      if( control.getMultipleDockable( id ) != null ){
        return true;
      }
     
      // if there is a strategy, then the placeholder may remain
      if( control.getMissingStrategy().shouldStoreMulti( id )){
        return true;
      }
    }
   
    // the client does not want to store information about this element
    return false;
  }
 
  public void install( DockStation station ){
    // ignore
  }
 
  public void uninstall( DockStation station ){
    // ignore
  }
}
TOP

Related Classes of bibliothek.gui.dock.common.intern.CPlaceholderStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.