📄 inputelement.java
字号:
/* InputElement.java{{IS_NOTE Purpose: Description: History: Tue Jul 5 08:49:30 2005, Created by tomyeh}}IS_NOTECopyright (C) 2005 Potix Corporation. All Rights Reserved.{{IS_RIGHT This program is distributed under GPL Version 2.0 in the hope that it will be useful, but WITHOUT ANY WARRANTY.}}IS_RIGHT*/package org.zkoss.zul.impl;import java.util.HashMap;import org.zkoss.lang.Objects;import org.zkoss.xml.HTMLs;import org.zkoss.xml.XMLs;import org.zkoss.lang.Exceptions;import org.zkoss.util.logging.Log;import org.zkoss.zk.ui.UiException;import org.zkoss.zk.ui.WrongValueException;import org.zkoss.zk.ui.util.Clients;import org.zkoss.zk.ui.ext.client.Inputable;import org.zkoss.zk.ui.ext.client.Errorable;import org.zkoss.zk.ui.event.Events;import org.zkoss.zk.ui.sys.ComponentsCtrl;import org.zkoss.zk.scripting.Namespace;import org.zkoss.zk.scripting.Namespaces;import org.zkoss.zul.mesg.MZul;import org.zkoss.zul.Constraint;import org.zkoss.zul.ClientConstraint;import org.zkoss.zul.CustomConstraint;import org.zkoss.zul.SimpleConstraint;import org.zkoss.zul.ext.Constrainted;/** * A skeletal implementation of an input box. * @author tomyeh */abstract public class InputElement extends XulElementimplements Constrainted { private static final Log log = Log.lookup(InputElement.class); /** The value. */ private Object _value; /** Used by setTextByClient() to disable sending back the value */ private String _txtByClient; /** The error message. Not null if users entered a wrong data (and * not correct it yet). */ private String _errmsg; /** The name. */ private String _name; private int _maxlength, _cols; private int _tabindex = -1; private Constraint _constr; private boolean _disabled, _readonly; /** Whether this input is validated (Feature 1461209). */ private boolean _valided; /** Returns whether it is disabled. * <p>Default: false. */ public boolean isDisabled() { return _disabled; } /** Sets whether it is disabled. */ public void setDisabled(boolean disabled) { if (_disabled != disabled) { _disabled = disabled; smartUpdate("disabled", _disabled); } } /** Returns whether it is readonly. * <p>Default: false. */ public boolean isReadonly() { return _readonly; } /** Sets whether it is readonly. */ public void setReadonly(boolean readonly) { if (_readonly != readonly) { _readonly = readonly; smartUpdate("readOnly", _readonly); } } /** Returns the name of this component. * <p>Default: null. * <p>Don't use this method if your application is purely based * on ZK's event-driven model. * <p>The name is used only to work with "legacy" Web application that * handles user's request by servlets. * It works only with HTTP/HTML-based browsers. It doesn't work * with other kind of clients. */ public String getName() { return _name; } /** Sets the name of this component. * <p>Don't use this method if your application is purely based * on ZK's event-driven model. * <p>The name is used only to work with "legacy" Web application that * handles user's request by servlets. * It works only with HTTP/HTML-based browsers. It doesn't work * with other kind of clients. * * @param name the name of this component. */ public void setName(String name) { if (name != null && name.length() == 0) name = null; if (!Objects.equals(_name, name)) { _name = name; smartUpdate("name", _name); } } /** Returns the error message that is caused when user entered * invalid value, or null if no error at all. * * <p>The error message is set when user has entered a wrong value, * or setValue is called with a wrong value. * It is cleared once a correct value is assigned. * * <p>If the error message is set, we say this input is in the error mode. * Any following invocation to {@link #getText} or getValue will throw * any exception. * Example, {@link org.zkoss.zul.Textbox#getValue} and * {@link org.zkoss.zul.Intbox#getValue}. */ public String getErrorMessage() { return _errmsg; } /** Clears the error message. * * <p>The error message is cleared automatically, so you rarely need * to call this method. * However, if a constraint depends on multiple input fields and * the error can be corrected by changing one of these fields, * then you may have to clear the error message manullay by invoking * this method. * * <p>For example, assume you have two {@link org.zkoss.zul.Intbox} * and want the value of the first one to be smaller than that of the * second one. Then, you have to call this method for the second intbox * once the validation of the first intbox succeeds, and vice versa. * Otherwise, the error message for the seoncd intbox remains if * the user fixed the error by lowering down the value of the first one * Why? The second intbox got no idea to clear the error message * (since its content doesn't change). */ public void clearErrorMessage() { if (_errmsg != null) { _errmsg = null; _valided = true; Clients.closeErrorBox(this); } } /** Returns the value in the String format. * In most case, you shall use the setValue method instead, e.g., * {@link org.zkoss.zul.Textbox#getValue} and * {@link org.zkoss.zul.Intbox#getValue}. * * <p>It invokes {@link #checkUserError} to ensure no user error. * * <p>It invokes {@link #coerceToString} to convert the stored value * into a string. * * @exception WrongValueException if user entered a wrong value */ public String getText() throws WrongValueException { checkUserError(); return coerceToString(_value); } /** Sets the value in the String format. * In most case, you shall use the setValue method instead, e.g., * {@link org.zkoss.zul.Textbox#setValue} and * {@link org.zkoss.zul.Intbox#setValue}. * * <p>It invokes {@link #coerceFromString} fisrt and then {@link #validate}. * Derives might override them for type conversion and special * validation. * * @param value the value; If null, it is considered as empty. */ public void setText(String value) throws WrongValueException { if (_maxlength > 0 && value != null && value.length() > _maxlength) throw showCustomError( new WrongValueException(this, MZul.STRING_TOO_LONG, new Integer(_maxlength))); final Object val = coerceFromString(value); validate(val); clearErrorMessage(); //no error at all if (!Objects.equals(_value, val)) { _value = val; final String fmtval = coerceToString(_value); if (_txtByClient == null || !Objects.equals(_txtByClient, fmtval)) { _txtByClient = null; //only once smartUpdate("value", fmtval); //Note: we have to disable the sending back of the value //Otherwise, it cause Bug 1488579's problem 3. //Reason: when user set a value to correct one and set //to an illegal one, then click the button cause both events } //being sent back to the server. } else if (_txtByClient != null) { //value equals but formatted result might differ because //our parse is more fault tolerant final String fmtval = coerceToString(_value); if (!Objects.equals(_txtByClient, fmtval)) { _txtByClient = null; //only once smartUpdate("value", fmtval); } } } /** Coerces the value passed to {@link #setText}. * * <p>Deriving note:<br> * If you want to store the value in other type, say BigDecimal, * you have to override {@link #coerceToString} and {@link #coerceFromString} * to convert between a string and your targeting type. * * <p>Moreover, when {@link org.zkoss.zul.Textbox} is called, it calls this method * with value = null. Derives shall handle this case properly. */ abstract protected Object coerceFromString(String value) throws WrongValueException; /** Coerces the value passed to {@link #setText}. * * <p>Default: convert null to an empty string. * * <p>Deriving note:<br> * If you want to store the value in other type, say BigDecimal, * you have to override {@link #coerceToString} and {@link #coerceFromString} * to convert between a string and your targeting type. */ abstract protected String coerceToString(Object value); /** Validates the value returned by {@link #coerceFromString}. * <p>Default: use {@link #getConstraint}'s {@link Constraint#validate}, * if not null. * <p>You rarely need to override this method. */ protected void validate(Object value) throws WrongValueException { final Constraint constr = getConstraint(); if (constr != null) { //Bug 1698190: contructor might be zscript final HashMap backup = new HashMap(); final Namespace ns = Namespaces.beforeInterpret(backup, this, true); try { constr.validate(this, value); if (constr instanceof CustomConstraint) { try { ((CustomConstraint)constr).showCustomError(this, null); //not call thru showCustomError(Wrong...) for better performance } catch (Throwable ex) { log.realCauseBriefly(ex); } } } finally { Namespaces.afterInterpret(backup, ns, true); } } } /** Shows the error message in the custom way by calling * ({@link CustomConstraint#showCustomError}, if the contraint * implements {@link CustomConstraint}. * * <p>Derived class shall call this method before throwing * {@link WrongValueException}, such that the constraint, * if any, has a chance to show the error message in a custom way. * * @param ex the exception, or null to clean up the error. * @return the exception (ex) */ protected WrongValueException showCustomError(WrongValueException ex) { if (_constr instanceof CustomConstraint) { final HashMap backup = new HashMap(); final Namespace ns = Namespaces.beforeInterpret(backup, this, true); try { ((CustomConstraint)_constr).showCustomError(this, ex); } catch (Throwable t) { log.realCause(t); //and ignore it } finally { Namespaces.afterInterpret(backup, ns, true); } } return ex; } /** Returns the maxlength. * <p>Default: 0 (non-postive means unlimited). */ public int getMaxlength() { return _maxlength; } /** Sets the maxlength. */ public void setMaxlength(int maxlength) { if (_maxlength != maxlength) { _maxlength = maxlength; invalidate(); } } /** Returns the cols. * <p>Default: 0 (non-positive means the same as browser's default). */ public int getCols() { return _cols; } /** Sets the cols. */ public void setCols(int cols) throws WrongValueException { if (cols <= 0) throw new WrongValueException("Illegal cols: "+cols); if (_cols != cols) { _cols = cols; smartUpdate("cols", Integer.toString(_cols)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -