/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.ui.scripting; import java.awt.Dimension; import java.awt.Point; import java.awt.Rectangle; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.HashMap; import java.util.Map; import javax.swing.JComponent; import org.mozilla.javascript.Wrapper; import com.servoy.j2db.IApplication; import com.servoy.j2db.IProvideFormName; import com.servoy.j2db.component.ComponentFactory; import com.servoy.j2db.dataprocessing.IDisplayData; import com.servoy.j2db.persistence.AbstractBase; import com.servoy.j2db.persistence.BaseComponent; import com.servoy.j2db.persistence.IPersist; import com.servoy.j2db.scripting.IScriptable; import com.servoy.j2db.ui.IComponent; import com.servoy.j2db.ui.ILabel; import com.servoy.j2db.ui.IStylePropertyChangesRecorder; import com.servoy.j2db.ui.ISupportCachedLocationAndSize; import com.servoy.j2db.ui.ISupportSecuritySettings; import com.servoy.j2db.ui.ISupportSimulateBoundsProvider; import com.servoy.j2db.ui.runtime.IRuntimeComponent; import com.servoy.j2db.util.ComponentFactoryHelper; import com.servoy.j2db.util.PersistHelper; import com.servoy.j2db.util.Utils; /** * Abstract scriptable component for {@link BaseComponent}. * * @author lvostinar * @since 6.0 */ @SuppressWarnings("nls") public abstract class AbstractRuntimeBaseComponent<C extends IComponent> implements IScriptable, IRuntimeComponent, Wrapper { private C component; private IPersist persist; private final IStylePropertyChangesRecorder jsChangeRecorder; private Map<Object, Object> clientProperties; protected final IApplication application; public AbstractRuntimeBaseComponent(IStylePropertyChangesRecorder jsChangeRecorder, IApplication application) { this.jsChangeRecorder = jsChangeRecorder; this.application = application; } /** * @return the component */ public C getComponent() { return component; } /** * @return the persist */ public IPersist getPersist() { return persist; } /** * @param component the component to set */ public void setComponent(C component, IPersist persist) { this.component = component; this.persist = persist; } public Object unwrap() { return component; } /** * @return the jsChangeRecorder */ public IStylePropertyChangesRecorder getChangesRecorder() { return jsChangeRecorder; } /** * @param propertyName * @param newValue * @param oldValue */ protected void propertyChanged(String propertyName, Object newValue, Object oldValue) { } public String getBgcolor() { return PersistHelper.createColorString(getComponent().getBackground()); } public void setBgcolor(String clr) { // always set in changesrecorder, has old value check as well getChangesRecorder().setBgcolor(clr); if (!getComponent().isOpaque()) { getChangesRecorder().setTransparent(true); } String old = getBgcolor(); if (!Utils.stringSafeEquals(old, clr)) { getComponent().setBackground(PersistHelper.createColor(clr)); propertyChanged("bgcolor", clr, old); } } public String getFgcolor() { return PersistHelper.createColorString(getComponent().getForeground()); } public void setFgcolor(String clr) { // always set in changesrecorder, has old value check as well getChangesRecorder().setFgcolor(clr); String old = getFgcolor(); if (!Utils.stringSafeEquals(old, clr)) { getComponent().setForeground(PersistHelper.createColor(clr)); propertyChanged("fgcolor", clr, old); } } public void setFont(String spec) { String old = getFont(); if (!Utils.stringSafeEquals(old, spec)) { getComponent().setFont(PersistHelper.createFont(spec)); getChangesRecorder().setFont(spec); propertyChanged("font", spec, old); } } public String getFont() { return PersistHelper.createFontString(getComponent().getFont()); } public int getWidth() { if (!sizeSet && getComponent() instanceof ISupportSimulateBoundsProvider && ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider() != null) { Rectangle bounds = ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider().getBounds(getComponent()); if (bounds != null) { return bounds.width; } } return getComponent().getSize().width; } public int getHeight() { if (!sizeSet && getComponent() instanceof ISupportSimulateBoundsProvider && ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider() != null) { Rectangle bounds = ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider().getBounds(getComponent()); if (bounds != null) { return bounds.height; } } return getComponent().getSize().height; } public boolean isVisible() { return getComponent().isVisible(); } public void setVisible(boolean b) { boolean old = isVisible(); if (b != old && (!(getComponent() instanceof ISupportSecuritySettings) || ((ISupportSecuritySettings)getComponent()).isViewable())) { getComponent().setComponentVisible(b); getChangesRecorder().setVisible(b); propertyChanged("visible", Boolean.valueOf(b), Boolean.valueOf(old)); } } public boolean isTransparent() { return !getComponent().isOpaque(); } public void setTransparent(boolean b) { boolean old = isTransparent(); if (b != old) { getComponent().setOpaque(!b); getChangesRecorder().setTransparent(b); if (!b) { // was transparent before String background = getBgcolor(); if (background != null) { // reapply background color getChangesRecorder().setBgcolor(background); } } if (getComponent() instanceof JComponent) { ((JComponent)getComponent()).repaint(); } propertyChanged("transparant", Boolean.valueOf(b), Boolean.valueOf(old)); } } public void setEnabled(final boolean b) { boolean old = isEnabled(); if (b != old) { getComponent().setComponentEnabled(b); propertyChanged("enabled", Boolean.valueOf(b), Boolean.valueOf(old)); } } public boolean isEnabled() { return getComponent().isEnabled(); } private boolean locationSet = false; private boolean sizeSet = false; public void setLocation(int x, int y) { Point newValue = new Point(x, y); Point oldValue = new Point(getLocationX(), getLocationY()); if (!newValue.equals(oldValue)) { getComponent().setLocation(newValue); getChangesRecorder().setLocation(x, y); if (getComponent() instanceof JComponent) { ((JComponent)getComponent()).validate(); } propertyChanged("location", newValue, oldValue); } if (getComponent() instanceof ISupportCachedLocationAndSize) { ((ISupportCachedLocationAndSize)getComponent()).setCachedLocation(new Point(x, y)); } locationSet = true; } protected final void setComponentSize(Dimension size) { Dimension oldSize = getComponent().getSize(); // sets the component, changes recorder is not called here if (getComponent() instanceof ISupportCachedLocationAndSize) { ((ISupportCachedLocationAndSize)getComponent()).setCachedSize(size); } getComponent().setSize(size); if (getComponent() instanceof JComponent) { ((JComponent)getComponent()).validate(); } sizeSet = true; propertyChanged("size", size, oldSize); } public String getName() { String jsName = getComponent().getName(); if (jsName != null && jsName.startsWith(ComponentFactory.WEB_ID_PREFIX)) jsName = null; return jsName; } public int getLocationX() { if (!locationSet && getComponent() instanceof ISupportSimulateBoundsProvider && ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider() != null) { Rectangle bounds = ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider().getBounds(getComponent()); if (bounds != null) { return bounds.x; } } return getComponent().getLocation().x; } public int getLocationY() { if (!locationSet && getComponent() instanceof ISupportSimulateBoundsProvider && ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider() != null) { Rectangle bounds = ((ISupportSimulateBoundsProvider)getComponent()).getBoundsProvider().getBounds(getComponent()); if (bounds != null) { return bounds.y; } } return getComponent().getLocation().y; } public void putClientProperty(Object key, Object value) { if (clientProperties == null) { clientProperties = new HashMap<Object, Object>(); } clientProperties.put(key, value); if (getComponent() instanceof JComponent) { ((JComponent)getComponent()).putClientProperty(key, value); } } public Object getClientProperty(Object key) { if (getComponent() instanceof JComponent) { return ((JComponent)getComponent()).getClientProperty(key); } if (clientProperties == null) return null; return clientProperties.get(key); } public String getBorder() { return ComponentFactoryHelper.createBorderString(getComponent().getBorder()); } public void setBorder(String spec) { String old = getBorder(); if (!Utils.stringSafeEquals(old, spec)) { getComponent().setBorder(ComponentFactoryHelper.createBorder(spec)); getChangesRecorder().setBorder(spec); propertyChanged("border", spec, old); } } public String getToolTipText() { return getComponent().getToolTipText(); } public void setToolTipText(String tooltip) { String old = getToolTipText(); if (!Utils.stringSafeEquals(old, tooltip)) { getComponent().setToolTipText(tooltip); getChangesRecorder().setChanged(); propertyChanged("toolTipText", tooltip, old); } } public String getValueString() { if (getComponent() instanceof IDisplayData) { return "value: " + ((IDisplayData)getComponent()).getValueObject(); //$NON-NLS-1$ } if (getComponent() instanceof ILabel) { return "label: " + ((ILabel)getComponent()).getText(); //$NON-NLS-1$ } return null; } /* * (non-Javadoc) * * @see com.servoy.j2db.ui.runtime.HasRuntimeDesignTimeProperty#getDesignTimeProperty(java.lang.String) */ public Object getDesignTimeProperty(String key) { if (getPersist() instanceof AbstractBase) { return Utils.parseJSExpression(((AbstractBase)getPersist()).getCustomDesignTimeProperty(key)); } return null; } public String toString(String valueString) { if (getComponent() == null) { return "ScriptObject (component not yet set): " + getClass(); //$NON-NLS-1$ } return getElementType() + "[name:" + getName() + ",x:" + getLocationX() + ",y:" + getLocationY() + ",width:" + getWidth() + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ ",height:" + getHeight() + (valueString == null ? "" : (',' + valueString)) + ']'; //$NON-NLS-1$ //$NON-NLS-2$ } @Override public String toString() { return getClass().getSimpleName(); } private PropertyChangeSupport changeSupport; public void addPropertyChangeListener(PropertyChangeListener listener) { synchronized (this) { if (listener == null) { return; } if (changeSupport == null) { changeSupport = new PropertyChangeSupport(this); } changeSupport.addPropertyChangeListener(listener); } } public void removePropertyChangeListener(PropertyChangeListener listener) { synchronized (this) { if (listener == null || changeSupport == null) { return; } changeSupport.removePropertyChangeListener(listener); } } protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { PropertyChangeSupport changeSupport; synchronized (this) { changeSupport = this.changeSupport; } if (changeSupport == null || (oldValue != null && newValue != null && oldValue.equals(newValue))) { return; } changeSupport.firePropertyChange(propertyName, oldValue, newValue); } @SuppressWarnings("cast") public String getFormName() { if (application instanceof IProvideFormName) { return ((IProvideFormName)application).getFormNameFor(component); } return null; } @Override public void addStyleClass(String styleName) { //only implemented in ngclient } @Override public void removeStyleClass(String styleName) { //only implemented in ngclient } }