001: package org.osbl.client.wings.form.editor;
002:
003: import org.conform.wings.Editor;
004: import org.conform.wings.PropertyAdapter;
005: import org.conform.wings.editor.*;
006: import org.conform.*;
007: import org.conform.format.Format;
008: import org.wings.*;
009: import org.wings.event.SParentFrameListener;
010: import org.wings.event.SParentFrameEvent;
011: import org.osbl.client.wings.XButton;
012: import org.osbl.client.wings.XIcons;
013: import org.osbl.client.wings.shell.*;
014: import org.osbl.client.wings.form.*;
015: import org.osbl.client.action.*;
016:
017: import javax.swing.*;
018: import javax.swing.event.ChangeListener;
019: import javax.swing.event.ChangeEvent;
020: import java.beans.PropertyChangeListener;
021: import java.beans.PropertyChangeEvent;
022: import java.awt.event.ActionEvent;
023: import java.util.*;
024:
025: public class ManyToOneAssociationEditor implements Editor,
026: SParentFrameListener {
027: public SComponent createComponent(PropertyMeta propertyMeta) {
028: ComboPanel comboPanel = new ComboPanel(propertyMeta);
029: configureComponent(propertyMeta, comboPanel, false);
030: comboPanel.addParentFrameListener(this );
031: return comboPanel;
032: }
033:
034: public void configureComponent(PropertyMeta propertyMeta,
035: SComponent component, boolean erroneous) {
036: ComboPanel comboPanel = (ComboPanel) component;
037: SComboBox comboBox = comboPanel.getComboBox();
038: comboBox.setEnabled(propertyMeta.isWritable());
039: comboBox.setVisible(propertyMeta.isReadable());
040: if (propertyMeta
041: .getAttribute(PropertyMeta.ATTRIBUTE_CHANGE_LISTENER) != null
042: && !Arrays.asList(comboBox.getActionListeners())
043: .contains(NoAction.INSTANCE))
044: comboBox.addActionListener(NoAction.INSTANCE);
045:
046: DefaultEditorStyles.applyEditorState(propertyMeta, comboBox,
047: erroneous);
048: }
049:
050: public void parentFrameAdded(SParentFrameEvent e) {
051: final ComboPanel component = (ComboPanel) e.getSource();
052: PropertyData propertyData = getPropertyData(component);
053: PropertyMeta propertyMeta = propertyData.getPropertyMeta();
054: DynamicDomainProvider domainProvider = (DynamicDomainProvider) propertyMeta
055: .getDomainProvider();
056: ChangeListener listener = new ChangeListener() {
057: public void stateChanged(ChangeEvent e) {
058: component.getComboBoxModel().refresh();
059: }
060: };
061: domainProvider.addChangeListener(listener);
062: component.putClientProperty("domainChangeListener", listener);
063: }
064:
065: public void parentFrameRemoved(SParentFrameEvent e) {
066: final ComboPanel component = (ComboPanel) e.getSource();
067: PropertyData propertyData = getPropertyData(component);
068: PropertyMeta propertyMeta = propertyData.getPropertyMeta();
069: DynamicDomainProvider domainProvider = (DynamicDomainProvider) propertyMeta
070: .getDomainProvider();
071: ChangeListener listener = (ChangeListener) component
072: .getClientProperty("domainChangeListener");
073: domainProvider.removeChangeListener(listener);
074: }
075:
076: public void setPropertyData(SComponent component,
077: PropertyData propertyData) {
078: BeanData beanData = propertyData.getBeanData();
079: if (beanData != null)
080: beanData.addPropertyChangeListener(propertyData
081: .getPropertyMeta().getName(),
082: new ComponentInvalidator(component));
083:
084: if (component instanceof ComboPanel) {
085: ComboPanel comboPanel = (ComboPanel) component;
086: comboPanel.setPropertyData(propertyData);
087:
088: if (beanData != null)
089: beanData.addPropertyChangeListener(propertyData
090: .getPropertyMeta().getName(), comboPanel);
091: }
092: }
093:
094: public PropertyData getPropertyData(SComponent component) {
095: if (component instanceof ComboPanel) {
096: ComboPanel comboPanel = (ComboPanel) component;
097: return comboPanel.getPropertyData();
098: }
099:
100: return null;
101: }
102:
103: static class ComboPanel extends SContainer implements
104: PropertyChangeListener {
105: private PropertyMeta propertyMeta;
106: private SComboBox comboBox;
107: private SButton choose;
108: PropertyData propertyData;
109: private ChooseAction action;
110:
111: public ComboPanel(PropertyMeta propertyMeta) {
112: super (new SBorderLayout());
113: this .propertyMeta = propertyMeta;
114:
115: action = new ChooseAction();
116: action.setComponent(this );
117:
118: choose = new XButton(action);
119: comboBox = new SComboBox();
120: comboBox.setPreferredSize(SDimension.FULLWIDTH);
121:
122: add(comboBox, SBorderLayout.CENTER);
123: add(choose, SBorderLayout.EAST);
124: }
125:
126: public PropertyData getPropertyData() {
127: return propertyData;
128: }
129:
130: public void setPropertyData(PropertyData propertyData) {
131: this .propertyData = propertyData;
132: action.setPropertyData(propertyData);
133:
134: PropertyMeta propertyMeta = propertyData.getPropertyMeta();
135: comboBox.setModel(new ComboBoxModelPropertyAdapter(
136: propertyMeta));
137: Format format = propertyMeta.getFormat();
138: if (format != null)
139: comboBox.setRenderer(new FormattedListCellRenderer(
140: format));
141:
142: getComboBoxModel().setPropertyData(propertyData);
143: }
144:
145: public SComboBox getComboBox() {
146: return comboBox;
147: }
148:
149: public ComboBoxModelPropertyAdapter getComboBoxModel() {
150: return (ComboBoxModelPropertyAdapter) comboBox.getModel();
151: }
152:
153: public void setComboBoxModel(ComboBoxModel model) {
154: comboBox.setModel(model);
155: }
156:
157: public void setEnabled(boolean b) {
158: comboBox.setEnabled(b);
159: choose.setEnabled(b);
160: }
161:
162: public void propertyChange(PropertyChangeEvent evt) {
163: if (getComboBoxModel() instanceof ListTableModel) {
164: final Object value = propertyData.getValue();
165: if (value == null)
166: propertyData.setValue(new ArrayList());
167: ((ListTableModel) getComboBoxModel())
168: .setList((java.util.List) value);
169: }
170: }
171:
172: static class ChooseAction extends AbstractEditorAction {
173: private EditorWindow window;
174:
175: public ChooseAction() {
176: putValue(Action.ACTION_COMMAND_KEY, ".buttons.choose");
177: putValue(Action.SMALL_ICON, XIcons.CHOOSE);
178: }
179:
180: public void setComponent(SComponent component) {
181: super .setComponent(component);
182: putValue(AuthorizedAction.PERMISSION_KEY,
183: ((ComboPanel) component).propertyMeta.getType()
184: .getName()
185: + "[r]");
186: }
187:
188: public void actionPerformed(ActionEvent e) {
189: EditorWindow window = getEditorWindow();
190: ObjectEditor editor = window.getEditor();
191: editor.showList();
192: editor
193: .setSelectedObject(((ComboPanel) getComponent()).comboBox
194: .getSelectedItem());
195: org.osbl.client.wings.shell.Window parent = org.osbl.client.wings.shell.Window
196: .currentWindow(getComponent());
197: Client.getInstance().pushWindow(parent, window);
198: }
199:
200: private EditorWindow getEditorWindow() {
201: if (window == null) {
202: ObjectEditor editor = getObjectEditor();
203: window = new EditorWindow(editor);
204: window.addPopAction(new PopAction());
205: }
206: return window;
207: }
208:
209: private ObjectEditor getObjectEditor() {
210: ObjectEditor objectEditor = (ObjectEditor) getPropertyMeta()
211: .getAttribute("objectEditor");
212: if (objectEditor == null)
213: objectEditor = Editors.get(getPropertyMeta()
214: .getType());
215: return objectEditor;
216: }
217:
218: private class PopAction extends AbstractObjectAction {
219: public PopAction() {
220: putValue(Action.ACTION_COMMAND_KEY,
221: ".buttons.takeOver");
222: }
223:
224: public void actionPerformed(ObjectActionEvent event) {
225: ((DynamicDomainProvider) getPropertyMeta()
226: .getDomainProvider()).refresh();
227:
228: List objects = getObjectEditor()
229: .getSelectedObjects();
230: Object object = getObjectEditor().getObject();
231: if (objects != null && objects.size() == 1)
232: ((ComboPanel) getComponent()).comboBox
233: .setSelectedItem(objects.get(0));
234: else if (object != null)
235: ((ComboPanel) getComponent()).comboBox
236: .setSelectedItem(object);
237: else if (objects != null && objects.size() > 0)
238: ((ComboPanel) getComponent()).comboBox
239: .setSelectedItem(objects.get(0));
240: }
241: }
242: }
243: }
244:
245: // TODO: add an item "...", if size exceeds 20
246: static class ComboBoxModelPropertyAdapter extends
247: SDefaultComboBoxModel implements PropertyAdapter {
248: private PropertyData propertyData;
249: private PropertyMeta property;
250:
251: public ComboBoxModelPropertyAdapter(PropertyMeta property) {
252: this .property = property;
253: }
254:
255: public PropertyData getPropertyData() {
256: return propertyData;
257: }
258:
259: public void setPropertyData(PropertyData propertyData) {
260: this .propertyData = propertyData;
261: fireContentsChanged(this , -1, -1);
262: }
263:
264: public Object getElementAt(int i) {
265: return property.getDomainProvider().getDomain().get(i);
266: }
267:
268: public int getSize() {
269: return property.getDomainProvider().getDomain().size();
270: }
271:
272: public Object getSelectedItem() {
273: if (propertyData == null)
274: return null;
275:
276: return propertyData.getValue();
277: }
278:
279: public void setSelectedItem(Object value) {
280: propertyData.setValue(value);
281: fireContentsChanged(this , -1, -1);
282: }
283:
284: protected void refresh() {
285: int end = getSize() - 1;
286: fireIntervalRemoved(this , 0, end);
287: fireIntervalAdded(this , 0, end);
288: }
289: }
290: }
|