/******************************************************************************* * Copyright (c) 2002-2006 Innoopract Informationssysteme GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Innoopract Informationssysteme GmbH - initial API and implementation ******************************************************************************/ package com.w4t; import java.beans.DesignMode; import org.eclipse.rwt.Adaptable; import org.eclipse.rwt.internal.events.EventAdapter; import org.eclipse.rwt.internal.events.IEventAdapter; import com.w4t.developer.PanelCreator; import com.w4t.event.WebRenderEvent; import com.w4t.event.WebRenderListener; import com.w4t.util.WebComponentCounter; import com.w4t.util.WebComponentRegistry; /** * <p>The abstract superclass of all WebComponents.</p> * * <p>A WebComponent is an object having a html representation that can be * used in an html document and that can interact with the user.</p> * * <p>Examples of WebComponent are the WebButtons, WebCheckBoxes, and * WebTexts of a typical graphical user interface.</p> */ public abstract class WebComponent extends WebObject implements DesignMode, Adaptable { /** <p>every WebComponent has an internal unique idendentifier, which is * set at construction time, see {@link #getUniqueID() getUniqueID()}.</p> */ private String uniqueId = ""; /** reference to the WebContainer, which contains this WebComponent * {@link #getParent getParent} */ protected WebContainer parent = null; /** used in design time for code generation as * variable name for this component */ protected String name = ""; /** <p>whether this WebComponent is enabled (reacts on user input) * or not. A WebComponent is also not enabled if it is added to a * WebContainer and the WebContainer to which it is added is * disabled.</p> */ private boolean enabled = true; /** <p>flag: tells, whether this component is rendered on the * WebForm.</p> */ private boolean visible = true; /** <p>the event semantics that was associated with this WebComponent * in a w4t application.</p> * <p>An event semantics identifies a special purpose of an event firing * that may occur on various Components in the application. A component * may follow various event semantics at once (ids must be bitwise * or-combined in order to achieve this.</p> * <p>Event semantics ids must be defined by the application. Value 0 * signals a null semantics.</p> */ private int eventSemanticsID = 0; private IEventAdapter eventAdapter; // design time specific fields ////////////////////////////// /** A value of true denotes that this WebComponent should behave in design * time mode, a value of false denotes runtime behavior. */ protected boolean designTime = false; /** Constructor. */ protected WebComponent() { uniqueId = WebComponentCounter.getInstance().getNewID(); WebComponentRegistry.getInstance().add( this ); if( this instanceof Concealer ) { this.designTime = false; } } /** returns a clone of this WebComponent.<br> * For all elementary WebComponents, cloning will result in a deep copy, * shallow copying all fields, cloning property objects (i.e. all * subclasses of WebComponentProperties, like Style, WindowProperties * etc.), and in case the WebObject to clone is a WebContainer, also * cloning all WebComponents, if they were added to it using * WebContainer.add(), and the WebLayout, if it was set using * WebContainer.setWebLayout(). Fields containing external references to * Objects which are not added with one of those methods are set to null * in the cloned object. */ public Object clone() throws CloneNotSupportedException { WebComponent clone = ( WebComponent )super.clone(); /* we must perform a separate init (get an ID, set unused) for the clone, since no constructors are called in Object.clone() */ clone.uniqueId = WebComponentCounter.getInstance().getNewID(); WebComponentRegistry.getInstance().add( clone ); return clone; } /** * <p>Adds the specified WebRenderListener to receive render events from * this WebComponent. Render events occur before and/or after this * WebComponent is rendered (note that WebComponents are not rendered if * the visible attribute is set to false; therefore no render event occurs). * </p> * * @param listener the WebRenderListener to add */ public void addWebRenderListener( final WebRenderListener listener ) { WebRenderEvent.addListener( this, listener ); } /** * <p>Removes the specified WebRenderListener so that it no longer * receives render events from this WebComponent. Render events occur before * and/or after this WebComponent is rendered (note that WebComponents are * not rendered if the visible attribute is set to false; therefore no * render event occurs).</p> * * @param listener the WebRenderListener to remove */ public void removeWebRenderListener( final WebRenderListener listener ) { WebRenderEvent.removeListener( this, listener ); } /** <p>returns a reference to the {@link org.eclipse.rwt.WebContainer WebContainer} * that contains this WebComponent.</p> * * @return the parent {@link org.eclipse.rwt.WebContainer WebContainer} * of this component */ public WebContainer getParent() { return parent; } /** * <p>Returns the <code>WebForm</code> that defines the root of the * component-tree to which this component belongs to. Might be null, * if the component or one of its predecessors has no parent.</p> */ public WebForm getWebForm() { WebForm result = null; if( this instanceof WebForm ) { result = ( WebForm )this; } else if ( parent != null ) { result = parent.getWebForm(); } return result; } /** Sets the "value" of the "designTime" property. * @param designTime sets the current "value" of the "designTime" property. */ public void setDesignTime( final boolean designTime ){ if( !( this instanceof Concealer ) || ( ( getParent() != null ) && ( getParent() instanceof PanelCreator ) ) ) { this.designTime = designTime; } } /** <p>A value of true denotes that this WebComponent should behave in * design time mode, a value of false denotes runtime behavior.</p> * * @return the current value of the designTime property. */ public boolean isDesignTime() { return designTime; } /** <p>sets the name of this WebComponent.</p> * * <p>The passed String is ignored, if it is not a valid Java identifier * </p> * * <p>Note that this name is not necessarily a unique identifier for * this WebComponent. It can be set freely and might change at runtime. * It is primarily used by development tools that inspect component * trees.</p> * * <p>If you need a unique id for this WebComponent, use * {@link #getUniqueID() getUniqueId()}, which returns an identifier that * is assigned to this WebComponent by the library and is really unique * in the application (not just in the session).</p> */ public void setName( final String name ) { if( !name.equals( "" ) && isCorrectIdentifier( name ) ) { this.name = name; } } /** <p>returns the name of this WebComponent.</p> * * <p>Note that this name is not necessarily a unique identifier for * this WebComponent. It can be set freely and might change at runtime. * It is primarily used by development tools that inspect component * trees.</p> * * <p>If you need a unique id for this WebComponent, use * {@link #getUniqueID() getUniqueId()}, which returns an identifier that * is assigned to this WebComponent by the library and is really unique * in the application (not just in the session).</p> */ public String getName() { return name; } /** removes this WebComponent from its parent container */ public void remove() { if( parent != null ) { parent.remove( this ); } } /** <p>sets, whether this WebComponent is enabled (reacts on user input) * or not. A webComponent is also not enabled if it is added to a * WebContainer and the WebContainer to which it is added is * disabled.</p> */ public void setEnabled( final boolean enabled ) { this.enabled = enabled; } /** <p>returns, whether this WebComponent is enabled (reacts on user input) * or not. A webComponent is also not enabled if it is added to a * WebContainer and the WebContainer to which it is added is * disabled.</p> */ public boolean isEnabled() { boolean result = true; if( this instanceof WebForm ) { result = enabled; } else { if( enabled ) { WebContainer par = getParent(); result = ( par == null ) ? enabled : par.isEnabled(); } else { result = false; } } return result; } /** <p>sets, if this WebComponent is rendered to the WebForm.</p> */ public void setVisible( final boolean visible ) { this.visible = visible; } /** <p>returns, whether this WebComponent is rendered to the * WebForm.</p> */ public boolean isVisible() { boolean result = true; if( this instanceof WebForm ) { result = visible; } else { if( visible ) { WebContainer parent = getParent(); result = ( parent == null ) ? visible : parent.isVisible(); } else { result = false; } } return result; } /** <p>sets the event semantics that was associated with this WebComponent * in a w4t application.</p> * <p>An event semantics identifies a special purpose of an event firing * that may occur on various Components in the application. A component * may follow various event semantics at once (ids must be bitwise * or-combined in order to achieve this.</p> * <p>Event semantics ids must be defined by the application. Value 0 * signals a null semantics.</p> */ public void setEventSemanticsID( final int eventSemanticsID ) { this.eventSemanticsID = eventSemanticsID; } /** <p>returns the event semantics that was associated with this WebComponent * in a w4t application.</p> * <p>An event semantics identifies a special purpose of an event firing * that may occur on various Components in the application. A component * may follow various event semantics at once (ids must be bitwise * or-combined in order to achieve this.</p> * <p>Event semantics ids must be defined by the application. Value 0 * signals a null semantics.</p> */ public int getEventSemanticsID() { return eventSemanticsID; } /** <p>returns a path to an image that represents this WebComponent * (widget icon).</p> */ public static String retrieveIconName() { return ""; } /** <p>returns a unique identifier for this WebComponent.</p> */ public String getUniqueID() { return uniqueId; } public Object getAdapter( final Class adapter ) { Object result = null; if( adapter == IEventAdapter.class ) { //////////////////////////////////////////////////////// // Note: This is not implemented via the AdapterManager, // since the manager's mapping mechanism prevents // the component being released unless the session // is invalidated. if( eventAdapter == null ) { eventAdapter = new EventAdapter(); } result = eventAdapter; } else { result = W4TContext.getAdapterManager().getAdapter( this, adapter ); } return result; } // helping methods ////////////////// private static boolean isCorrectIdentifier( final String name ) { boolean result = Character.isJavaIdentifierStart( name.charAt ( 0 ) ); if( name.length() > 1 ) { for( int i = 0; i < name.length(); i++ ) { result &= Character.isJavaIdentifierPart( name.charAt( i ) ); } } return result; } }