package net.xoetrope.xui.style;
import net.xoetrope.xui.XComponentFactory;
import net.xoetrope.xui.XProject;
import java.util.Hashtable;
import net.xoetrope.xui.XAttributedComponent;
import net.xoetrope.xui.helper.ReflectionHelper;
/**
* Extends the basic component factory by adding style information.
* As the component are added the styles are applied.
* <p>Copyright (c) Xoetrope Ltd., 1998-2003<br>
* License: see license.txt
* $Revision: 2.5 $
*/
public class XStyleFactory extends XComponentFactory
{
/**
* The project XStyleManager
*/
protected XStyleManager styleManager;
/**
* Create the StyleFactory and initialise with an XStyleManager.
* @param project The current project
* @param packageName The package being used in the project AWT/Swing
*/
public XStyleFactory( XProject project, String packageName )
{
super( project, packageName );
setup();
}
/**
* moved from the ctor so as to allow subclassed XStyleFactories to do the
* initialisation in the getInstance().
*/
protected void setup()
{
styleManager = currentProject.getStyleManager();
}
/**
* Pass the addNamedComponent call to the XStyleFactory base Class
* @param type The type of object being constructed
* @param constraint the layout constraint
* @param txt The content to display
* @param style The name of the style to apply
* @return The created component
*/
public Object addComponent( String type, Object constraint, String txt, String style )
{
Object c = super.addComponent( type, constraint, txt );
applyStyle( c, style );
return c;
}
/**
* Pass the addNamedComponent call to the XStyleFactory base Class
* @param txt The content to be applied to the component
* @param type The type of object being constructed
* @param x The x coordinate of the new component
* @param y The y coordinate of the new component
* @param w The width of the new component
* @param h The height of the new component
* @param style The name of the style to apply
* @return The created component
*/
public Object addComponent( String type, int x, int y, int w, int h, String txt, String style )
{
Object c = super.addComponent( type, x, y, w, h, txt );
applyStyle( c, style, false, (( w > 0 ) || ( h > 0 )) ? true : false );
return c;
}
/**
* Overloading method with the same signature in XComponentFactory.
* @param type The type of object being constructed
* @param x The x coordinate of the new component
* @param y The y coordinate of the new component
* @param w The width of the new component
* @param h The height of the new component
* @param txt The text/caption of the component
* @return The created component
*/
public Object addComponent( String type, int x, int y, int w, int h, String txt )
{
return addComponent( type, x, y, w, h, txt, null );
}
/**
* Pass the addNamedComponent call to the XStyleFactory base Class
* @param type The type of object being constructed
* @param x The x coordinate of the new component
* @param y The y coordinate of the new component
* @param w The width of the new component
* @param h The height of the new component
* @return The created component
*/
public Object addComponent( String type, int x, int y, int w, int h )
{
Object c = super.addComponent( type, x, y, w, h, null );
applyStyle( c, (String)null, false, (( w > 0 ) || ( h > 0 )) ? true : false );
return c;
}
/**
* Sets a LayoutManager for the panel
* @param attribs Hashtable of layout attributes
* @param cont the container whose layout manager is being set or null to set the parent panel's layout manager
* @param type the layout manager as defined in the XLayoutHelper class
* @return The created LayoutManager
*/
public Object addLayout( Object cont, int type, Hashtable attribs )
{
if ( cont == null )
cont = parentPanel;
try {
return layoutHelper.addLayout( cont, type, attribs );
}
catch ( Exception e ) {
e.printStackTrace();
}
return null;
}
/**
* Apply a style to a component, looking up the style name if necessary
* @param c the component to style
* @param style the style name
* @param lookupComp true to lookup the style based on the component class
*/
public void applyStyle( Object c, String style, boolean lookupComp )
{
applyStyle( c, style, lookupComp, false );
}
/**
* Apply a style to a component, looking up the style name if necessary
* @param c the component to style
* @param style the style name
* @param lookupComp true to lookup the style based on the component class
* @param sizeAlreadySet specifies whether the preferred size can be set by the style
*/
public void applyStyle( Object c, String style, boolean lookupComp, boolean sizeAlreadySet )
{
boolean createStyle = true;
if ( style == null ) {
lookupComp = true;
createStyle = false;
style = "";
}
if (( c != null ) && ( style != null )) {
String type = "";
if ( lookupComp ) {
type = c.getClass().getName();
int pos = type.lastIndexOf( "." );
type = type.substring( pos + 1, type.length() );
}
XStyle xstyle = styleManager.getStyle( checkStyleName( style, type, lookupComp ), createStyle );
if ( xstyle != null ) {
adapter.setFont( c, styleManager.getFont( xstyle ) );
adapter.setBackground( c, xstyle.getStyleAsColor( XStyle.COLOR_BACK ) );
adapter.setForeground( c, xstyle.getStyleAsColor( XStyle.COLOR_FORE ) );
if ( c instanceof XStyleComponent )
((XStyleComponent)c).setStyle( style );
}
// Set the attributes listed as part of the style
if ( xstyle instanceof XStyleEx ) {
int numStyles = xstyle.getNumStyles();
if ( c instanceof XAttributedComponent ) {
XAttributedComponent ac = (XAttributedComponent)c;
for ( int i = XStyle.NUM_DEFAULT_STYLES; i < numStyles; i++ )
ac.setAttribute( xstyle.getStyleName( i ), xstyle.getStyleAsString( i ));
}
else {
for ( int i = XStyle.NUM_DEFAULT_STYLES; i < numStyles; i++ ) {
String methodName = xstyle.getStyleName( i );
methodName = "set" + methodName.substring( 0, 1 ).toUpperCase() + methodName.substring( 1 );
Object value = xstyle.getStyleValue( i );
try {
/** @todo check if the classes Integer, Double, Float need to be converted to int.class, double.class, and float.class */
ReflectionHelper.setViaReflection( methodName, c, value, value.getClass());
}
catch ( Exception e ) {}
}
}
}
}
}
/**
* Apply a style to a component. Set the font and foreground/background color.
* @param c The component to style
* @param xstyle The XStyle object whose style is to be applied to the
* component
*/
public void applyStyle( Object c, XStyle xstyle )
{
applyStyle( c, xstyle, true );
}
/**
* Apply a style to a component. Set the font and foreground/background color.
* @param c The component to style
* @param xstyle The XStyle object whose style is to be applied to the
* component
*/
public void applyStyle( Object c, XStyle xstyle, boolean sizeAlreadySet )
{
if (( c != null ) && ( xstyle != null )) {
adapter.setFont( c, styleManager.getFont( xstyle ) );
adapter.setBackground( c, xstyle.getStyleAsColor( XStyle.COLOR_BACK ) );
adapter.setForeground( c, xstyle.getStyleAsColor( XStyle.COLOR_FORE ) );
String s = xstyle.getStyleAsString( xstyle.getStyleIndex( XStyleConstants.ALIGN_HORZ ));
if ( s != null )
adapter.setHorizontalAlignment( c, s );
s = xstyle.getStyleAsString( xstyle.getStyleIndex( XStyleConstants.ALIGN_VERT ));
if ( s != null )
adapter.setVerticalAlignment( c, s );
s = xstyle.getStyleAsString( xstyle.getStyleIndex( XStyleConstants.BORDER_STYLE ));
if ( s != null )
adapter.setBorderStyle( c, s );
s = xstyle.getStyleAsString( xstyle.getStyleIndex( XStyleConstants.BORDER_TYPE ));
if ( s != null )
adapter.setBorderType( c, s );
s = xstyle.getStyleAsString( xstyle.getStyleIndex( XStyleConstants.PREF_WIDTH ));
if ( !sizeAlreadySet && ( s != null ))
adapter.setPreferredSize( c, xstyle.getStyleAsInt( xstyle.getStyleIndex( XStyleConstants.PREF_WIDTH )),
xstyle.getStyleAsInt( xstyle.getStyleIndex( XStyleConstants.PREF_HEIGHT )));
}
}
/**
* Called after a new component is created. Append the style to the base and
* then append the component classname with '/' delimiters.
* @param c Component to apply the style to.
* @param style the name of the style to apply.
*
*/
public void applyStyle( Object c, String style )
{
applyStyle( c, style, false );
}
/**
* Check that the style name is fully qualified with the 'base' name and
* add the type name if needed.
* @param style the style name
* @param type the componnet type name
* @param lookupComp append the style name to the type if true
* @return the fully qualified style name
*/
private String checkStyleName( String style, String type, boolean lookupComp )
{
String retStyle = "";
if ( style != null )
retStyle = style;
if ( lookupComp )
retStyle += type;
return retStyle;
}
}