001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package org.wings.plaf.css;
014:
015: import org.wings.SCellRendererPane;
016: import org.wings.SComponent;
017: import org.wings.SDefaultListCellRenderer;
018: import org.wings.SList;
019: import org.wings.SListCellRenderer;
020: import org.wings.util.SStringBuilder;
021: import org.wings.io.Device;
022: import org.wings.io.StringBuilderDevice;
023: import org.wings.plaf.CGManager;
024: import org.wings.plaf.Update;
025: import org.wings.script.JavaScriptEvent;
026: import org.wings.script.JavaScriptListener;
027:
028: import java.awt.Rectangle;
029: import java.io.IOException;
030: import java.util.List;
031:
032: public final class ListCG extends AbstractComponentCG<SList> implements
033: org.wings.plaf.ListCG {
034:
035: private static final long serialVersionUID = 1L;
036:
037: public void installCG(final SList list) {
038: super .installCG(list);
039: final CGManager manager = list.getSession().getCGManager();
040: Object value;
041: value = manager.getObject("SList.cellRenderer",
042: SDefaultListCellRenderer.class);
043: if (value != null) {
044: list.setCellRenderer((SDefaultListCellRenderer) value);
045: }
046: }
047:
048: protected void writeFormList(final Device device, final SList list)
049: throws IOException {
050: Object clientProperty = list
051: .getClientProperty("onChangeSubmitListener");
052: // If the application developer attached any ListSelectionListeners to this
053: // SList, the surrounding form gets submitted as soon as the state / the
054: // selection of this SList changed.
055: if (list.getListSelectionListeners().length > 0) {
056: if (clientProperty == null) {
057: String event = JavaScriptEvent.ON_CHANGE;
058: String code = "wingS.request.sendEvent(event, true, "
059: + !list.isReloadForced() + ");";
060: JavaScriptListener javaScriptListener = new JavaScriptListener(
061: event, code);
062: list.addScriptListener(javaScriptListener);
063: list.putClientProperty("onChangeSubmitListener",
064: javaScriptListener);
065: }
066: } else if (clientProperty != null
067: && clientProperty instanceof JavaScriptListener) {
068: list
069: .removeScriptListener((JavaScriptListener) clientProperty);
070: list.putClientProperty("onChangeSubmitListener", null);
071: }
072:
073: device.print("<span");
074: SStringBuilder builder = new SStringBuilder();
075: Utils.appendCSSInlineSize(builder, list);
076: if (builder.length() != 0) {
077: device.print(" style=\"");
078: device.print(builder.toString());
079: device.print("\"");
080: }
081: device.print("><select wrapping=\"1\"");
082: Utils.writeAllAttributes(device, list);
083:
084: Utils.optAttribute(device, "name", Utils.event(list));
085: Utils.optAttribute(device, "tabindex", list
086: .getFocusTraversalIndex());
087: Utils.optAttribute(device, "size", list.getVisibleRowCount());
088: Utils
089: .optAttribute(
090: device,
091: "multiple",
092: (list.getSelectionMode() == SList.MULTIPLE_SELECTION) ? "multiple"
093: : null);
094: Utils.writeEvents(device, list, null);
095:
096: if (!list.isEnabled())
097: device.print(" disabled=\"true\"");
098: if (list.isFocusOwner())
099: Utils.optAttribute(device, "foc", list.getName());
100:
101: device.print(">");
102:
103: final javax.swing.ListModel model = list.getModel();
104: final int size = model.getSize();
105: final SListCellRenderer cellRenderer = list.getCellRenderer();
106: final StringBuilderDevice stringBuilderDevice = new StringBuilderDevice(
107: 512);
108:
109: for (int i = 0; i < size; i++) {
110: SComponent renderer = null;
111: if (cellRenderer != null) {
112: renderer = cellRenderer.getListCellRendererComponent(
113: list, model.getElementAt(i), false, i);
114: }
115:
116: Utils.printNewline(device, list, 1);
117: device.print("<option");
118: Utils.optAttribute(device, "value", list
119: .getSelectionParameter(i));
120: if (list.isSelectedIndex(i)) {
121: device.print(" selected");
122: //Utils.optAttribute(device, "class", "selected");
123: }
124:
125: if (renderer != null) {
126: Utils.optAttribute(device, "style", Utils
127: .generateCSSComponentInlineStyle(renderer));
128: }
129: device.print(">");
130:
131: if (renderer != null) {
132: String tooltipText = renderer.getToolTipText();
133: renderer.setToolTipText(null);
134:
135: // Hack: remove all tags, because in form selections, looks ugly.
136: stringBuilderDevice.reset();
137: renderer.write(stringBuilderDevice);
138:
139: final int charsWritten = Utils.writeWithoutHTML(device,
140: stringBuilderDevice.toString());
141: if (charsWritten == 0) {
142: // If the option is empty ("") Firefox
143: // renders somehow smaller comboboxes!
144: device.print(" ");
145: }
146:
147: renderer.setToolTipText(tooltipText);
148: } else {
149: device.print(model.getElementAt(i).toString());
150: }
151:
152: device.print("</option>");
153: }
154:
155: Utils.printNewline(device, list);
156: device.print("</select>");
157: Utils.printNewline(device, list);
158: device.print("<input type=\"hidden\"");
159: Utils.optAttribute(device, "name", Utils.event(list));
160: Utils.optAttribute(device, "value", -1);
161: device.print("/></span>");
162: }
163:
164: public void writeAnchorList(Device device, SList list)
165: throws IOException {
166: // Remove superfluous 'onChangeSubmitListener' (in case there is any).
167: // This is because we don't want to render 'onclick' AND 'onchange'.
168: Object clientProperty = list
169: .getClientProperty("onChangeSubmitListener");
170: if (clientProperty != null
171: && clientProperty instanceof JavaScriptListener) {
172: list
173: .removeScriptListener((JavaScriptListener) clientProperty);
174: list.putClientProperty("onChangeSubmitListener", null);
175: }
176:
177: boolean renderSelection = list.getSelectionMode() != SList.NO_SELECTION;
178:
179: device.print("<");
180: device.print(list.getType());
181: Utils.optAttribute(device, "type", list.getOrderType());
182: Utils.optAttribute(device, "start", list.getStart());
183: Utils.writeAllAttributes(device, list);
184: device.print(">");
185:
186: javax.swing.ListModel model = list.getModel();
187: SListCellRenderer cellRenderer = list.getCellRenderer();
188: SCellRendererPane rendererPane = list.getCellRendererPane();
189:
190: Rectangle currentViewport = list.getViewportSize();
191: Rectangle maximalViewport = list.getScrollableViewportSize();
192: int start = 0;
193: int end = model.getSize();
194: int empty = maximalViewport != null ? maximalViewport.height
195: : end;
196:
197: if (currentViewport != null) {
198: start = currentViewport.y;
199: end = start + currentViewport.height;
200: }
201:
202: for (int i = start; i < end; ++i) {
203: if (i >= empty) {
204: device.print("<li class=\"empty\"> </li>");
205: continue;
206: }
207:
208: boolean selected = list.isSelectedIndex(i);
209:
210: if (renderSelection && selected)
211: device.print("<li class=\"selected clickable\"");
212: else
213: device.print("<li class=\"clickable\"");
214:
215: SComponent renderer = cellRenderer
216: .getListCellRendererComponent(list, model
217: .getElementAt(i), selected, i);
218:
219: if (renderSelection) {
220: Utils.printClickability(device, list, list
221: .getToggleSelectionParameter(i), true, list
222: .getShowAsFormComponent());
223: Utils.optAttribute(device, "foc", renderer.getName());
224: }
225: device.print(">");
226: rendererPane.writeComponent(device, renderer, list);
227: device.print("</li>\n");
228: }
229:
230: device.print("</");
231: Utils.write(device, list.getType());
232: device.print(">");
233: }
234:
235: @Override
236: public void writeInternal(final Device device, final SList list)
237: throws IOException {
238: if (list.getShowAsFormComponent()) {
239: writeFormList(device, list);
240: } else {
241: writeAnchorList(device, list);
242: }
243: }
244:
245: public Update getSelectionUpdate(SList list,
246: List deselectedIndices, List selectedIndices) {
247: return new SelectionUpdate(list, deselectedIndices,
248: selectedIndices);
249: }
250:
251: protected static class SelectionUpdate extends
252: AbstractUpdate<SList> {
253: private List deselectedIndices;
254: private List selectedIndices;
255:
256: public SelectionUpdate(SList component, List deselectedIndices,
257: List selectedIndices) {
258: super (component);
259: this .deselectedIndices = deselectedIndices;
260: this .selectedIndices = selectedIndices;
261: }
262:
263: public Handler getHandler() {
264: UpdateHandler handler = new UpdateHandler("selectionList");
265: handler.addParameter(component.getName());
266: handler
267: .addParameter(Utils
268: .listToJsArray(deselectedIndices));
269: handler.addParameter(Utils.listToJsArray(selectedIndices));
270: return handler;
271: }
272:
273: }
274: }
|