AbstractComponent.java :  » Web-Framework » ThinWire » thinwire » ui » Java Open Source

Java Open Source » Web Framework » ThinWire 
ThinWire » thinwire » ui » AbstractComponent.java
/*
#IFNDEF ALT_LICENSE
                           ThinWire(R) RIA Ajax Framework
                 Copyright (C) 2003-2007 Custom Credit Systems

  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., 59
  Temple Place, Suite 330, Boston, MA 02111-1307 USA

  Users who would rather have a commercial license, warranty or support should
  contact the following company who invented, built and supports the technology:
  
                Custom Credit Systems, Richardson, TX 75081, USA.
                 email: info@thinwire.com    ph: +1 (888) 644-6405
                           http://www.thinwire.com
#ENDIF
 [ v1.2_RC2 ] 
*/
package thinwire.ui;

import thinwire.render.Renderer;
import thinwire.ui.event.ActionEvent;
import thinwire.ui.event.ActionListener;
import thinwire.ui.event.DropEvent;
import thinwire.ui.event.DropListener;
import thinwire.ui.event.KeyPressEvent;
import thinwire.ui.event.PropertyChangeListener;
import thinwire.ui.event.KeyPressListener;
import thinwire.ui.style.*;

/**
 * @author Joshua J. Gertzen
 */
abstract class AbstractComponent implements Component {
    
    Application app;
    private Object parent;
    private Label label;
    private Style style;
    private EventListenerImpl<PropertyChangeListener> pcei;
    private EventListenerImpl<ActionListener> aei;
    private EventListenerImpl<DropListener> dei;
    private EventListenerImpl<KeyPressListener> kpei;
    private Object userObject;
    private boolean focusCapable = true;
    private boolean focus;
    private boolean enabled = true;
    private int x;
    private int y;
    private int width;
    private int height;
    private Object limit;
    private boolean visible;
    private boolean ignoreFirePropertyChange;
    
    AbstractComponent() {
        this(EventListenerImpl.ACTION_VALIDATOR);
    }
    
    AbstractComponent(EventListenerImpl.SubTypeValidator actionValidator) {
        this.visible = true;
        app = Application.current();
        
        EventListenerImpl<PropertyChangeListener> gpcei;
        EventListenerImpl<ActionListener> gaei;
        EventListenerImpl<DropListener> gdei;
        EventListenerImpl<KeyPressListener> gkpei;
        
        if (app == null) {
          gpcei = null;
          gaei = null;
          gdei = null;
          gkpei = null;
        } else {
          gpcei = app.getGlobalListenerSet(PropertyChangeListener.class, false);
          gaei = app.getGlobalListenerSet(ActionListener.class, false);
          gdei = app.getGlobalListenerSet(DropListener.class, false);
          gkpei = app.getGlobalListenerSet(KeyPressListener.class, false);
        }
        
        pcei = new EventListenerImpl<PropertyChangeListener>(this, PropertyChangeListener.class, null, gpcei);
        aei = new EventListenerImpl<ActionListener>(this, ActionListener.class, actionValidator, gaei);
        dei = new EventListenerImpl<DropListener>(this, DropListener.class, null, gdei);
        kpei = new EventListenerImpl<KeyPressListener>(this, KeyPressListener.class, EventListenerImpl.KEY_PRESS_VALIDATOR, gkpei);
            
        this.style = new Style(Application.getDefaultStyle(this.getClass()), this) {
            protected void firePropertyChange(Object source, String propertyName, Object oldValue, Object newValue) {
                AbstractComponent.this.firePropertyChange(source, propertyName, oldValue, newValue);
            }
        };
    }
        
    void setRenderer(Renderer r) {
        pcei.setRenderer(r);
        aei.setRenderer(r);
        dei.setRenderer(r);
        kpei.setRenderer(r);                
    }
    
