001: package org.osbl.client.wings.shell;
002:
003: import java.util.*;
004:
005: import org.conform.BeanMetaProvider;
006: import org.osbl.client.action.ActionProvider;
007: import org.osbl.client.ClientResourceProvider;
008: import org.osbl.client.ClientServiceProvider;
009: import org.osbl.client.wings.devtools.DevelopmentTool;
010: import org.wings.*;
011: import org.wings.session.*;
012:
013: import javax.swing.*;
014: import javax.swing.event.*;
015:
016: /**
017: * @author hengels
018: * @version $Revision$
019: */
020: public abstract class Client {
021: private BeanMetaProvider beanMetaProvider;
022: private ActionProvider actionProvider;
023: private ClientServiceProvider serviceProvider;
024: private ClientResourceProvider resourceProvider;
025: private static List<ClientInitializer> initializers = new LinkedList<ClientInitializer>();
026: protected DevelopmentTool developmentTool;
027: protected ContextHelpTool contextHelpTool;
028:
029: protected Client() {
030: getSession().setProperty("Client", this );
031:
032: for (Iterator<ClientInitializer> iterator = initializers
033: .iterator(); iterator.hasNext();) {
034: ClientInitializer clientInitializer = iterator.next();
035: clientInitializer.preInitialization(this );
036: }
037:
038: initialize();
039:
040: for (Iterator<ClientInitializer> iterator = initializers
041: .iterator(); iterator.hasNext();) {
042: ClientInitializer clientInitializer = iterator.next();
043: clientInitializer.postInitialization(this );
044: }
045:
046: new URLNavigation();
047: }
048:
049: protected abstract void initialize();
050:
051: public static void addInitializer(
052: ClientInitializer clientInitializer) {
053: initializers.add(clientInitializer);
054: }
055:
056: public static Client getInstance() {
057: return (Client) SessionManager.getSession().getProperty(
058: "Client");
059: }
060:
061: public BeanMetaProvider getBeanMetaProvider() {
062: return beanMetaProvider;
063: }
064:
065: public void setBeanMetaProvider(BeanMetaProvider beanMetaProvider) {
066: this .beanMetaProvider = beanMetaProvider;
067: }
068:
069: public ActionProvider getActionProvider() {
070: return actionProvider;
071: }
072:
073: public void setActionProvider(ActionProvider actionProvider) {
074: this .actionProvider = actionProvider;
075: }
076:
077: public ClientServiceProvider getServiceProvider() {
078: return serviceProvider;
079: }
080:
081: public void setServiceProvider(ClientServiceProvider serviceProvider) {
082: this .serviceProvider = serviceProvider;
083: }
084:
085: public ClientResourceProvider getResourceProvider() {
086: return resourceProvider;
087: }
088:
089: public void setResourceProvider(
090: ClientResourceProvider resourceProvider) {
091: this .resourceProvider = resourceProvider;
092: }
093:
094: protected Session getSession() {
095: return SessionManager.getSession();
096: }
097:
098: public abstract void addNavigation(String character, String title,
099: SIcon icon, SComponent component);
100:
101: public abstract void removeNavigation(String character);
102:
103: public abstract void removeNavigation(SComponent component);
104:
105: public abstract SComponent getNavigation(String character);
106:
107: public abstract void clearNavigations();
108:
109: @Deprecated
110: public abstract void show(String character, SComponent component);
111:
112: @Deprecated
113: public abstract void hide(String character, SComponent component);
114:
115: @Deprecated
116: public abstract void showMessage(Message message);
117:
118: @Deprecated
119: public abstract void hideMessage(Message message);
120:
121: @Deprecated
122: public abstract void clearMessages();
123:
124: @Deprecated
125: public abstract void refreshTitle();
126:
127: @Deprecated
128: public abstract void refreshActions();
129:
130: @Deprecated
131: public abstract void refreshTools();
132:
133: protected boolean isIE() {
134: System.out.println("getSession().getUserAgent() = "
135: + getSession().getUserAgent());
136: return BrowserType.IE.equals(getSession().getUserAgent()
137: .getBrowserType());
138: }
139:
140: public abstract void showDetailHelp(String key);
141:
142: public abstract SComponent getShownComponent();
143:
144: public abstract void addHeaderComponent(SComponent component);
145:
146: public void addHeaderButton(Action action) {
147: if (action != null && action.isEnabled()) {
148: SButton button = new SButton(action);
149: button.setToolTipText(button.getText());
150: button.setText(null);
151: button.setStyle("borderless_form");
152: addHeaderComponent(button);
153: }
154: }
155:
156: public void setDevelopmentTool(DevelopmentTool developmentTool) {
157: this .developmentTool = developmentTool;
158: }
159:
160: public void setContextHelpTool(ContextHelpTool contextHelpTool) {
161: this .contextHelpTool = contextHelpTool;
162: }
163:
164: private WindowStacksModel windowStacksModel = new WindowStacksModel();
165: {
166: windowStacksModel.addChangeListener(new ChangeListener() {
167: public void stateChanged(ChangeEvent e) {
168: int i = windowStacksModel.getActiveStack();
169: activateStack(i != -1 ? windowStacksModel
170: .getElementAt(i) : null);
171: }
172: });
173: }
174:
175: public WindowStacksModel getWindowStacksModel() {
176: return windowStacksModel;
177: }
178:
179: public void pushWindow(Window window) {
180: if (!activateStack(window))
181: pushWindow(null, window);
182: }
183:
184: public void pushWindow(Window parent, Window window) {
185: if (parent != null) {
186: window.setParent(parent);
187:
188: for (Stack<Window> stack : windowStacksModel) {
189: if (stack.contains(parent)) {
190: stack.peek().setVisible(false);
191:
192: stack.push(window);
193: window.setVisible(true);
194: window.setActive(windowStacksModel.getStacks()
195: .indexOf(stack) == windowStacksModel
196: .getActiveStack());
197:
198: break;
199: }
200: }
201: } else {
202: Stack<Window> stack = new Stack<Window>();
203: windowStacksModel.add(stack);
204: windowStacksModel.setActiveStack(windowStacksModel
205: .getSize() - 1);
206:
207: stack.push(window);
208: window.setVisible(true);
209: window.setActive(true);
210: }
211: }
212:
213: public void popWindow(Window window) {
214: for (Stack<Window> stack : windowStacksModel) {
215: if (stack.peek() == window) {
216: window.setActive(false);
217: window.setVisible(false);
218: stack.pop();
219: if (stack.size() > 0)
220: stack.peek().setVisible(true);
221: else {
222: windowStacksModel.remove(stack);
223: }
224: return;
225: }
226: }
227: throw new IllegalArgumentException(
228: "Can't pop this window. It is not lying on top of any window stack!");
229: }
230:
231: public boolean activateStack(Window window) {
232: int i = 0;
233: for (Stack<Window> stack : windowStacksModel) {
234: if (stack.contains(window)) {
235: activateStack(stack);
236: windowStacksModel.setActiveStack(i);
237: return true;
238: }
239: i++;
240: }
241: return false;
242: }
243:
244: Stack<Window> activeStack = null;
245:
246: private void activateStack(Stack<Window> activeStack) {
247: if (this .activeStack == activeStack)
248: return;
249:
250: if (this .activeStack != null)
251: for (Window window : this .activeStack)
252: window.setActive(false);
253:
254: this .activeStack = activeStack;
255:
256: if (this .activeStack != null)
257: for (Window window : this .activeStack)
258: window.setActive(true);
259: else {
260: setTitle(null);
261: setContent(null);
262: setStatusMessage(null);
263: setControls(null);
264: setTools(null);
265: setDevelopmentActions(null);
266: setDefaultButton(null);
267: }
268: }
269:
270: protected abstract void setContent(SComponent contentPane);
271:
272: protected void setTitle(String title) {
273: if (windowStacksModel.getActiveStack() != -1)
274: windowStacksModel.changed(windowStacksModel
275: .getActiveStack());
276: }
277:
278: protected abstract void setControls(List<SComponent> controls);
279:
280: protected abstract void setTools(List<Tool> tools);
281:
282: protected abstract void setStatusMessage(Message statusMessage);
283:
284: protected abstract void setDevelopmentActions(
285: List<Action> developmentActions);
286:
287: protected abstract void setHelpCode(String helpCode);
288:
289: protected abstract void setDefaultButton(SButton button);
290:
291: protected abstract Window currentWindow(SComponent component);
292:
293: public Locale getLocale() {
294: return getSession().getLocale();
295: }
296:
297: public static class Message {
298: public static final int TYPE_INFO = javax.swing.JOptionPane.INFORMATION_MESSAGE;
299: public static final int TYPE_WARNING = javax.swing.JOptionPane.WARNING_MESSAGE;
300: public static final int TYPE_ERROR = javax.swing.JOptionPane.ERROR_MESSAGE;
301:
302: private int type;
303: private String message;
304: private String detail;
305:
306: public Message() {
307: }
308:
309: public Message(int type, String message, String detail) {
310: if (type < 0 || type > 2)
311: throw new IllegalArgumentException("Illegal type");
312: this .type = type;
313: this .message = message;
314: this .detail = detail;
315: }
316:
317: public Message(int type, String message) {
318: if (type < 0 || type > 2)
319: throw new IllegalArgumentException("Illegal type");
320: this .type = type;
321: this .message = message;
322: }
323:
324: public int getType() {
325: return type;
326: }
327:
328: public void setType(int type) {
329: this .type = type;
330: }
331:
332: public String getMessage() {
333: return message;
334: }
335:
336: public void setMessage(String message) {
337: this .message = message;
338: }
339:
340: public String getDetail() {
341: return detail;
342: }
343:
344: public void setDetail(String detail) {
345: this .detail = detail;
346: }
347:
348: public boolean equals(Object o) {
349: if (this == o)
350: return true;
351: if (o == null || getClass() != o.getClass())
352: return false;
353:
354: Message message1 = (Message) o;
355:
356: if (type != message1.type)
357: return false;
358: if (detail != null ? !detail.equals(message1.detail)
359: : message1.detail != null)
360: return false;
361: if (message != null ? !message.equals(message1.message)
362: : message1.message != null)
363: return false;
364:
365: return true;
366: }
367:
368: public int hashCode() {
369: int result;
370: result = type;
371: result = 31 * result
372: + (message != null ? message.hashCode() : 0);
373: result = 31 * result
374: + (detail != null ? detail.hashCode() : 0);
375: return result;
376: }
377:
378: public String toString() {
379: switch (type) {
380: case TYPE_INFO:
381: return "[I] " + message;
382: case TYPE_WARNING:
383: return "[W] " + message;
384: case TYPE_ERROR:
385: return "[E] " + message;
386: default:
387: return message;
388: }
389: }
390: }
391:
392: protected class WindowStacksModel extends AbstractListModel
393: implements Iterable<Stack<Window>> {
394: private List<Stack<Window>> stacks = new ArrayList<Stack<Window>>();
395: private int activeStack;
396:
397: private EventListenerList listeners = new EventListenerList();
398: private ChangeEvent changeEvent = new ChangeEvent(this );
399:
400: public List<Stack<Window>> getStacks() {
401: return stacks;
402: }
403:
404: public int getSize() {
405: return stacks.size();
406: }
407:
408: public Stack<Window> getElementAt(int index) {
409: return stacks.get(index);
410: }
411:
412: public void changed(int activeStack) {
413: fireContentsChanged(this , activeStack, activeStack);
414: }
415:
416: public int getActiveStack() {
417: return activeStack;
418: }
419:
420: public void setActiveStack(int activeStack) {
421: this .activeStack = activeStack;
422: fireChangeEvent();
423: }
424:
425: private void fireChangeEvent() {
426: for (ChangeListener changeListener : listeners
427: .getListeners(ChangeListener.class)) {
428: changeListener.stateChanged(changeEvent);
429: }
430: }
431:
432: public void addChangeListener(ChangeListener listener) {
433: listeners.add(ChangeListener.class, listener);
434: }
435:
436: public void removeChangeListener(ChangeListener listener) {
437: listeners.remove(ChangeListener.class, listener);
438: }
439:
440: public void add(Stack<Window> stack) {
441: stacks.add(stack);
442: fireIntervalAdded(this , stacks.size(), stacks.size());
443: }
444:
445: public void remove(Stack<Window> stack) {
446: Stack<Window> selected = activeStack != -1
447: && activeStack < stacks.size() ? stacks
448: .get(activeStack) : null;
449:
450: int removedIndex = stacks.indexOf(stack);
451: stacks.remove(removedIndex);
452: fireIntervalRemoved(this , removedIndex, removedIndex);
453:
454: // try to keep active stack selected
455: int index = stacks.indexOf(selected);
456: // active stack has been removed -> select stack at same index
457: if (index == -1)
458: index = activeStack;
459: // index out of bounds -> select last
460: if (index > stacks.size() - 1)
461: index = stacks.size() - 1;
462:
463: setActiveStack(index);
464: }
465:
466: public Iterator<Stack<Window>> iterator() {
467: return stacks.iterator();
468: }
469: }
470: }
|