001: /*
002: * de.jwic.controls.ListBoxControl
003: * $Id: ListControl.java,v 1.8 2007/04/03 09:35:28 cosote Exp $
004: */
005: package de.jwic.controls;
006:
007: import java.util.ArrayList;
008: import java.util.Collection;
009: import java.util.Iterator;
010: import java.util.LinkedHashMap;
011: import java.util.List;
012: import java.util.Map;
013:
014: import de.jwic.base.Control;
015: import de.jwic.base.Field;
016: import de.jwic.base.IControlContainer;
017: import de.jwic.base.Page;
018: import de.jwic.base.SessionContext;
019: import de.jwic.events.ElementSelectedEvent;
020: import de.jwic.events.ElementSelectedListener;
021: import de.jwic.events.ValueChangedEvent;
022: import de.jwic.events.ValueChangedListener;
023:
024: /**
025: * This control renders list like a list box, radio group or checkbox.
026: *
027: * @author Florian Lippisch
028: * @version $Revision: 1.8 $
029: */
030: public abstract class ListControl extends HTMLElement {
031:
032: protected Map elements = new LinkedHashMap();
033: protected boolean changeNotification = false;
034: protected List selectionListeners = null;
035: protected Field field = null;
036:
037: /**
038: * @param container
039: * @param name
040: */
041: public ListControl(IControlContainer container, String name) {
042: super (container, name);
043: init();
044: }
045:
046: /* (non-Javadoc)
047: * @see de.jwic.base.Control#init()
048: */
049: private void init() {
050:
051: field = new Field(this );
052: field.setValue("");
053:
054: field.addValueChangedListener(new ValueChangedListener() {
055: private static final long serialVersionUID = 1L;
056:
057: public void valueChanged(ValueChangedEvent event) {
058: sendElementSelectedEvent(); // transform the event.
059: }
060: });
061:
062: }
063:
064: /**
065: * Invoked when the value has been changed.
066: *
067: */
068: public void actionValuechanged() {
069: // nothing to do, as the valueChanged is triggered directly by the field.
070: // but we must leave this method as it is invoked by the onChanged event.
071: }
072:
073: /**
074: * Send the element selected event to the registerd listeners.
075: */
076: protected void sendElementSelectedEvent() {
077:
078: if (selectionListeners != null) {
079: ElementSelectedEvent e = new ElementSelectedEvent(this ,
080: getSelectedKey());
081: for (Iterator it = selectionListeners.iterator(); it
082: .hasNext();) {
083: ElementSelectedListener osl = (ElementSelectedListener) it
084: .next();
085: osl.elementSelected(e);
086: }
087: }
088:
089: }
090:
091: /**
092: * Add an element to the list where the title is used as the key.
093: * @param title
094: */
095: public void addElement(String title) {
096: addElement(title, title);
097: }
098:
099: /**
100: * Add an element to the list with a title and a seperate key.
101: * @param title
102: * @param key
103: */
104: public void addElement(String title, String key) {
105: elements.put(key, new ListEntry(title, key));
106: requireRedraw();
107: }
108:
109: /**
110: * Register a listener that will be notified when an element has been selected.
111: * @param listener
112: */
113: public void addElementSelectedListener(
114: ElementSelectedListener listener) {
115: if (selectionListeners == null) {
116: selectionListeners = new ArrayList();
117: }
118: selectionListeners.add(listener);
119: }
120:
121: /**
122: * Removes the specified listener.
123: * @param listener
124: */
125: public void removeElementSelectedListener(
126: ElementSelectedListener listener) {
127: if (selectionListeners != null) {
128: selectionListeners.remove(listener);
129: }
130: }
131:
132: /**
133: * Remove all entries from the list.
134: */
135: public void clear() {
136:
137: elements.clear();
138: field.setValue(""); // reset the key.
139: requireRedraw();
140:
141: }
142:
143: /**
144: * Returns the collection of elements.
145: * @return List of ListEntry objects.
146: */
147: public Collection getElements() {
148: return elements.values();
149: }
150:
151: /**
152: * Returns the collection of elements keys.
153: * @return
154: */
155: public Collection getElementsKeys() {
156: return elements.keySet();
157: }
158:
159: /**
160: * The field representation used by the ListControl on the HTML form.
161: * This property is used by the renderer to generate the proper HTML code.
162: * Use the <code>selectedKey</code> property to change the ListControls data.
163: * @return
164: */
165: public Field getField() {
166: return field;
167: }
168:
169: /**
170: * Returns the key of the selected element as String. If
171: * multiple elements are selected, the keys are seprated by a ';'.
172: */
173: public String getSelectedKey() {
174:
175: return field.getValue();
176:
177: }
178:
179: /**
180: * Returns the selected keys as String[].
181: * @return
182: */
183: public String[] getSelectedKeys() {
184: return field.getValues();
185: }
186:
187: /**
188: * Set the key of the selected element.
189: * @param key
190: * @return
191: */
192: public void setSelectedKey(String key) {
193: field.setValue(key);
194: requireRedraw();
195: }
196:
197: /**
198: * Returns true if the page will be submited when the value has been changed
199: * by the user.
200: * @return Returns the changeNotification.
201: */
202: public boolean isChangeNotification() {
203: return changeNotification;
204: }
205:
206: /**
207: * Set to true if the page should be submited when the value has been changed
208: * by the user.
209: * @param changeNotification boolean
210: */
211: public void setChangeNotification(boolean changeNotification) {
212: this .changeNotification = changeNotification;
213: requireRedraw();
214: }
215:
216: /**
217: * @param key the element beeing testet
218: * handle also the multiselect case
219: */
220: public boolean isKeySelected(String key) {
221: String[] selection = field.getValues();
222: for (int i = 0; i < selection.length; i++) {
223: if (key.equalsIgnoreCase(selection[i])) {
224: return true;
225: }
226: }
227: return false;
228: }
229:
230: /**
231: * Remove an element by its key. Returns the number of elements removed.
232: * @param key
233: */
234: public int removeElement(String key) {
235:
236: int count = 0;
237: String[] selection = field.getValues();
238: List newSelection = new ArrayList(selection.length);
239:
240: for (Iterator it = elements.values().iterator(); it.hasNext();) {
241: ListEntry entry = (ListEntry) it.next();
242: if (entry.key.equals(key)) {
243: it.remove();
244: count++;
245: } else {
246: if (isKeySelected(entry.key)) {
247: newSelection.add(entry.key);
248: }
249: }
250: }
251: if (newSelection.size() != selection.length) { // a selected element has been removed
252: String[] newList = new String[newSelection.size()];
253: for (int i = 0; i < newSelection.size(); i++) {
254: newList[i] = (String) newSelection.get(i);
255: }
256: field.setValues(newList);
257: }
258:
259: requireRedraw();
260: return count; // no element removed.
261: }
262:
263: /**
264: * Forces focus for this field. Returns <code>true</code> if the
265: * field Id could have been set.
266: */
267: public boolean forceFocus() {
268:
269: // Check if the current top-control is a parent of this input box.
270: // if so, force focus.
271: SessionContext context = getSessionContext();
272: Control topCtrl = context.getTopControl();
273: if (topCtrl == null) {
274: // initialization phase -> walk up the control hieracy to find a Page control
275: IControlContainer container = getContainer();
276: while (container != null
277: && !(container instanceof SessionContext)) {
278: Control ctrl = (Control) container;
279: if (ctrl instanceof Page) {
280: topCtrl = ctrl;
281: break;
282: }
283: container = ctrl.getContainer();
284: }
285: }
286: if (topCtrl != null
287: && getControlID().startsWith(
288: topCtrl.getControlID() + ".")) {
289: if (topCtrl instanceof Page) {
290: Page page = (Page) topCtrl;
291: page.setForceFocusElement(getForceFocusElement());
292: return true;
293: }
294: }
295: return false;
296: }
297:
298: /**
299: * @return Name of form element that is used to set the focus.
300: */
301: public String getForceFocusElement() {
302: return getField().getId();
303: }
304: }
|