Package net.xoetrope.xui.style

Source Code of net.xoetrope.xui.style.XStyleManager

package net.xoetrope.xui.style;

import java.io.BufferedReader;
import java.util.Enumeration;
import java.util.Hashtable;
import java.awt.Font;

import net.xoetrope.debug.DebugLogger;
import net.xoetrope.xml.XmlElement;
import net.xoetrope.xml.XmlSource;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.build.BuildProperties;

/**
* Class for managing XStyles. XStyles are created
* externally and added to the hashtable. Also handles the retrieval of styles.
* <p>Copyright (c) Xoetrope Ltd., 1998-2004<br>
* $Revision: 2.7 $
*/
public class XStyleManager
{
  /**
   * Hashtable of project styles
   */
  protected Hashtable styles;
 
  /**
   * Used to merge child styles with their parents
   */
  protected Hashtable mergedStyles;
 
  /**
   * Fonts found when creating styles
   */
  protected Hashtable fontCache;
 
  /**
   * The base style from which all others will be inherited
   */
  protected static XStyle baseStyle = new XStyleEx();
 
  /**
   * The XProject for which this instance of the XStyleManager is working
   */
  protected XProject currentProject;

  /**
   * Mapping of font attributes
   */
  protected Hashtable fontMap;

  /**
   * Construct a new style manager.
   * @param project the owner project
   */
  public XStyleManager( XProject project )
  {
    this( project, 10 );
  }

  /**
   * Construct a new style manager with an initial size.
   * @param styleCount The number of initial styles in the styles Hashtable
   */
  public XStyleManager( XProject project, int styleCount )
  {
    currentProject = project;

    styles = new Hashtable( styleCount );
    mergedStyles = new Hashtable( styleCount );
    fontCache = new Hashtable( 10 );

    try {
      String styleFile = currentProject.getStartupParam( "StyleFile" );
      if ( styleFile == null )
        styleFile = "styles.xml";
      load( styleFile );
    }
    catch ( Exception ex ) {
      DebugLogger.logWarning( "No style file loaded!" );
    }
  }

  /**
   * Add a new XStyle to the hashtable with a unique name
   * @param name The name of the style
   * @param newStyle The XStyle to be associated with the passed name
   */
  public void addStyle( String name, XStyle newStyle )
  {
    styles.remove( name );
    styles.put( name, newStyle );
  }

  /**
   * Retrieve a named XStyle from the hashtable. loop thru the "/" character
   * and merge each one found with a new XStyle.
   * @param name The name of the style.
   * @param create booean to indicate whether the style should be created.
   * @return The referenced XStyle
   */
  public XStyle getStyle( String name, boolean create )
  {
    String styleName;
    String qualifiedName = null;
    qualifiedName = name;

    if ( qualifiedName == null )
      return null;

    XStyle tempXStyle = (XStyle)mergedStyles.get( qualifiedName );
    if ( tempXStyle != null )
      return tempXStyle;

    int startPos = 0;
    if ( create ) {
      tempXStyle = (XStyle)baseStyle.clone();
      int pos;
      do {
        pos = qualifiedName.indexOf( "/", startPos );

        if ( pos != -1 )
          styleName = qualifiedName.substring( 0, pos );
        else
          styleName = qualifiedName;

        XStyle targetStyle = (XStyle)styles.get( styleName );
        if ( targetStyle instanceof XStyleEx ) {
          if ( !( tempXStyle instanceof XStyleEx ))
            tempXStyle = new XStyleEx( tempXStyle );
        }
        tempXStyle.mergeStyle( targetStyle );
        startPos = pos + 1;
      }
      while ( pos != -1 );

      mergedStyles.put( qualifiedName, tempXStyle );
    }

    return tempXStyle;
  }
 
  /**
   * Check if a style is available, either already processed, or named somewhere
   * in the raw styles file. The method checks only basic style names
   * @param styleName the name of the style
   * @return true if the style is found
   */
  public boolean hasStyle( String styleName )
  {
    if ( mergedStyles.get( styleName ) != null )
      return true;
    else if ( styles.get( styleName ) != null )
      return true;
   
    return false;
  }

  /**
   * Retrieve a named XStyle from the hashtable. loop thru the "/" character
   * and merge each one found with a new XStyle.
   * @param name The name of the style.
   * @return The referenced XStyle
   */
  public XStyle getStyle( String name )
  {
    return getStyle( name, true );
  }

  /**
   * Get the font for a given style. Use the bold and italic attributes and do a
   * bitwise or using the Font values to set the style.
   * @param style the name of the style
   * @return The constructed Font Object for the named XStyle
   */
  public Font getFont( String style )
  {
    return getFont( getStyle( style ));
  }

