View Javadoc

1   /*
2    * Copyright (c) 2005, The K-Wf Grid Consortium
3    * Fraunhofer Institute for Computer Architecture and Software Technology
4    * See http://www.kwfgrid.eu and http://www.first.fraunhofer.de for more details.
5    */
6   package net.kwfgrid.gwui.gui;
7   
8   import org.glassbox.Theme;
9   import org.glassbox.gui.Visible;
10  import org.glassbox.executor.Executor;
11  
12  import net.kwfgrid.gwui.SwingFactory2;
13  import net.kwfgrid.gwui.GWUI;
14  import net.kwfgrid.gwui.workflow.XMLUtilities;
15  import net.kwfgrid.gworkflowdl.structure.Transition;
16  import net.kwfgrid.gworkflowdl.structure.Workflow;
17  import net.kwfgrid.gworkflowdl.structure.Factory;
18  import net.kwfgrid.gworkflowdl.structure.Property;
19  import net.kwfgrid.gworkflowdl.protocol.structure.*;
20  
21  import java.util.List;
22  import java.awt.GridBagLayout;
23  import java.awt.GridBagConstraints;
24  import java.awt.Insets;
25  import java.awt.event.ActionEvent;
26  import java.awt.event.ActionListener;
27  import java.awt.event.MouseEvent;
28  import java.awt.event.MouseListener;
29  import java.awt.event.MouseAdapter;
30  import java.awt.event.ItemEvent;
31  import java.awt.event.ItemListener;
32  import java.io.*;
33  import javax.swing.*;
34  import javax.swing.border.TitledBorder;
35  import javax.swing.event.DocumentListener;
36  import javax.swing.event.DocumentEvent;
37  
38  import org.apache.log4j.Logger;
39  
40  /***
41     An editor for the conditions of a transition.
42   */
43  public class TransitionConditionEditor extends AbstractWorkflowElementEditor {
44      private static final Logger logger = Logger.getLogger(TransitionConditionEditor.class);
45  
46      private static final String ADD_COMMAND = "ADD";
47      private static final String REMOVE_COMMAND = "REMOVE";
48      private static final String CONDITION_TRUE_COMMAND = "TRUE";
49      private static final String CONDITION_FALSE_COMMAND = "FALSE";
50  
51      private static final String CONDITION_TRUE = "true";
52      private static final String CONDITION_FALSE = "false";
53  
54      private ActionListener ACTION_LISTENER = new ActionListener() {
55  	    public void actionPerformed(ActionEvent e) {
56  		String c = e.getActionCommand();
57  		if (ADD_COMMAND.equals(c)) {
58  		    final String condition = _conditionfield.getText();
59  		    final Transition element = (Transition)getElement();
60  		    setPerformingTask(true);
61  		    getExecutor().execute(new GUIMethodCallTask("Adding condition ...", getExecutor(), TransitionConditionEditor.this) {
62  			    protected void execute() {
63  				element.addCondition(condition);
64  			    }
65  			});
66  		} else if (REMOVE_COMMAND.equals(c)) {
67  		    final int index = _conditionbox.getSelectedIndex();
68  		    final Transition element = (Transition)getElement();
69  		    setPerformingTask(true);
70  		    getExecutor().execute(new GUIMethodCallTask("Removing condition ...", getExecutor(), TransitionConditionEditor.this) {
71  			    protected void execute() {
72  				element.removeCondition(index);
73  			    }
74  			});
75  		} else if (CONDITION_TRUE_COMMAND.equals(c)) {
76  		    _conditionfield.setText(CONDITION_TRUE);
77  		} else if (CONDITION_FALSE_COMMAND.equals(c)) {
78  		    _conditionfield.setText(CONDITION_FALSE);
79  		} 
80  	    }	    
81  	};
82  
83      private MouseListener MOUSE_LISTENER = new MouseAdapter() {
84  	    public void mouseClicked(MouseEvent e) {
85  		if (e.getButton()!=MouseEvent.BUTTON1) {
86  		    _popup.show(_conditionfield, e.getX(), e.getY());
87  		}
88  	    }
89  	}; 
90  
91      private DocumentListener INPUT_LISTENER = new DocumentListener() {
92  	    private void update() {
93  		if (_conditionbox.getSelectedIndex()<_conditionbox.getItemCount()-1) {
94  		    _conditionbox.removeItemListener(ITEM_LISTENER);
95  		    _conditionbox.setSelectedIndex(_conditionbox.getItemCount()-1);
96  		    _conditionbox.addItemListener(ITEM_LISTENER);
97  		} 
98  		_newcondition = _conditionfield.getText();
99  		updateView();
100 	    }
101 
102 	    public void insertUpdate(DocumentEvent e) {
103 		update();
104 	    }
105 
106 	    public void removeUpdate(DocumentEvent e) {
107 		update();
108 	    }
109 
110 	    public void changedUpdate(DocumentEvent e) {
111 	    }
112 	};
113 
114     private ItemListener ITEM_LISTENER = new ItemListener() {
115 	    public void itemStateChanged(ItemEvent e) {		
116 		String text = null;
117 		if (_conditionbox.getSelectedIndex()<_conditionbox.getItemCount()-1) {
118 		    text = (String)_conditionbox.getSelectedItem();
119 		} else {
120 		    text = _newcondition;
121 		}
122 		_conditionfield.getDocument().removeDocumentListener(INPUT_LISTENER);
123 		_conditionfield.setText(text);
124 		_conditionfield.getDocument().addDocumentListener(INPUT_LISTENER);
125 		updateView();
126 	    }
127 	};
128 
129     private class ConditionBoxModel extends DefaultComboBoxModel {
130 	public ConditionBoxModel(Object[] conditions) {
131 	    super(conditions);
132 	    String bottom = "New Condition";
133 	    addElement(bottom);
134 	}
135 
136 	public ConditionBoxModel(Object[] conditions, Object selected) {
137 	    this(conditions);
138 	    if (selected!=null) {
139 		for (int i=0; i<getSize(); i++) {
140 		    if (selected.equals(getElementAt(i))) {
141 			setSelectedItem(selected);
142 			break;
143 		    }
144 		}
145 	    }
146 	}
147     }
148 
149     private JComponent _view;
150 
151     private JButton _button_add;
152     private JButton _button_remove;
153     private JTextField _conditionfield;
154     private JComboBox _conditionbox;
155     private JPopupMenu _popup;
156     private JMenuItem _mitem_condition_true;
157     private JMenuItem _mitem_condition_false;
158 
159     private String _newcondition;
160 	    
161     public TransitionConditionEditor(Executor executor, ProtocolWorkflow workflow, ProtocolTransition transition) {
162 	super(executor, workflow, transition);
163 	_view = null;
164 	_newcondition = null;
165     }
166 
167     public void objectsAdded(IStructureObject parent, String namespace, String name, List objects) {
168 	if (affectsConditionSet(parent, namespace, name)) updateConditionList();
169     }
170     
171     public void objectsRemoved(IStructureObject parent, String namespace, String name, List objects) {
172 	if (affectsConditionSet(parent, namespace, name)) updateConditionList();
173     }
174     
175     public void propertyChanged(IStructureObject parent, String namespace, String name, Object newvalue) {
176 	if (affectsConditionSet(parent, namespace, name)) updateConditionList();
177     }
178     
179     private boolean affectsConditionSet(IStructureObject parent, String namespace, String name) {
180 	if (parent == getElement() &&
181 	    XMLUtilities.equalNamespace(ProtocolTransition.NAMESPACE, namespace) &&
182 	    ProtocolTransition.NAME_CONDITION.equals(name)) {
183 	    return true;
184 	} 
185 	return false;
186     }
187     
188     private void updateConditionList() {
189 	Object selected = _conditionbox.getSelectedItem();
190 	_conditionbox.setModel(new ConditionBoxModel(((Transition)getElement()).getConditions(), selected));
191 	ITEM_LISTENER.itemStateChanged(null); // HACK to update the textarea		    
192 	updateView();
193     }
194     
195     public void setEditable(boolean editable) {
196 	if (isEditable() && !editable)
197 	    _conditionfield.removeMouseListener(MOUSE_LISTENER);
198 	if (editable && !isEditable()) 
199 	    _conditionfield.addMouseListener(MOUSE_LISTENER);
200 	_conditionfield.setEditable(editable);
201 	super.setEditable(editable);
202     }
203 
204     protected void updateState() {
205 	String text = _conditionfield.getText();
206 	boolean newcondition = _conditionbox.getSelectedIndex()==_conditionbox.getItemCount()-1;	
207 	boolean textentered = text!=null && text.length()>0;
208 
209 	if (!isEnabled() || isPerformingTask()) {
210 	    _button_add.setEnabled(false);
211 	    _button_remove.setEnabled(false);
212 	    _conditionfield.setEnabled(false);
213 	    _conditionbox.setEnabled(false);
214 	} else {
215 	    _conditionfield.setEnabled(true);
216 	    _conditionbox.setEnabled(true);
217 	    if (newcondition) {
218 		_button_remove.setEnabled(false);
219 		_button_add.setEnabled(textentered && isEditable());
220 	    } else {
221 		_button_remove.setEnabled(isEditable());
222 		_button_add.setEnabled(false);
223 	    }
224 	}
225     }
226 
227     protected void updateView() {
228 	updateState();
229 	_view.invalidate();
230 
231 	int condition_num = _conditionbox.getItemCount()-1;
232 
233 	_view.setSize(_view.getLayout().preferredLayoutSize(_view));
234 	_view.doLayout();
235 	_view.validate();
236     }
237 
238     public JComponent getView() {
239 	if (_view==null) {
240 	    Transition transition = (Transition)getElement();
241 	    _mitem_condition_true = new JMenuItem("new Condition 'true'");
242 	    _mitem_condition_true.addActionListener(ACTION_LISTENER);
243 	    _mitem_condition_true.setActionCommand(CONDITION_TRUE_COMMAND);
244 	    _mitem_condition_false = new JMenuItem("new Condition 'false'");
245 	    _mitem_condition_false.addActionListener(ACTION_LISTENER);
246 	    _mitem_condition_false.setActionCommand(CONDITION_FALSE_COMMAND);
247 	    _popup = new JPopupMenu("Content of Condition");
248 	    _popup.add(_mitem_condition_true);
249 	    _popup.add(_mitem_condition_false);
250 	    _popup.pack();
251 
252 	    _button_add = new JButton("add");
253 	    _button_add.setActionCommand(ADD_COMMAND);
254 	    _button_add.addActionListener(ACTION_LISTENER);
255 	    _button_remove = new JButton("remove");
256 	    _button_remove.addActionListener(ACTION_LISTENER);
257 	    _button_remove.setActionCommand(REMOVE_COMMAND);
258 	    _conditionbox = new JComboBox(new ConditionBoxModel(transition.getConditions()));
259 	    _conditionbox.addItemListener(ITEM_LISTENER);
260 	    _conditionfield = new JTextField(40);
261 	    if (_conditionbox.getSelectedIndex()<_conditionbox.getItemCount()-1) {
262 		_conditionfield.setText((String)_conditionbox.getSelectedItem());
263 	    }
264 	    _conditionfield.addMouseListener(MOUSE_LISTENER);
265 	    _conditionfield.getDocument().addDocumentListener(INPUT_LISTENER);
266 
267 	    GridBagLayout gridbag = new GridBagLayout();
268 
269 	    _view = new JPanel();
270 	    _view.setBorder(createBorder("Conditions"));
271 	    _view.setLayout(gridbag);
272 
273 	    GridBagConstraints c = new GridBagConstraints();
274 
275 	    c.insets = new Insets(5, 0, 0, 0);
276 	    c.weightx = 1.0;
277 	    c.gridx = 0;
278 	    c.gridy = 0;
279 	    c.anchor = GridBagConstraints.CENTER;
280 	    c.fill = GridBagConstraints.BOTH;
281 	    c.gridwidth = GridBagConstraints.REMAINDER;
282 
283 	    _view.add(_conditionbox, c);
284 
285 	    c.fill = GridBagConstraints.HORIZONTAL;
286 	    c.gridx = 0;
287 	    c.gridy = 1;
288 	    c.gridwidth = GridBagConstraints.REMAINDER;
289 
290 	    _view.add(_conditionfield, c);
291 
292 	    c.weightx = 0.0;
293 	    c.anchor = GridBagConstraints.WEST;
294 	    c.gridwidth = 1;
295 	    c.fill = GridBagConstraints.NONE;
296 	    c.gridy = 2;
297 	    c.gridx = 0;
298 
299 	    _view.add(_button_remove, c);
300 
301 	    c.anchor = GridBagConstraints.EAST;
302 	    c.gridwidth = GridBagConstraints.REMAINDER;
303 	    c.gridx = 2;
304 
305 	    _view.add(_button_add, c);
306 
307 	    updateView();
308 	}
309 	return _view;
310     }    
311 }