1 package org.glassbox.widgets;
2
3 import org.glassbox.executor.*;
4 import org.glassbox.gui.*;
5 import org.glassbox.Theme;
6 import org.glassbox.SwingFactory;
7 import org.glassbox.SwingThread;
8
9 import java.util.HashMap;
10 import javax.swing.*;
11 import java.awt.*;
12 import java.awt.event.ComponentAdapter;
13 import java.awt.event.ComponentEvent;
14
15 import org.apache.log4j.Logger;
16
17 /***
18 A widget which executes tasks sequentially on a background thread.
19 The widget allows to execute <code>VisibleTasks</code>. The view of a
20 <code>VisibleTask</code> is added to the view of this widget during it's execution.<br><br>
21 This widget has the following properties which can be configured by the application's theme:
22 <ul>
23 <li>glassbox.widgets.VisibleExecutor.background.color</li>
24 <li>glassbox.widgets.VisibleExecutor.insets</li>
25 </ul>
26 */
27 public class VisibleExecutor extends TaskQueue implements VisibleMember {
28 public static final String IDENTIFIER = "glassbox.widgets.VisibleExecutor";
29
30 public interface VisibleTask extends Visible, Runnable {
31 /***
32 Get the view of the task.
33 */
34 JComponent getView();
35 /***
36 Run the task.
37 */
38 void run();
39 }
40
41 protected static final String THEME_PREFIX = "glassbox.widgets.VisibleExecutor";
42
43 private JComponent _view;
44 private Visible _idleview;
45 private Group _group;
46 private ViewHandler _viewhandler;
47
48 public VisibleExecutor() {
49 this(new Visible() {
50 private JPanel _view = null;
51
52 public JComponent getView() {
53 if (_view==null) {
54 _view = new JPanel();
55 _view.setOpaque(false);
56 }
57 return _view;
58 }
59 });
60 }
61
62 public VisibleExecutor(Visible idleview) {
63 super();
64 _viewhandler = new ViewHandler();
65 setHandler(_viewhandler);
66 _view = null;
67 _idleview = idleview;
68 }
69
70
71 public JComponent getView() {
72 if (_view==null) {
73 _view = SwingFactory.createPanel(THEME_PREFIX);
74 _view.setLayout(new BorderLayout());
75 if (_idleview!=null) {
76 _view.setVisible(true);
77 _view.add(_idleview.getView(), BorderLayout.CENTER);
78
79 _view.validate();
80 _idleview.getView().addComponentListener(_viewhandler);
81 } else {
82 _view.setVisible(false);
83 }
84 }
85 return _view;
86 }
87
88 public String getIdentifier() {
89 return IDENTIFIER;
90 }
91
92 public Group getGroup() {
93 return _group;
94 }
95
96 public void setGroup(Group group) {
97 _group = group;
98 }
99
100 public void groupPropertyChanged(String name, Object oldvalue, Object newvalue) {
101 Logger.getLogger(VisibleExecutor.class).debug("groupPropertyChanged("+name+", "+oldvalue+", "+newvalue+")");
102
103 /***
104 if (Group.APPLICATION_STATUS_KEY.equals(name)) {
105 if (Group.EXITING.equals(newvalue)) {
106 stop();
107 }
108 }
109 */
110
111 Logger.getLogger(VisibleExecutor.class).debug("groupPropertyChanged.exit");
112 }
113
114 private class ViewHandler extends ComponentAdapter implements Handler {
115 public void beforeRun(Runnable task) {
116 if (task instanceof VisibleTask) {
117 final VisibleTask vtask = (VisibleTask)task;
118 SwingThread.invokeAndWaitSilently(new Runnable() {
119 public void run() {
120 _view.invalidate();
121 if (_idleview!=null && _idleview.getView().getParent()==_view) {
122 _idleview.getView().removeComponentListener(ViewHandler.this);
123 _view.remove(_idleview.getView());
124 }
125 _view.add(vtask.getView(), BorderLayout.CENTER);
126
127 _view.validate();
128 vtask.getView().addComponentListener(ViewHandler.this);
129 ((VisibleGroup)getGroup()).memberViewUpdated(VisibleExecutor.this);
130 getGroup().setProperty(VisibleGroup.MODAL_MEMBER_KEY, VisibleExecutor.this);
131 }
132 });
133 } else if (_idleview!=null && _idleview.getView().getParent()!=_view) {
134 SwingThread.invokeAndWaitSilently(new Runnable() {
135 public void run() {
136 _view.invalidate();
137 _view.add(_idleview.getView(), BorderLayout.CENTER);
138
139 _view.validate();
140 _idleview.getView().addComponentListener(ViewHandler.this);
141 getGroup().setProperty(VisibleGroup.MODAL_MEMBER_KEY, null);
142 ((VisibleGroup)getGroup()).memberViewUpdated(VisibleExecutor.this);
143 }
144 });
145 }
146 }
147
148 public void afterRun(Runnable task) {
149 if (task instanceof VisibleTask) {
150 final VisibleTask vtask = (VisibleTask)task;
151 SwingThread.invokeAndWaitSilently(new Runnable() {
152 public void run() {
153 vtask.getView().removeComponentListener(ViewHandler.this);
154 _view.invalidate();
155 _view.remove(vtask.getView());
156 if (isEmpty()) {
157 if (_idleview!=null && _idleview.getView().getParent()!=_view) {
158 _view.add(_idleview.getView(), BorderLayout.CENTER);
159
160 _view.validate();
161 _idleview.getView().addComponentListener(ViewHandler.this);
162 }
163 getGroup().setProperty(VisibleGroup.MODAL_MEMBER_KEY, null);
164 }
165 ((VisibleGroup)getGroup()).memberViewUpdated(VisibleExecutor.this);
166
167 }
168 });
169 }
170 }
171
172
173 public void afterFailure(Runnable task, RuntimeException x) {
174 afterRun(task);
175 }
176
177 public void componentResized(ComponentEvent e) {
178
179
180
181
182 }
183 }
184 }