  /**
   * Get the font for a given style. Use the bold and italic attributes and do a
   * bitwise or using the Font values to set the style.
   * @param style the style
   * @return The constructed Font Object for the passed XStyle
   */
  public Font getFont( XStyle style )
  {
    Font f = (Font)fontCache.get( style.getFontHashcode());
    if ( f != null )
      return f;
    int bold = style.getStyleAsInt( XStyle.FONT_WEIGHT );
    int italic = style.getStyleAsInt( XStyle.FONT_ITALIC );
    int fontStyle = 0;

    if ( bold == 1 )
      fontStyle = Font.BOLD;
    if ( italic == 1 )
      fontStyle = fontStyle | Font.ITALIC;

    String fontFace = style.getStyleAsString( XStyle.FONT_FACE );
    if ( fontFace == null )
      return null;

    int fontSize = style.getStyleAsInt( XStyle.FONT_SIZE );
   
    // Now check the font mapping
    // First the font face and font size
    if ( fontMap != null ) {
      String mappedFontFace = (String)fontMap.get( fontFace + fontSize );
      if ( mappedFontFace != null )
        fontFace = mappedFontFace;   
      else {
        // Then just the face
        mappedFontFace = (String)fontMap.get( fontFace );
        if ( mappedFontFace != null )
          fontFace = mappedFontFace;
      }

      // Split out the font size if necessary
      int pos = fontFace.indexOf( ';' );
      if ( pos > 0 ) {
        fontSize = new Integer( fontFace.substring( pos + 1 )).intValue();
        fontFace = fontFace.substring( 0, pos );
      }
    }
    f = new Font( fontFace, fontStyle, fontSize );
   
    fontCache.put( style.getFontHashcode(), f );
    return f;
  }

  /**
   * Setup the font mapping for
   * @param fontMaps the font mappings (face and size or just face to face)
   */
  public void setFontMap( Hashtable fontMaps )
  {
    fontCache = new Hashtable();
    fontMap = new Hashtable();
   
    Enumeration keys = fontMaps.keys();
    while( keys.hasMoreElements()) {
      String key = (String)keys.nextElement();
      if ( key.startsWith( "font_" ))
        fontMap.put( key.substring( 5 ), fontMaps.get( key ));
    }
  }

  /**
   * Load the styles from the specified file
   * @param file the file name of the file to load
   */
  public void load( String file )
  {
    BufferedReader r = null;
    try {
      r = currentProject.getBufferedReader( file, null );
      if ( r != null ) {
        XmlElement element = XmlSource.read( r );
        loadXStyle( element, null );
        baseStyle = getStyle( "base" );
      }
    }
    catch ( Exception ex ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.trace( "Error loading styles file (" + file + "), please check that the file exists. Usually it is found in the resources folder of the project." );
    }
  }

  /**
   * Load a style from the XML element and save it to the specified path in the
   * style hierarchy
   * @param element the source element
   * @param path the save path
   */
  public void loadXStyle( XmlElement element, String path )
  {
    Enumeration e = element.getChildren().elements();
    XStyle xstyle = /*"true".equals( element.getAttribute( "extended" )) ?*/ new XStyleEx()/* : new XStyle()*/;
    /**
     * @todo set the number of styles based upon the number of children instead
     * of adding them one by one. The addStle method needs to be modified on this
     * basis also. (see XStyle and XStyleEx)
     */
    while ( e.hasMoreElements() ) {
      XmlElement eleStyle = ( XmlElement )e.nextElement();
      String elementName = eleStyle.getName();
      if ( elementName.equals( "style" )) {
        String temp = element.getAttribute( "name" );
        if (( path != null ) && ( path.length() > 0 ))
          temp = path + "/" + element.getAttribute( "name" );
        loadXStyle( eleStyle, temp );
      }
      else
        xstyle.setStyle( xstyle.getStyleIndex( elementName ), eleStyle.getAttribute( "value" ) );
    }
    xstyle.setClosed( true );

    String styleName = element.getAttribute( "name" );
    if (( path != null ) && ( path.length() > 0 ))
      styleName = path + "/" + styleName;
    if (( styleName != null ) && ( styleName.length() > 0 ))
      addStyle( styleName, xstyle );
  }
 
  /**
   * Get the table of styles
   * @return the stytle table
   */
  public Hashtable getStyles()
  {
    return styles;
  }

  /**
   * Get the parent of the named style
   * @param name the style name
   * @return the parent style
   */
  public XStyle getStyleParent( String name )
  {
    if ( name.indexOf( "/" ) > 0 )
      return getStyle( "base/" + name.substring( 0, name.lastIndexOf( "/" ) ) );
   
    return null;
  }
 
  /**
   * reset the styles in case a new stylesheet is to be loaded.
   */
  public void reset()
  {
    styles.clear();
    mergedStyles.clear();
    fontCache.clear();
  }
}
TOP

Related Classes of net.xoetrope.xui.style.XStyleManager

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.