/* * Copyright (c) 2003,2009 Declarative Engineering LLC. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Declarative Engineering LLC * verson 1 which accompanies this distribution, and is available at * http://declarativeengineering.com/legal/DE_Developer_License_v1.txt */ package com.foundation.tcv.swt.server; import com.common.comparison.Comparator; import com.foundation.view.*; import com.foundation.view.resource.ResourceReference; import com.foundation.tcv.model.LinkInfo; import com.foundation.tcv.swt.*; import com.foundation.tcv.view.*; public class Button extends Component implements IButton { /** Called when the button is pressed (only used for push buttons). */ private IMethodAssociation selectionMethod = null; /** The button's selection state resource. */ private SingleResourceAssociation selection = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_OBJECT, true, Boolean.FALSE); /** The button's text resource. */ private SingleResourceAssociation text = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_TEXT, false, ""); /** The button's image resource. */ private SingleResourceAssociation image = new SingleResourceAssociation(this, this, getViewContext(), SingleResourceAssociation.TYPE_IMAGE, false, null); /** The optional object that represents a selection of this button. Used for radio buttons only - to allow them to work on the same attribute. Never used for the linkages. */ private Object selectionData = null; /** Whether the button's selection state (for check boxes and the like) should be synchronized by the client when changed. */ private boolean autoSynchronizeSelection = false; /** The delay to be used when auto synchronizing changes to the text. */ private long autoSynchronizeSelectionDelay = 500; /** Whether the view should be disabled while a selection event is processed. */ private boolean blockOnSelection = false; /** Whether this is a stateful button. */ private final boolean isStateful; /** Whether this is a radio button. */ private final boolean isRadio; /** Whether this is a push button. */ private final boolean isPush; /** Whether the validation code in the view controller should be executed after synchronizing the state. */ private boolean autoValidate = false; /** * Button constructor. * @param parent A composite control which will be the parent of the new instance (cannot be null). * @param name The unique component name. * @param style The style of control to construct. * @see #STYLE_ARROW * @see #STYLE_CHECK * @see #STYLE_PUSH * @see #STYLE_RADIO * @see #STYLE_TOGGLE * @see #STYLE_FLAT * @see #STYLE_LEFT * @see #STYLE_RIGHT * @see #STYLE_CENTER * @see #STYLE_UP * @see #STYLE_DOWN */ public Button(IAbstractContainer parent, String name, int style) { super(parent, name, style); isRadio = (style & STYLE_RADIO) > 0; isStateful = isRadio || ((style & STYLE_TOGGLE) > 0) || ((style & STYLE_CHECK) > 0); isPush = !isStateful; //Initialize the client component.// sendMessage(MESSAGE_INITIALIZE, null, null, ((AbstractComponent) parent).getNumber(), style); //Don't set a delay for standard push buttons.// sendMessage(MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY, new Long((((style & STYLE_CHECK) > 0) || ((style & STYLE_RADIO) > 0) || ((style & STYLE_TOGGLE) > 0)) ? 500 : 0)); }//Button()// /** * Gets the optional selection data for the radio button (radio only). * @return The data to use to determine whether this button is selected (within the group of radio buttons) and to pass to the model when selected. */ public Object getSelectionData() { verifyThread(); return selectionData; }//getSelectionData()// /** * Sets the optional selection data for the radio button (radio only). * @param selectionData The data to use to determine whether this button is selected (within the group of radio buttons) and to pass to the model when selected. */ public void setSelectionData(Object selectionData) { verifyThread(); if(isRadio && !isInitialized()) { this.selectionData = selectionData; }//if// }//setSelectionData()// /** * Sets an association container used to access the text. * @param container The text association metadata. */ public void setTextAssociation(SingleAssociationContainer container) { verifyThread(); this.text.setAssociations(container); }//setTextAssociation()// /** * Sets an association container used to access the image. * @param container The image association metadata. */ public void setImageAssociation(SingleAssociationContainer container) { verifyThread(); this.image.setAssociations(container); }//setImageAssociation()// /** * Sets an association container used to access the selection. * @param container The selection association metadata. */ public void setSelectionAssociation(SingleAssociationContainer container) { verifyThread(); this.selection.setAssociations(container); }//setSelectionAssociation()// /** * Adds a link for the selection. * @param link The local linkage for the selection. */ public void addSelectionLink(LinkData link) { sendMessage(MESSAGE_ADD_SELECTION_LINK, new LinkInfo(((AbstractComponent) link.getComponent()).getNumber(), link.getTarget(), link.getData(), link.isBoolean(), link.invertLogic(), link.nullValue())); }//addSelectionLink()// /** * Sets the component text. * @param text The text that will appear in the component. */ public void setText(String text) { verifyThread(); this.text.setDefaultValue(text); }//setText()// /** * Sets the component's default text resource. * @param text The text to be displayed by this component. */ public void setText(ResourceReference text) { verifyThread(); this.text.setDefaultValue(text); }//setText()// /** * Sets the component image. * @param image The image to be displayed by the component. */ public void setImage(JefImage image) { verifyThread(); this.image.setDefaultValue(image); }//setImage()// /** * Sets the component's default image resource. * @param image The image to be displayed by this component. */ public void setImage(ResourceReference image) { verifyThread(); this.image.setDefaultValue(image); }//setImage()// /** * Gets the component selection state. * @return Whether the component is in the selected state. */ public Boolean getIsSelected() { verifyThread(); return (Boolean) selection.getValue(); }//getIsSelected()// /** * Sets the component default selection state. * @param isSelected Whether the component is in the selected state. */ public void setIsSelected(Boolean isSelected) { verifyThread(); if(isStateful) { selection.setDefaultValue(isSelected); }//if// }//setIsSelected()// /** * Sets the selection method called when the button is pressed (intended for push buttons). * @param selectionMethod The method called when the button is selected. */ public void setSelectionMethod(IMethodAssociation selectionMethod) { verifyThread(); if(isPush) { this.selectionMethod = selectionMethod; sendMessage(MESSAGE_SET_BLOCK_ON_SELECTIONS, selectionMethod != null ? Boolean.TRUE : Boolean.FALSE); }//if// }//setSelectionMethod()// /** * Sets whether validate routine is called after a synchronize. * @param autoValidate Whether the validation code in the view controller will be called after synchronizing the state. */ public void setAutoValidate(boolean autoValidate) { this.autoValidate = autoValidate; }//setAutoValidate()// /** * Sets whether the control auto synchronizes the selected state of the button. * @param autoSynchronizeSelection Whether the button state is automatically synchronized. */ public void setAutoSynchronizeSelection(boolean autoSynchronizeSelection) { verifyThread(); if((isStateful) && (autoSynchronizeSelection != this.autoSynchronizeSelection)) { this.autoSynchronizeSelection = autoSynchronizeSelection; //Notify the client as to whether it should auto synchronize the selection.// sendMessage(MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION, autoSynchronizeSelection ? Boolean.TRUE : Boolean.FALSE); }//if// }//setAutoSynchronizeSelection()// /** * Sets the delay for the auto synchronize selection. * @param autoSynchronizeSelectionDelay The delay in terms of milliseconds between the value of zero and ten thousand. A zero value has no delay. */ public void setAutoSynchronizeSelectionDelay(long autoSynchronizeSelectionDelay) { verifyThread(); if(autoSynchronizeSelectionDelay < 0) { autoSynchronizeSelectionDelay = 0; }//if// else if(autoSynchronizeSelectionDelay > 10000) { autoSynchronizeSelectionDelay = 10000; }//else if// if((isStateful) && (autoSynchronizeSelectionDelay != this.autoSynchronizeSelectionDelay)) { this.autoSynchronizeSelectionDelay = autoSynchronizeSelectionDelay; sendMessage(MESSAGE_SET_AUTO_SYNCHRONIZE_SELECTION_DELAY, new Long(autoSynchronizeSelectionDelay)); }//if// }//setAutoSynchronizeSelectionDelay()// /** * Sets whether the client views should be disabled while a selection event is processed. * @param blockOnSelection Whether push style buttons stop user input while processing the selection event. */ public void setBlockOnSelection(boolean blockOnSelection) { verifyThread(); if((!isStateful) && (blockOnSelection != this.blockOnSelection)) { this.blockOnSelection = blockOnSelection; sendMessage(MESSAGE_SET_BLOCK_ON_SELECTIONS, blockOnSelection ? Boolean.TRUE : Boolean.FALSE); }//if// }//setBlockOnSelection()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.AbstractComponent#internalViewInitialize() */ protected void internalViewInitialize() { super.internalViewInitialize(); text.initialize(); image.initialize(); selection.initialize(); }//internalViewInitialize()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.AbstractComponent#internalViewRelease() */ protected void internalViewRelease() { super.internalViewRelease(); text.release(); image.release(); selection.release(); }//internalViewRelease()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.AbstractComponent#internalViewRefresh() */ protected void internalViewRefresh() { super.internalViewRefresh(); internalViewRefreshSelection(); internalViewRefreshText(); internalViewRefreshImage(); }//internalViewRefresh()// /** * Refreshes the button image. */ protected void internalViewRefreshImage() { if(image.refresh()) { sendMessage(MESSAGE_SET_IMAGE, image.getValue()); }//if// }//internalViewRefreshImage()// /** * Refreshes the button text. */ protected void internalViewRefreshText() { if(text.refresh()) { sendMessage(MESSAGE_SET_TEXT, text.getValue()); }//if// }//internalViewRefreshText()// /** * Refreshes the selection. */ protected void internalViewRefreshSelection() { if(selection.refresh()) { Object value = selection.getValue(); Boolean isSelected; if(value instanceof Boolean) { isSelected = (Boolean) value; }//if// else if(selectionData != null) { isSelected = Comparator.equals(selectionData, value) ? Boolean.TRUE : Boolean.FALSE; }//else if// else { isSelected = value != null ? Boolean.TRUE : Boolean.FALSE; }//else// sendMessage(MESSAGE_SET_IS_SELECTED, isSelected); }//if// }//internalViewRefreshSelection()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.AbstractComponent#internalOnValueChanged(com.foundation.view.SingleResourceAssociation) */ protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) { if(resourceAssociation == text) { internalViewRefreshText(); }//else if// else if(resourceAssociation == image) { internalViewRefreshImage(); }//else if// else if(resourceAssociation == selection) { internalViewRefreshSelection(); }//else if// else { super.internalOnValueChanged(resourceAssociation, flags); }//else// }//internalOnValueChanged()// /* (non-Javadoc) * @see com.foundation.tcv.view.IViewComponent#processMessage(com.foundation.tcv.model.ViewMessage) */ public Object processMessage(ViewMessage viewMessage) { Object result = null; switch(viewMessage.getMessageNumber()) { case MESSAGE_VIEW_SYNCHRONIZE_SELECTION: { Boolean selectionState = (Boolean) viewMessage.getMessageData(); //Call the selection method.// if((!isStateful) && (selectionMethod != null)) { selectionMethod.invoke(null, true); }//if// //Update the selection value.// if(isStateful) { boolean isSelected = selectionState.booleanValue(); if(isRadio && isSelected) { //Only positive values are sent for radio buttons.// selection.setValue(selectionData != null ? selectionData : Boolean.TRUE); }//if// else if(!isRadio) { selection.setValue(isSelected ? Boolean.TRUE : Boolean.FALSE); }//else if// }//if// if(autoValidate) { postSynchronizeValidate(); }//if// break; }//case// default: { result = super.processMessage(viewMessage); }//default// }//switch// return result; }//processMessage()// /* (non-Javadoc) * @see com.foundation.tcv.swt.server.AbstractComponent#getClientClassName() */ protected String getClientClassName() { return "com.foundation.tcv.swt.client.Button"; }//getClientClassName()// }//Button//