1
2
3
4
5
6 package net.kwfgrid.gwui;
7
8 import net.kwfgrid.gwui.graphview.TransitionNode;
9 import net.kwfgrid.gwui.graphview.WorkflowGraph;
10 import net.kwfgrid.gwui.taskframework.UserTaskHandler;
11 import net.kwfgrid.gwui.taskframework.UserTask;
12 import net.kwfgrid.gworkflowdl.structure.*;
13
14 import org.glassbox.gui.*;
15 import org.glassbox.Theme;
16 import org.glassbox.SwingFactory;
17
18 import javax.swing.*;
19 import java.util.Iterator;
20 import java.awt.*;
21 import java.awt.event.*;
22 import java.awt.image.ImageObserver;
23
24 import org.apache.log4j.Logger;
25
26 /***
27 A view which gives textual feedback about the status of a workflow.<br>
28 This widget must be member of a <code>WorkflowGroup</code>.<br>
29 This widget has the following properties which can be configured in the application's theme:<br>
30 <ul>
31 <li>kwfgrid.WorkflowStatusView.insets</li>
32 <li>kwfgrid.WorkflowStatusView.font</li>
33 <li>kwfgrid.WorkflowStatusView.color</li>
34 <li>kwfgrid.WorkflowStatusView.running.icon</li>
35 <li>kwfgrid.WorkflowStatusView.warning.icon</li>
36 <li>kwfgrid.STATUS.initiated.color</li>
37 <li>kwfgrid.STATUS.running.color</li>
38 <li>kwfgrid.STATUS.suspended.color</li>
39 <li>kwfgrid.STATUS.terminated.color</li>
40 <li>kwfgrid.STATUS.completed.color</li>
41 <li>kwfgrid.STATUS.active.color</li>
42 </ul>
43 */
44 public class WorkflowStatusView extends AbstractMember implements VisibleMember, UserTaskHandler.Listener {
45 private static final Logger logger = Logger.getLogger(WorkflowStatusView.class);
46
47 public static String IDENTIFIER = "net.kwfgrid.gwui.WorkflowStatusView";
48
49 private static final String THEME_PREFIX = "kwfgrid.WorkflowStatusView";
50 private static final String ICON_RUNNING_KEY = "kwfgrid.WorkflowStatusView.running.icon";
51
52 private static final Color TEXT_COLOR = Theme.getColor(THEME_PREFIX+".color");
53
54 private static String[] STATUS = new String[] { "Workflow is undefined.",
55 "Workflow has been initiated.",
56 "Workflow is running.",
57 "Workflow has been suspended.",
58 "Workflow is active.",
59 "Workflow has been terminated.",
60 "Workflow has been completed." };
61
62 private static Color[] BACKGROUND_COLOR = new Color[] { Theme.getColor("kwfgrid.STATUS.undefined.color"),
63 Theme.getColor("kwfgrid.STATUS.initiated.color"),
64 Theme.getColor("kwfgrid.STATUS.running.color"),
65 Theme.getColor("kwfgrid.STATUS.suspended.color"),
66 Theme.getColor("kwfgrid.STATUS.active.color"),
67 Theme.getColor("kwfgrid.STATUS.terminated.color"),
68 Theme.getColor("kwfgrid.STATUS.completed.color") };
69
70 private Action _action = new AbstractAction() {
71 public void actionPerformed(ActionEvent e) {
72 UserTask task = _currenttask;
73 if (task != null) task.execute();
74 }
75 };
76
77 private JLabel _label;
78 private JButton _button;
79 private JPanel _view;
80 private int _status;
81 private Icon[] _icons;
82 private UserTaskHandler _taskhandler;
83 private UserTask _currenttask;
84
85 public WorkflowStatusView() {
86 _view = null;
87 _status = 0;
88 _icons = null;
89 _taskhandler = null;
90 _currenttask = null;
91 }
92
93 public WorkflowStatusView(UserTaskHandler taskhandler) {
94 this();
95 setUserTaskHandler(taskhandler);
96 }
97
98 public void setUserTaskHandler(UserTaskHandler handler) {
99 _taskhandler = handler;
100 _taskhandler.addUserTaskListener(this);
101 }
102
103 public void setGroup(Group group) {
104 super.setGroup(group);
105 }
106
107 public JComponent getView() {
108 if (_label==null) {
109 logger.debug("Creating view.");
110 _label = SwingFactory.createLabel(STATUS[_status], THEME_PREFIX);
111 _label.setForeground(TEXT_COLOR);
112
113 _button = new JButton();
114 _button.setBorder(null);
115 _button.setAction(_action);
116
117 Icon icon_running = Theme.getIcon(ICON_RUNNING_KEY);
118 if (icon_running instanceof ImageIcon)
119 ((ImageIcon)icon_running).setImageObserver(_label);
120 _icons = new Icon[] { null, null, icon_running, null, icon_running, null, null };
121
122 _view = new JPanel();
123 _view.setLayout(new FlowLayout(5, 0, FlowLayout.LEFT));
124 _view.add(_button);
125 _view.add(_label);
126
127 updateView();
128 }
129 return _view;
130 }
131
132 public String getIdentifier() {
133 return IDENTIFIER;
134 }
135
136 protected Workflow getWorkflow() {
137 return (Workflow)getGroup().getProperty(WorkflowGroup.ACTIVE_WORKFLOW_DOCUMENT_KEY);
138 }
139
140 protected void updateView() {
141 logger.debug("updateView()");
142
143 logger.debug("Status: "+_status);
144
145 _label.setText(STATUS[_status]);
146 _label.setBackground(BACKGROUND_COLOR[_status]);
147 _view.setBackground(BACKGROUND_COLOR[_status]);
148 _button.setBackground(BACKGROUND_COLOR[_status]);
149
150 if (_status != 3) {
151 _label.setIcon(_icons[_status]);
152 _label.setToolTipText(null);
153 _button.setVisible(false);
154 } else {
155 _currenttask = _taskhandler.nextTask();
156
157 logger.debug("Next task: "+_currenttask);
158
159 if (_currenttask != null) {
160 _button.setIcon(_currenttask.getIcon());
161 _label.setToolTipText("To continue the workflow: "+_currenttask.getTitle());
162 _label.setIcon(null);
163 _button.setToolTipText("Click to execute task: "+_currenttask.getTitle());
164 _button.setVisible(true);
165 } else {
166 _label.setIcon(_icons[_status]);
167 _label.setToolTipText(null);
168 _button.setVisible(false);
169 }
170 }
171 }
172
173 public void tasksAdded(UserTask[] tasks) {
174 logger.debug("tasksAdded");
175 updateView();
176 }
177
178 public void taskInvalid(UserTask task) {
179 logger.debug("taskInvalid");
180 updateView();
181 }
182
183 public void taskDone(UserTask task) {
184 logger.debug("taskDone");
185 updateView();
186 }
187
188 public void groupPropertyChanged(String name, Object oldvalue, Object newvalue) {
189 if (WorkflowGroup.WORKFLOW_STATUS_KEY.equals(name)) {
190 _status = ((Integer)newvalue).intValue();
191 updateView();
192 }
193 }
194 }