001: /*
002: * Beryl - A web platform based on XML, XSLT and Java
003: * This file is part of the Beryl XML GUI
004: *
005: * Copyright (C) 2004 Wenzel Jakob <wazlaf@tigris.org>
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011:
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-3107 USA
020: */
021:
022: package org.beryl.gui.widgets;
023:
024: import java.awt.Color;
025: import java.awt.Component;
026:
027: import javax.swing.JScrollPane;
028: import javax.swing.event.ListSelectionEvent;
029: import javax.swing.event.ListSelectionListener;
030:
031: import org.beryl.gui.GUIEvent;
032: import org.beryl.gui.GUIEventListener;
033: import org.beryl.gui.GUIException;
034: import org.beryl.gui.Widget;
035: import org.beryl.gui.WidgetInfo;
036: import org.beryl.gui.model.ListDataModel;
037: import org.beryl.gui.model.MapChangeEvent;
038: import org.beryl.gui.model.MapDataModel;
039: import org.beryl.gui.model.ModelChangeEvent;
040: import org.beryl.gui.swing.JIconView;
041:
042: public class IconView extends Widget {
043: protected static WidgetInfo iconViewInfo = null;
044: private JIconView iconView = null;
045: private JScrollPane scrollPane = null;
046: private ListDataModel listDataModel = null;
047: private String indexKey = null, valueKey = null;
048: private boolean sendEvents = true;
049: private boolean processEvents = true;
050:
051: static {
052: iconViewInfo = new WidgetInfo(IconView.class, widgetInfo);
053: iconViewInfo.addProperty("indexkey", "");
054: iconViewInfo.addProperty("valuekey", "");
055: };
056:
057: public IconView(Widget parent, String name) throws GUIException {
058: super (parent, name);
059: JIconView.initialize();
060: iconView = new JIconView();
061: iconView.setBackground(Color.white);
062: scrollPane = new JScrollPane(iconView);
063: iconView.addListSelectionListener(new ListSelectionListener() {
064: public void valueChanged(ListSelectionEvent e) {
065: int index = e.getFirstIndex();
066: MapDataModel model = getDataModel();
067: try {
068: if (!e.getValueIsAdjusting() && sendEvents) {
069: try {
070: sendEvents = false;
071: processEvents = false;
072:
073: if (indexKey != null)
074: model.setValue(indexKey, new Integer(
075: index));
076: if (valueKey != null)
077: model
078: .setValue(
079: valueKey,
080: index != -1 ? listDataModel
081: .getValue(index)
082: : null);
083: } finally {
084: sendEvents = true;
085: processEvents = true;
086: }
087: }
088: } catch (GUIException ex) {
089: throw new RuntimeException(ex);
090: }
091: }
092: });
093: }
094:
095: public void addListener(String event, final String name,
096: final GUIEventListener listener) throws GUIException {
097: if ("selected".equals(event)) {
098: iconView
099: .addListSelectionListener(new ListSelectionListener() {
100: public void valueChanged(ListSelectionEvent e) {
101: int index = e.getFirstIndex();
102: listener.eventOccured(new GUIEvent(
103: IconView.this , name, e));
104: }
105: });
106: } else {
107: super .addListener(event, name, listener);
108: }
109: }
110:
111: public void setProperty(String name, Object value)
112: throws GUIException {
113: if ("indexkey".equals(name)) {
114: indexKey = (String) value;
115: } else if ("valuekey".equals(name)) {
116: valueKey = (String) value;
117: } else {
118: super .setProperty(name, value);
119: }
120: }
121:
122: public void addChild(Widget widget, Object constraint)
123: throws GUIException {
124: if (widget instanceof Item) {
125: try {
126: if (listDataModel == null) {
127: listDataModel = new ListDataModel();
128: sendEvents = false;
129: iconView.setModel(new List.ListDataModelAdapter(
130: listDataModel));
131: }
132: listDataModel.addValue(this , widget);
133: addChild(widget);
134: } finally {
135: sendEvents = true;
136: }
137: } else {
138: throw new GUIException(
139: "Only Item children are allowed inside an IconView");
140: }
141: }
142:
143: public void removeChildWidget(Widget widget) throws GUIException {
144: if (listDataModel != null) {
145: listDataModel.removeValue(this , widget);
146: super .removeChildWidget(widget);
147: } else {
148: throw new GUIException(
149: "There are no static items to remove");
150: }
151: }
152:
153: public void setListDataModel(ListDataModel listDataModel)
154: throws GUIException {
155: ModelChangeEvent event = new ModelChangeEvent(this ,
156: listDataModel);
157: this .listDataModel = listDataModel;
158: sendEvents = false;
159: try {
160: iconView.setModel(new List.ListDataModelAdapter(
161: listDataModel));
162: } finally {
163: sendEvents = true;
164: }
165: /* Reload data model information */
166: modelChanged(event);
167: }
168:
169: private void setSelectionValue(Object value) {
170: if (value == null)
171: iconView.setSelectedIndex(-1);
172: else
173: iconView.setSelectedIndex(listDataModel.indexOf(value));
174: }
175:
176: private void setSelectionIndex(Integer index) {
177: if (index == null)
178: iconView.setSelectedIndex(-1);
179: else
180: iconView.setSelectedIndex(index.intValue());
181: }
182:
183: private void reload() throws GUIException {
184: MapDataModel model = getDataModel();
185: if (model != null) {
186: try {
187: processEvents = false;
188:
189: Integer index = indexKey == null ? null
190: : (Integer) model.getValue(indexKey);
191: Object value = valueKey == null ? null : model
192: .getValue(valueKey);
193:
194: if (index != null) {
195: setSelectionIndex(index);
196: } else if (value != null) {
197: setSelectionValue(value);
198: }
199:
200: if (((value != null && index == null) || (value == null && index == null))
201: && indexKey != null) {
202: model.setValue(IconView.this , indexKey,
203: new Integer(iconView.getSelectedIndex()));
204: }
205:
206: if (((index != null && value == null) || (value == null && index == null))
207: && valueKey != null) {
208: value = index.intValue() != -1 ? listDataModel
209: .getValue(index.intValue()) : null;
210: model.setValue(IconView.this , valueKey, value);
211: }
212: } finally {
213: processEvents = true;
214: }
215: }
216: }
217:
218: public void modelChanged(ModelChangeEvent e) throws GUIException {
219: if (processEvents) {
220: try {
221: sendEvents = false;
222: if (e.getSource() == this ) {
223: try {
224: reload();
225: } catch (IllegalArgumentException ex) {
226: /* Ignore, list data model is not yet set */
227: } catch (ArrayIndexOutOfBoundsException ex) {
228: /* Ignore, list data model is not yet set */
229: }
230: } else if (e instanceof MapChangeEvent) {
231: MapChangeEvent event = (MapChangeEvent) e;
232: if (event.getKey() == null) {
233: reload();
234: } else if (event.getKey().equals(indexKey)) {
235: setSelectionIndex((Integer) event.getNewValue());
236: try {
237: processEvents = false;
238: int index = iconView.getSelectedIndex();
239: if (valueKey != null)
240: ((MapDataModel) event.getModel())
241: .setValue(
242: IconView.this ,
243: valueKey,
244: index != -1 ? listDataModel
245: .getValue(index)
246: : null);
247: } finally {
248: processEvents = true;
249: }
250: } else if (event.getKey().equals(valueKey)) {
251: setSelectionValue(event.getNewValue());
252: try {
253: processEvents = false;
254: if (indexKey != null)
255: ((MapDataModel) event.getModel())
256: .setValue(
257: IconView.this ,
258: indexKey,
259: new Integer(
260: iconView
261: .getSelectedIndex()));
262: } finally {
263: processEvents = true;
264: }
265: }
266: }
267: } finally {
268: sendEvents = true;
269: }
270: }
271: }
272:
273: public Component getWidget() {
274: return scrollPane;
275: }
276:
277: public Component getRealWidget() {
278: return iconView;
279: }
280:
281: public WidgetInfo getWidgetInfo() {
282: return iconViewInfo;
283: }
284: }
|