/* * #%L * carewebframework * %% * Copyright (C) 2008 - 2016 Regenstrief Institute, Inc. * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This Source Code Form is also subject to the terms of the Health-Related * Additional Disclaimer of Warranty and Limitation of Liability available at * * http://www.carewebframework.org/licensing/disclaimer. * * #L% */ package org.carewebframework.shell.designer; import org.carewebframework.shell.layout.UIElementBase; import org.carewebframework.shell.property.PropertyInfo; import org.carewebframework.ui.zk.ZKUtil; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.impl.XulElement; /** * All property editors must descend from this abstract class. * * @param <T> The type of input component. */ public abstract class PropertyEditorBase<T extends XulElement> { protected final T editor; private Object value; private UIElementBase target; private PropertyInfo propInfo; /** * Create property editor using the specified template. * * @param template The template to create the editing component. */ @SuppressWarnings("unchecked") protected PropertyEditorBase(String template) { this((T) ZKUtil.loadZulPage(template, null)); } /** * Create property editor using the specified component for editing. * * @param editor The component used to edit the property. */ protected PropertyEditorBase(T editor) { this.editor = editor; editor.setHeight("80%"); editor.setWidth("95%"); ZKUtil.wireController(editor, this); } /** * Returns the component used to edit the property. * * @return The editor component. */ public XulElement getComponent() { return editor; } /** * Logic to return the value from the editor component. * * @return Value from the editor component. */ protected abstract Object getValue(); /** * Logic to set the value in the editor component. * * @param value Value for the editor component. */ protected abstract void setValue(Object value); /** * Returns true if the property value has been changed since the last commit. * * @return True if pending changes exist. */ public boolean hasChanged() { Object currentValue = getValue(); return value == null || currentValue == null ? value != currentValue : !value.equals(currentValue); } /** * Returns the PropertyInfo object associated with this editor. * * @return PropInfo object. */ public PropertyInfo getPropInfo() { return propInfo; } /** * Returns the target UI element associated with this editor. * * @return Target UI element. */ public UIElementBase getTarget() { return target; } /** * Updates the last committed value. */ public void updateValue() { value = getValue(); } /** * Sets focus to the editor component. */ public void setFocus() { editor.setFocus(true); } /** * Initializes the property editor. * * @param target The target UI element. * @param propInfo The PropertyInfo instance reflecting the property being edited on the target. * @param propGrid The property grid owning this property editor. */ protected void init(UIElementBase target, PropertyInfo propInfo, PropertyGrid propGrid) { this.target = target; this.propInfo = propInfo; editor.addForward(Events.ON_CHANGE, propGrid, Events.ON_CHANGE); editor.addForward(Events.ON_FOCUS, propGrid, Events.ON_SELECT); } /** * Commit the changed value. * * @return True if the operation was successful. */ public boolean commit() { try { setWrongValueMessage(null); propInfo.setPropertyValue(target, getValue()); updateValue(); return true; } catch (Exception e) { setWrongValueException(e); return false; } } /** * Revert changes to the property value. * * @return True if the operation was successful. */ public boolean revert() { try { setWrongValueMessage(null); setValue(propInfo.getPropertyValue(target)); updateValue(); return true; } catch (Exception e) { setWrongValueException(e); return false; } } /** * Updates the wrong value message at the client. * * @param exc The exception to display. */ public void setWrongValueException(Throwable exc) { setWrongValueMessage(ZKUtil.formatExceptionForDisplay(exc)); } /** * Updates the wrong value message at the client. * * @param message If null, any existing message is removed. Otherwise, the specified method is * displayed next to the editor component. */ public void setWrongValueMessage(String message) { if (message == null) { Clients.clearWrongValue(editor); } else { Clients.wrongValue(editor, message); } } }