001: package org.osbl.client.wings.form.editor;
002:
003: import org.conform.wings.Editor;
004: import org.conform.wings.editor.ComponentInvalidator;
005: import org.conform.wings.editor.FormattedListCellRenderer;
006: import org.conform.*;
007: import org.conform.format.Format;
008: import org.wings.*;
009: import org.osbl.client.wings.XButton;
010: import org.osbl.client.wings.shell.*;
011: import org.osbl.client.wings.form.*;
012: import org.osbl.client.action.AbstractObjectAction;
013: import org.osbl.client.action.ObjectActionEvent;
014:
015: import javax.swing.*;
016: import javax.swing.event.*;
017: import java.beans.PropertyChangeListener;
018: import java.beans.PropertyChangeEvent;
019: import java.util.*;
020: import java.util.List;
021: import java.awt.*;
022: import java.awt.event.ActionEvent;
023:
024: public class ManyToManyAssociationEditor implements Editor {
025: public SComponent createComponent(PropertyMeta propertyMeta) {
026: Panel panel = new Panel(propertyMeta);
027: configureComponent(propertyMeta, panel, false);
028: return panel;
029: }
030:
031: public void configureComponent(PropertyMeta propertyMeta,
032: SComponent component, boolean erroneous) {
033: Panel panel = (Panel) component;
034: panel.setEnabled(propertyMeta.isWritable());
035: panel.setVisible(propertyMeta.isReadable());
036: }
037:
038: public void setPropertyData(SComponent component,
039: PropertyData propertyData) {
040: BeanData beanData = propertyData.getBeanData();
041: if (beanData != null)
042: beanData.addPropertyChangeListener(propertyData
043: .getPropertyMeta().getName(),
044: new ComponentInvalidator(component));
045:
046: if (component instanceof Panel) {
047: Panel panel = (Panel) component;
048: panel.setPropertyData(propertyData);
049:
050: if (beanData != null)
051: beanData.addPropertyChangeListener(propertyData
052: .getPropertyMeta().getName(), panel);
053: }
054: }
055:
056: public PropertyData getPropertyData(SComponent component) {
057: if (component instanceof Panel) {
058: Panel panel = (Panel) component;
059: return panel.getPropertyData();
060: }
061:
062: return null;
063: }
064:
065: protected static class Panel extends SContainer implements
066: PropertyChangeListener {
067: protected SList included;
068: protected SList excluded;
069: protected SButton include;
070: protected SButton exclude;
071: protected SButton manage;
072: protected PropertyData propertyData;
073: private List<? extends EditorAction> actions;
074: private IncludeExcludeModel model;
075:
076: public Panel(PropertyMeta propertyMeta) {
077: super (new SGridBagLayout());
078:
079: include = new XButton(new Panel.IncludeAction());
080: exclude = new XButton(new Panel.ExcludeAction());
081: manage = new XButton(new Panel.ManageAction());
082:
083: included = new SList();
084: included.setPreferredSize(SDimension.FULLWIDTH);
085: excluded = new SList();
086: excluded.setPreferredSize(SDimension.FULLWIDTH);
087:
088: Format format = propertyMeta.getFormat();
089: if (format != null) {
090: included.setCellRenderer(new FormattedListCellRenderer(
091: format));
092: excluded.setCellRenderer(new FormattedListCellRenderer(
093: format));
094: }
095: actions = (List<? extends EditorAction>) propertyMeta
096: .getAttribute(Editor.ACTIONS);
097: if (actions == null)
098: actions = createActions();
099:
100: for (EditorAction action : actions)
101: action.setComponent(this );
102:
103: initialize();
104: }
105:
106: protected List<? extends EditorAction> createActions() {
107: return Arrays.asList(new IncludeAction(),
108: new ExcludeAction(), new ManageAction());
109: }
110:
111: protected void initialize() {
112: GridBagConstraints constraints = new GridBagConstraints();
113: constraints.gridheight = actions.size() + 1;
114: constraints.weightx = .4;
115: constraints.gridy = 0;
116: add(included, constraints);
117: constraints.gridx = 2;
118: add(excluded, constraints);
119:
120: constraints.gridheight = 1;
121: constraints.gridx = 1;
122: constraints.weightx = .2;
123: constraints.insets = new Insets(0, 6, 6, 6);
124:
125: for (Action action : actions) {
126: add(new XButton(action), constraints);
127: constraints.gridy++;
128: }
129: add(new SLabel(), constraints);
130: }
131:
132: public PropertyData getPropertyData() {
133: return propertyData;
134: }
135:
136: public void setPropertyData(PropertyData propertyData) {
137: this .propertyData = propertyData;
138: for (EditorAction action : actions)
139: action.setPropertyData(propertyData);
140:
141: IncludeExcludeModel model = new IncludeExcludeModel(
142: propertyData);
143: model.addChangeListener(new ChangeListener() {
144: public void stateChanged(ChangeEvent e) {
145: BeanData beanData = Panel.this .propertyData
146: .getBeanData();
147: List value = getModel().getIncludedModel()
148: .getList();
149: Panel.this .propertyData.setValue(value);
150: PropertyChangeListener[] propertyChangeListeners = beanData
151: .getPropertyChangeListeners(Panel.this .propertyData
152: .getPropertyMeta().getName());
153: for (PropertyChangeListener propertyChangeListener : propertyChangeListeners) {
154: propertyChangeListener
155: .propertyChange(new PropertyChangeEvent(
156: beanData,
157: Panel.this .propertyData
158: .getPropertyMeta()
159: .getName(), value,
160: value));
161: }
162: }
163: });
164: setModel(model);
165:
166: DomainProvider domainProvider = propertyData
167: .getPropertyMeta().getDomainProvider();
168: if (domainProvider instanceof DynamicDomainProvider) {
169: ((DynamicDomainProvider) domainProvider)
170: .addChangeListener(new ChangeListener() {
171: public void stateChanged(ChangeEvent e) {
172: propertyChange(null);
173: }
174: });
175: }
176: }
177:
178: public void setEnabled(boolean enabled) {
179: included.setEnabled(enabled);
180: excluded.setEnabled(enabled);
181: for (Action action : actions) {
182: action.setEnabled(enabled);
183: }
184: }
185:
186: public void propertyChange(PropertyChangeEvent evt) {
187: getModel().refresh();
188: }
189:
190: public void setModel(IncludeExcludeModel model) {
191: this .model = model;
192: included.setModel(model.getIncludedModel());
193: excluded.setModel(model.getExcludedModel());
194: }
195:
196: public IncludeExcludeModel getModel() {
197: return model;
198: }
199:
200: protected class IncludeAction extends AbstractEditorAction {
201: public IncludeAction() {
202: putValue(Action.ACTION_COMMAND_KEY, ".buttons.include");
203: }
204:
205: public void actionPerformed(ActionEvent e) {
206: Object[] objects = ((Panel) getComponent()).excluded
207: .getSelectedValues();
208: for (int i = 0; i < objects.length; i++) {
209: Object object = objects[i];
210: ((Panel) getComponent()).getModel().include(object);
211: }
212: excluded.clearSelection();
213: }
214: }
215:
216: protected class ExcludeAction extends AbstractEditorAction {
217: public ExcludeAction() {
218: putValue(Action.ACTION_COMMAND_KEY, ".buttons.exclude");
219: }
220:
221: public void actionPerformed(ActionEvent e) {
222: Object[] objects = ((Panel) getComponent()).included
223: .getSelectedValues();
224: for (int i = 0; i < objects.length; i++) {
225: Object object = objects[i];
226: ((Panel) getComponent()).getModel().exclude(object);
227: }
228: included.clearSelection();
229: }
230: }
231:
232: static protected class ManageAction extends
233: AbstractEditorAction {
234: private EditorWindow window;
235:
236: public ManageAction() {
237: putValue(Action.ACTION_COMMAND_KEY, ".buttons.manage");
238: }
239:
240: public void actionPerformed(ActionEvent e) {
241: EditorWindow window = getEditorWindow();
242: ObjectEditor editor = window.getEditor();
243: editor.setObject(null);
244: editor.showList();
245: org.osbl.client.wings.shell.Window parent = org.osbl.client.wings.shell.Window
246: .currentWindow(((Panel) getComponent()).included);
247: Client.getInstance().pushWindow(parent, window);
248: }
249:
250: private EditorWindow getEditorWindow() {
251: if (window == null) {
252: ObjectEditor editor = getObjectEditor();
253: window = new EditorWindow(editor);
254: window.addPopAction(new PopAction());
255: }
256: return window;
257: }
258:
259: private ObjectEditor getObjectEditor() {
260: ObjectEditor objectEditor = (ObjectEditor) getPropertyData()
261: .getPropertyMeta().getAttribute("objectEditor");
262: if (objectEditor == null)
263: objectEditor = Editors.get(getPropertyData()
264: .getPropertyMeta().getType());
265: return objectEditor;
266: }
267:
268: protected class PopAction extends AbstractObjectAction {
269: public PopAction() {
270: putValue(Action.ACTION_COMMAND_KEY, ".buttons.back");
271: }
272:
273: public void actionPerformed(ObjectActionEvent event) {
274: DomainProvider domainProvider = propertyData
275: .getPropertyMeta().getDomainProvider();
276: if (domainProvider instanceof DynamicDomainProvider) {
277: DynamicDomainProvider dynamicDomainProvider = (DynamicDomainProvider) domainProvider;
278: dynamicDomainProvider.refresh();
279: }
280: //((Panel)getComponent()).getModel().refresh();
281: }
282:
283: public void setEnabled(boolean enabled) {
284: }
285: }
286: }
287: }
288:
289: public static class IncludeExcludeModel {
290: private PropertyData propertyData;
291: private ListListModel excludedModel = new ListListModel();
292: private ListListModel includedModel = new ListListModel();
293: private ChangeListener changeListener;
294:
295: public IncludeExcludeModel(PropertyData propertyData) {
296: this .propertyData = propertyData;
297: refresh();
298: }
299:
300: public void refresh() {
301: List value = (List) propertyData.getValue();
302: if (value == null)
303: return;
304:
305: DomainProvider domainProvider = propertyData
306: .getPropertyMeta().getDomainProvider();
307:
308: List included = new ArrayList(value);
309: List available = domainProvider.getDomain();
310: List excluded = new ArrayList(available);
311: excluded.removeAll(included);
312:
313: includedModel.setList(included);
314: excludedModel.setList(excluded);
315: }
316:
317: public ListListModel getExcludedModel() {
318: return excludedModel;
319: }
320:
321: public ListListModel getIncludedModel() {
322: return includedModel;
323: }
324:
325: public void include(Object object) {
326: if (excludedModel.remove(object))
327: includedModel.add(object);
328:
329: if (changeListener != null)
330: changeListener.stateChanged(new ChangeEvent(this ));
331: }
332:
333: public void exclude(Object object) {
334: if (includedModel.remove(object))
335: excludedModel.add(object);
336:
337: if (changeListener != null)
338: changeListener.stateChanged(new ChangeEvent(this ));
339: }
340:
341: public void addChangeListener(ChangeListener changeListener) {
342: this.changeListener = changeListener;
343: }
344: }
345: }
|