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

bibliothek.gui.dock.extension.css.scheme.MatchedCssRule 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) 2012 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.extension.css.scheme;

import bibliothek.gui.dock.extension.css.CssItem;
import bibliothek.gui.dock.extension.css.CssProperty;
import bibliothek.gui.dock.extension.css.CssPropertyContainer;
import bibliothek.gui.dock.extension.css.CssPropertyKey;
import bibliothek.gui.dock.extension.css.CssRule;
import bibliothek.gui.dock.extension.css.CssRuleContent;
import bibliothek.gui.dock.extension.css.CssScheme;
import bibliothek.gui.dock.extension.css.transition.TransitionalCssRuleContent;

/**
 * A {@link MatchedCssRule} is responsible for reading the properties of one {@link CssRule}
 * and forward them to a {@link CssItem}. Due to transitions several {@link CssRule}s may be active
 * at the same time, in this case this {@link MatchedCssRule} is marked as {@link #outdate()}. Only
 * {@link CssProperty}s which are considered {@link #isInput(CssPropertyKey) input properties} remain
 * active. Input properties usually are attached to a {@link CssPropertyContainer} which got involved
 * in an transition, yet itself is not a {@link CssProperty} nor a {@link CssItem}.
 * @author Benjamin Sigg
 */
public class MatchedCssRule {
	private static enum Mode{
		NEW, HEAD, OUTDATED, DESTROYED
	}
	
	/** the values of all the properties */
	private TransitionalCssRuleContent rule;
	
	/** the behavior of this {@link MatchedCssRule} */
	private Mode mode = Mode.NEW;
	
	private Forwarder forwarder;
	
	/**
	 * Creates a new match
	 * @param scheme the scheme in whose realm this rule is used
	 * @param item the item whose properties are set
	 * @param rule the rule from which to read properties, can be null
	 */
	public MatchedCssRule( CssScheme scheme, CssItem item, TransitionalCssRuleContent rule ){
		this.rule = rule;
		forwarder = new Forwarder( rule, item, scheme );
	}
	
	/**
	 * Install this, starts monitoring all {@link CssProperty}s of the {@link CssItem}.
	 * @param firstRule whether this is the first rule for the {@link CssItem}, the first rule also
	 * call {@link CssProperty#setScheme(CssScheme, String)}
	 */
	public void install( boolean firstRule ){
		if( mode != Mode.NEW ){
			throw new IllegalStateException( "already installed" );
		}
		mode = Mode.HEAD;
		forwarder.install( firstRule );
	}
	
	private boolean isInput( CssPropertyKey key ){
		if( rule == null ){
			return false;
		}
		return rule.isInput( key );
	}
	
	/**
	 * Informs this {@link MatchedCssRule} that it is no longer working with the most recent
	 * {@link CssRule}. The current {@link CssProperty}s will be copied and kept alive until
	 * {@link #destroy()} is called. 
	 */
	public void outdate(){
		if( mode != Mode.DESTROYED ){
			if( mode == Mode.HEAD ){
				forwarder.outdate();
			}
			mode = Mode.OUTDATED;
		}
	}
	
	/**
	 * Informs this {@link MatchedCssRule} that it is no longer in use, all resources are released.
	 */
	public void destroy(){
		if( mode != Mode.DESTROYED ){
			outdate();
			mode = Mode.DESTROYED;
			forwarder.destroy();
		}
	}
	
	private class Forwarder extends PropertyForwarder{
		public Forwarder( CssRuleContent source, CssPropertyContainer target, CssScheme scheme ){
			super( source, target, scheme );
		}
		
		@Override
		protected  void addProperty( CssPropertyKey key, CssProperty property, boolean firstRule ){
			if( mode == Mode.OUTDATED && !isInput(key) ){
				throw new IllegalStateException( "attempt to register a static property after rule has been outdated" );
			}
			super.addProperty( key, property, firstRule );
		}
		
		public void outdate(){
			// remove all static properties, keep dynamic properties until destruction
			ignoreTarget();
			
			CssPropertyKey[] keys = getKeys();
			for( CssPropertyKey key : keys ){
				CssProperty property = getProperty( key );
				if( !isInput(key) ){
					removeProperty( key, property, false );
				}
			}
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy