/*******************************************************************************
* Copyright 2015 xWic group (http://www.xwic.de)
*
* 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.
*
*******************************************************************************/
package de.jwic.base;
import java.io.Serializable;
import java.util.Arrays;
import de.jwic.events.ValueChangedEvent;
import de.jwic.events.ValueChangedListener;
import de.jwic.util.StringTool;
/**
* Represents a field on an HTML form that contains a string value or an array
* of string values. A field is created for a control and is linked to it with
* its name.<p>
* The field offers an ValueChangedEvent.
*
* @author Florian Lippisch
* @version $Revision: 1.2 $
*/
public class Field implements Serializable {
private static final long serialVersionUID = 1L;
private String name = null;
private Control control = null;
private String[] values = null;
private ValueChangedListener[] listeners = null;
/**
* Creates a new field with an autogenerated name.
* @param parent
*/
public Field (Control parent) {
this(parent, null);
}
/**
* Creates a new field with the given name.
* @param parent
* @param name
*/
public Field (Control parent, String name) {
this.control = parent;
this.name = name;
control.addField(this);
}
/**
* Removes the field from its container.
*
*/
public void destroy() {
if (control != null) {
control.removeField(this);
}
}
/**
* Add a ValueChangedListener to this field.
* @param listener
*/
public synchronized void addValueChangedListener(ValueChangedListener listener) {
if (listeners == null) {
listeners = new ValueChangedListener[] { listener };
} else {
ValueChangedListener[] tmp = new ValueChangedListener[listeners.length + 1];
System.arraycopy(listeners, 0, tmp, 0, listeners.length);
tmp[listeners.length] = listener;
listeners = tmp;
}
}
/**
* Removes the specified listener from the field.
* @param listener
*/
public synchronized void removeValueChangedListener(ValueChangedListener listener) {
if (listeners != null && listeners.length > 0) {
ValueChangedListener[] tmp = new ValueChangedListener[listeners.length - 1];
int idx = 0;
for (int i = 0; i < listeners.length; i++) {
if (listeners[i] != listener) {
if (idx == tmp.length) {
// the listener was not registerd
return; // early exit
}
tmp[idx++] = listeners[i];
}
}
listeners = tmp;
}
}
/**
* Fires the value changed event.
* @param event
*/
protected void fireValueChangedEvent(ValueChangedEvent event) {
if (listeners != null) {
for (int i = 0; i < listeners.length; i++) {
listeners[i].valueChanged(event);
}
}
}
/**
* @return Returns the name.
*/
public String getName() {
return name;
}
/**
* @param name The name to set.
*/
void setName(String name) {
this.name = name;
}
/**
* Returns the id of the field. This property must return a unique id of
* the field that can be used to identify the field when it is submited
* by the browser.
* @return
*/
public String getId() {
return "fld_" + control.getControlID() + "." + name;
}
/**
* Returns the values as a string. If the value is an array, the values
* are seperated by a semmicolon.
* @return
*/
public String getValue() {
return StringTool.getSingleString(values);
}
/**
* Returns the values as array.
* @return Returns the values.
*/
public String[] getValues() {
return values;
}
/**
* Set the value of the field.
* @param value
*/
public void setValue(String value) {
setValues(new String[] { value });
}
/**
* Sets the values as array.
* @param values The values to set.
*/
public void setValues(String[] values) {
if (!Arrays.equals(this.values, values)) {
ValueChangedEvent event = new ValueChangedEvent(this, this.values, values);
this.values = values;
fireValueChangedEvent(event);
}
}
/**
* Set the values of the field as array without fireing the ValueChangedEvent. The
* event is added to the ValueChangedQueue for later processing.
* @param values
* @param queue
*/
public void batchUpdate(String[] newValues, ValueChangedQueue queue) {
if (!Arrays.equals(this.values, newValues)) {
ValueChangedEvent event = new ValueChangedEvent(this, this.values, newValues);
this.values = newValues;
if (listeners != null) {
queue.valueChanged(listeners, event);
}
}
}
}