    String getStandardPropertyUnsupportedMsg(String propertyName, boolean read) {
        return this.getClass().getName() + " does not support " + (read ? "reading from" : "writing to") + " the property: " + propertyName;
    }

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
        pcei.addListener(propertyName, listener);
    }
    
    public void addPropertyChangeListener(String[] propertyNames, PropertyChangeListener listener) {
        pcei.addListener(propertyNames, listener);
    }
    
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcei.removeListener(listener);
    }

    protected final boolean firePropertyChange(Object source, String propertyName, int oldValue, int newValue) {
        if (oldValue == newValue) return false;
        if (ignoreFirePropertyChange) return true;
        pcei.firePropertyChange(source, propertyName, oldValue, newValue);            
        return true;
    }

    protected final boolean firePropertyChange(Object source, String propertyName, boolean oldValue, boolean newValue) {
        if (oldValue == newValue) return false;
        if (ignoreFirePropertyChange) return true;
        pcei.firePropertyChange(source, propertyName, oldValue, newValue);
        return true;
    }

    protected final boolean firePropertyChange(Object source, String propertyName, Object oldValue, Object newValue) {
        if (oldValue == newValue || (oldValue != null && oldValue.equals(newValue)) || (newValue != null && newValue.equals(oldValue))) return false;
        if (ignoreFirePropertyChange) return true;
        pcei.firePropertyChange(source, propertyName, oldValue, newValue);        
        return true;
    }

    public void addActionListener(String action, ActionListener listener) {
        aei.addListener(action, listener);
    }
    
    public void addActionListener(String[] actions, ActionListener listener) {
        aei.addListener(actions, listener);
    }    
    
    public void removeActionListener(ActionListener listener) {
        aei.removeListener(listener);
    }

    public void fireAction(ActionEvent ev) {
        aei.fireAction(ev);
    }

    public void fireAction(String action) {
        fireAction(new ActionEvent(action, this));
    }
    
    public void fireAction(String action, Object source) {
        fireAction(new ActionEvent(action, this, source));
    }
    
    public void addDropListener(Component dragComponent, DropListener listener) {
        dei.addListener(dragComponent, listener);
    }
    
    public void addDropListener(Component[] dragComponents, DropListener listener) {
        dei.addListener(dragComponents, listener);
    }    
    
    public void removeDropListener(DropListener listener) {
        dei.removeListener(listener);
    }    

    public void fireDrop(DropEvent ev) {
        dei.fireDrop(ev);
    }
    
    public void fireDrop(Component dragComponent) {
        fireDrop(new DropEvent(this, dragComponent));
    }
    
    public void fireDrop(Component dragComponent, Object dragObject) {
        fireDrop(new DropEvent(this, null, dragComponent, dragObject));
    }
        
    public void addKeyPressListener(String keyPressCombo, KeyPressListener listener) {
        kpei.addListener(keyPressCombo, listener);
    }
    
    public void addKeyPressListener(String[] keyPressCombos, KeyPressListener listener) {
        kpei.addListener(keyPressCombos, listener);
    }
    
    public void removeKeyPressListener(KeyPressListener listener) {
        kpei.removeListener(listener);
    }
    
    public void fireKeyPress(KeyPressEvent ev) {
        kpei.fireKeyPress(ev);
    }
    
    public void fireKeyPress(String keyPressCombo) {
        fireKeyPress(new KeyPressEvent(keyPressCombo, this));
    }
    
    public Object getParent() {
        return parent;
    }
    
    void setParent(Object parent) {
        this.parent = parent;
    }    
    
    public Container getContainer() {
        Container c = null;        
        Object o = this.getParent();
        
        while (o != null) {
            if (o instanceof Container) {
                c = (Container)o;
                break;
            } else if (o instanceof Component) {
                o = ((Component)o).getParent();
            } else if (o instanceof GridBox.Row) {
                o = ((GridBox.Row)o).getParent();
            } else {
                throw new IllegalStateException("No known method of getting the parent for class '" + o.getClass() + "'");
            }
        }
        
        return c;
    }
    
    public Label getLabel() {
        return label;
    }    
    
    void setLabel(Label label) {
        this.label = label;
    }    
    
    public Object getUserObject() {
        return userObject;
    }
    
    public void setUserObject(Object userObject) {
        Object oldUserObject = this.userObject;
        this.userObject = userObject;
        firePropertyChange(this, PROPERTY_USER_OBJECT, oldUserObject, userObject);        
    }

    public boolean isEnabled() {
        return this.enabled;
    }

    public void setEnabled(boolean enabled) {
        boolean oldEnabled = this.enabled;
        this.enabled = enabled;
        firePropertyChange(this, PROPERTY_ENABLED, oldEnabled, enabled);
    }

    public boolean isFocusCapable() {
        return focusCapable;
    }
    
    public void setFocusCapable(boolean focusCapable) {
        boolean oldFocusCapable = this.focusCapable;
        this.focusCapable = focusCapable;
        firePropertyChange(this, PROPERTY_FOCUS_CAPABLE, oldFocusCapable, focusCapable);
    }
       
    public final boolean isFocus() {
        return focus;
    }

    public void setFocus(boolean focus) {
        if (!this.isFocusCapable()) throw new IllegalStateException(this.getClass().getSimpleName() + ": !this.isFocusCapable()");
            
        if (parent instanceof Container || parent == null) {
            if (this.focus == focus) return;
            
            if (focus) {
              
              // Determine if the component is a new container (a container that has just been given focus by application code
              //  or has a component thet has focus, but hasn't yet been rendered)
              boolean newContainer = false;
              if (this instanceof Container) {
                Container cont = (Container) this;
                Component cwf = cont.getChildWithFocus();
                
                while (cwf != null && cwf instanceof Container) cwf = ((Container) cwf).getChildWithFocus();
                if (cwf == null || !cwf.equals(cont.getComponentWithFocus())) newContainer = true;
              }
              
                if ((parent != null && (!(this instanceof Container) || newContainer)) || (this instanceof Dialog && newContainer)) {
                    Container container = parent != null ? (Container)parent : app.getFrame();                    
                    Component childWithFocus = container.getChildWithFocus();
                    
                    while (childWithFocus == null) {
                        container = (Container)container.getParent();
                        if (container == null) break;
                        childWithFocus = container.getChildWithFocus();
                    }

                    if (childWithFocus != null) childWithFocus.setFocus(false);
                }
                
            firePropertyChange(this, PROPERTY_FOCUS, this.focus, this.focus = true);
            
            if (parent != null || this instanceof Dialog) {
                    AbstractContainer container = parent != null ? (AbstractContainer)parent : app.getFrame();
                    container.setChildWithFocus(this);
                    if (app == null || !container.equals(app.getFrame())) container.setFocus(true);
            }
            } else {
              app.setPriorFocus(this);
              // We need to walk down the containment hierarchy nulling out the childWithFocus property
              //  and setting each component's focus property to false, until we reach the final component
              if (this instanceof Container) {
                Component childWithFocus = ((Container)this).getChildWithFocus();                      
                    if (childWithFocus != null) {
                      ((AbstractContainer) this).setChildWithFocus(null);
                      childWithFocus.setFocus(false);
                    }
              } else if (parent != null) {
                AbstractContainer container = (AbstractContainer)parent;
                    Component childWithFocus = container.getChildWithFocus();
                    if (this.equals(childWithFocus)) container.setChildWithFocus(null);
              }
              
              firePropertyChange(this, PROPERTY_FOCUS, this.focus, this.focus = false);
            }
        } else
            throw new UnsupportedOperationException("the property 'focus' is not supported by " + this.getClass());
    }
    
    public Style getStyle() {
        return style;
    }
           
    private void rangeCheck(String propertyName, int value, int min, int max) {
        if (value < min || value >= max) throw new IllegalArgumentException(propertyName + " < " + min + " || " + propertyName + " >= " + max);
    }
    
    public int getX() {
        return x;
    }

    public void setX(int x) {
        rangeCheck(PROPERTY_X, x, Short.MIN_VALUE, Short.MAX_VALUE);
        int oldX = this.x;
        this.x = x;
        firePropertyChange(this, PROPERTY_X, oldX, x);
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        rangeCheck(PROPERTY_Y, y, Short.MIN_VALUE, Short.MAX_VALUE);
        int oldY = this.y;
        this.y = y;
        firePropertyChange(this, PROPERTY_Y, oldY, y);
    }
        
    public Component setPosition(int x, int y) {
        rangeCheck(PROPERTY_X, x, Short.MIN_VALUE, Short.MAX_VALUE);
        rangeCheck(PROPERTY_Y, y, Short.MIN_VALUE, Short.MAX_VALUE);
        int oX = -1, oY = -1;
        boolean error = false;
        
        try {
            oX = getX();
            oY = getY();
            ignoreFirePropertyChange = true;
            setX(x);
            setY(y);
        } catch (RuntimeException e) {
            error = true;
            throw e;
        } finally {            
            if (error) {
                if (oX != -1 && oY != -1) {                    
                    setX(oX);
                    setY(oY);
                }
                
                ignoreFirePropertyChange = false;
            } else {
                ignoreFirePropertyChange = false;
                firePropertyChange(this, PROPERTY_X, oX, x);
                firePropertyChange(this, PROPERTY_Y, oY, y);                
            }
        }
        
        return this;
    }    

    public int getWidth() {
        return width;
    }

    public void setWidth(int width) {
        rangeCheck(PROPERTY_WIDTH, width, 0, Short.MAX_VALUE);
        int oldWidth = this.width;
        this.width = width;
        firePropertyChange(this, PROPERTY_WIDTH, oldWidth, width);
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        rangeCheck(PROPERTY_HEIGHT, height, 0, Short.MAX_VALUE);
        int oldHeight = this.height;
        this.height = height;
        firePropertyChange(this, PROPERTY_HEIGHT, oldHeight, height);
    }
    
    public Component setSize(int width, int height) {
        rangeCheck(PROPERTY_WIDTH, width, 0, Short.MAX_VALUE);
        rangeCheck(PROPERTY_HEIGHT, height, 0, Short.MAX_VALUE);
        int oWidth = -1, oHeight = -1;
        boolean error = false;
        
        try {
            oWidth = getWidth();
            oHeight = getHeight();
            ignoreFirePropertyChange = true;
            setWidth(width);
            setHeight(height);
        } catch (RuntimeException e) {
            error = true;
            throw e;
        } finally {            
            if (error) {
                if (oWidth != -1 && oHeight != -1) {                    
                    setWidth(oWidth);
                    setHeight(oHeight);
                }
                
                ignoreFirePropertyChange = false;
            } else {
                ignoreFirePropertyChange = false;
                firePropertyChange(this, PROPERTY_WIDTH, oWidth, width);
                firePropertyChange(this, PROPERTY_HEIGHT, oHeight, height);                
            }
        }
        
        return this;
    }
    
    public Component setBounds(int x, int y, int width, int height) {
        rangeCheck(PROPERTY_X, x, Short.MIN_VALUE, Short.MAX_VALUE);
        rangeCheck(PROPERTY_Y, y, Short.MIN_VALUE, Short.MAX_VALUE);
        rangeCheck(PROPERTY_WIDTH, width, 0, Short.MAX_VALUE);
        rangeCheck(PROPERTY_HEIGHT, height, 0, Short.MAX_VALUE);
        int oX = -1, oY = -1, oWidth = -1, oHeight = -1;
        boolean error = false;
        
        try {
            oX = getX();
            oY = getY();
            oWidth = getWidth();
            oHeight = getHeight();
            ignoreFirePropertyChange = true;
            setX(x);
            setY(y);
            setWidth(width);
            setHeight(height);
        } catch (RuntimeException e) {
            error = true;
            throw e;
        } finally {            
            if (error) {
                if (oX != -1 && oY != -1 && oWidth != -1 && oHeight != -1) {                    
                    setX(oX);
                    setY(oY);
                    setWidth(oWidth);
                    setHeight(oHeight);
                }
                
                ignoreFirePropertyChange = false;
            } else {
                ignoreFirePropertyChange = false;
                firePropertyChange(this, PROPERTY_X, oX, x);
                firePropertyChange(this, PROPERTY_Y, oY, y);                
                firePropertyChange(this, PROPERTY_WIDTH, oWidth, width);
                firePropertyChange(this, PROPERTY_HEIGHT, oHeight, height);                
            }
        }
        return this;
    }
    
    public Object getLimit() {
        return limit;
    }
    
    public Component setLimit(Object limit) {
        Object oldLimit = this.limit;
        this.limit = limit;
        firePropertyChange(this, PROPERTY_LIMIT, oldLimit, limit);
        return this;
    }
    
    public boolean isVisible() {
        return visible;
    }
    
    public void setVisible(boolean visible) {
        boolean oldVisible = this.visible;
        this.visible = visible;
        firePropertyChange(this, PROPERTY_VISIBLE, oldVisible, visible);
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.