/[xulu]/branches/1.8-gt2-2.6/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java
ViewVC logotype

Contents of /branches/1.8-gt2-2.6/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 60 - (show annotations)
Sun Oct 4 16:54:52 2009 UTC (15 years, 2 months ago) by alfonx
File size: 20205 byte(s)
* organized imports
1 package appl.plugin.multimodelcontrol;
2
3 import java.awt.Color;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.util.concurrent.locks.Condition;
7 import java.util.concurrent.locks.Lock;
8 import java.util.concurrent.locks.ReentrantLock;
9
10 import javax.swing.DefaultListModel;
11 import javax.swing.JOptionPane;
12 import javax.swing.ListSelectionModel;
13 import javax.swing.event.ListSelectionEvent;
14 import javax.swing.event.ListSelectionListener;
15
16 import schmitzm.data.event.ObjectEvent;
17 import schmitzm.data.event.ObjectListener;
18 import schmitzm.lang.WorkingThread;
19 import schmitzm.lang.WorkingThreadAdapter;
20 import schmitzm.swing.TextAreaPrintStream;
21 import appl.parallel.gui.ParallelControlPanelEngine;
22 import edu.bonn.xulu.XuluModellingPlatform;
23 import edu.bonn.xulu.appl.ModelControlManager;
24 import edu.bonn.xulu.gui.ModelControlFrame;
25 import edu.bonn.xulu.model.XuluModel;
26 import edu.bonn.xulu.plugin.gui.ModelControlFrame_Basic;
27
28 /**
29 * The class allows to control several models at once. At the moment it provides
30 * a batch like execution functionality. It is still under development but
31 * should basically work. It was developed in very short time and is therefore
32 * not as well commented, as other classes.
33 *
34 * @author Dominik Appl
35 */
36 public class MultiModelControlHandler implements ListSelectionListener,
37 ObjectListener, ActionListener {
38
39 private MultiModelControlFrame frame;
40
41 private final XuluModellingPlatform xulu;
42
43 private DefaultListModel modelListModel;
44
45 private ParallelControlPanelEngine parallelControlPanelEngine;
46
47 private DefaultListModel commandListModel;
48
49 private InterpretingThread interpretingThread;
50
51 private TextAreaPrintStream consoleStream;
52
53 private String string;
54
55 public MultiModelControlHandler(XuluModellingPlatform xulu) {
56 this.xulu = xulu;
57 frame = new MultiModelControlFrame();
58 initGUI();
59 consoleStream = new TextAreaPrintStream(frame.console);
60 }
61
62 /**
63 *
64 */
65 private void initGUI() {
66 // register as listener for changes in the ModelControlManager
67 xulu.getModelControlManager().addObjectListener(this);
68 // init model list
69 initModelList();
70 initCommandList();
71 registerListeners();
72 }
73
74 /**
75 *
76 */
77 private void registerListeners() {
78 frame.addStepCommand.addActionListener(this);
79 frame.newOverAllStep.addActionListener(this);
80 frame.clearModelSteps.addActionListener(this);
81 frame.startButton.addActionListener(this);
82 frame.stopButton.addActionListener(this);
83 frame.stepButton.addActionListener(this);
84 frame.modelList.addMouseListener(new java.awt.event.MouseAdapter() {
85 public void mouseClicked(java.awt.event.MouseEvent e) {
86 if (e.getClickCount() == 2) {
87 handleModelListDoubleClick();
88 }
89 }
90 });
91 }
92
93 /**
94 *
95 */
96 private void initCommandList() {
97 commandListModel = new DefaultListModel();
98 frame.syncCommandList.setModel(commandListModel);
99 commandListModel.addElement(new StartCommand());
100 commandListModel.addElement(new StopCommand());
101 frame.syncCommandList
102 .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
103 frame.syncCommandList.setSelectedIndex(0);
104 }
105
106 /**
107 * inits the modelList
108 */
109 private void initModelList() {
110 modelListModel = new DefaultListModel();
111 frame.modelList.setModel(modelListModel);
112 frame.modelList.addListSelectionListener(this);
113 int modelCount = xulu.getModelControlManager().getCount();
114 for (int i = 0; i < modelCount; i++) {
115 ModelControlFrame frame = xulu.getModelControlManager().getAll()[i];
116 this.addModelControlFrame(frame);
117 }
118 // frame.modelList.add(frame.modelPopupMenu);
119 }
120
121 public MultiModelControlFrame getFrame() {
122 return frame;
123 }
124
125 /*
126 * (non-Javadoc)
127 *
128 * @see schmitzm.data.event.ObjectListener#performObjectEvent(schmitzm.data.event.ObjectEvent)
129 */
130 public void performObjectEvent(ObjectEvent e) {
131 // only listen for ChangeEvents
132 if (!(e instanceof ModelControlManager.ChangeEvent))
133 return;
134 ModelControlManager.ChangeEvent event = (ModelControlManager.ChangeEvent) e;
135 // if model was added:
136 if (event.getOldValue() == null && event.getNewValue() != null
137 && event.getNewValue() instanceof ModelControlFrame)
138 addModelControlFrame((ModelControlFrame) event.getNewValue());
139 // if model was removed
140 if (event.getOldValue() != null && event.getNewValue() == null
141 && event.getOldValue() instanceof ModelControlFrame)
142 removeModelControlFrame((ModelControlFrame) event.getOldValue());
143 }
144
145 /**
146 * @param model
147 */
148 private void addModelControlFrame(ModelControlFrame frame2) {
149 modelListModel.addElement(new ModelListObject(frame2,
150 frame2.getModel(), frame2.getModel().getName()));
151
152 }
153
154 /**
155 * Removes the model, which belongs to the specified ModelControlFrame from
156 * the list in the MCC
157 *
158 * @param frame2
159 * the ModelControlFrame from the removed model
160 */
161 private void removeModelControlFrame(ModelControlFrame frame2) {
162 // find the index of the model in the vector
163 for (int i = 0; i < modelListModel.size(); i++) {
164 ModelListObject m = (ModelListObject) modelListModel.get(i);
165 if (frame2.equals(m.getFrame()))
166 modelListModel.remove(i);
167 }
168 }
169
170 /**
171 * @return the actually selected ModelListObject from the model list
172 */
173 private ModelListObject getSelectedModelListObject() {
174 return (ModelListObject) frame.modelList.getSelectedValue();
175
176 }
177
178 /*
179 * (non-Javadoc)
180 *
181 * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
182 */
183 public void valueChanged(ListSelectionEvent e) {
184 // TODO Auto-generated method stub
185 }
186
187 abstract class ModelCommand {
188 protected boolean finished = false;
189
190 public abstract String toString();
191
192 public void execute() {
193 finished = true;
194 }
195
196 public void reset() {
197 finished = false;
198 }
199
200 // /**
201 // * executed after all commands are executed
202 // */
203 // public void dispose()
204 // {
205 //
206 // }
207
208 /**
209 * @return true, if the execution is finished and no further execution
210 * is required
211 */
212 public boolean hasFinished() {
213 return finished;
214 }
215
216 /**
217 * tries to stop the execution of the command
218 */
219 public void stop() {
220 };
221
222 /**
223 * @return Message to be displayed in the console
224 */
225 public String startMessage() {
226 return null;
227 }
228
229 /**
230 * @return Message to be displayed
231 */
232 public String finshedMessage() {
233 return null;
234 }
235 }
236
237 class RepeatStartCommand extends ModelCommand {
238 private final int execTimes;
239
240 private int alreadyExec;
241
242 /**
243 * @param execTimes
244 */
245 public RepeatStartCommand(int execTimes) {
246 this.execTimes = execTimes;
247 alreadyExec = 0;
248 // TODO Auto-generated constructor stub
249 }
250
251 public String toString() {
252 return "Start Repeat (" + execTimes + " exec)";
253 }
254
255 /*
256 * (non-Javadoc)
257 *
258 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
259 */
260 @Override
261 public String finshedMessage() {
262 return "Starting Repeat (" + (alreadyExec) + "/" + execTimes + ")";
263 }
264
265 /*
266 * (non-Javadoc)
267 *
268 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
269 */
270 @Override
271 public String startMessage() {
272 return null;
273 }
274
275 /*
276 * (non-Javadoc)
277 *
278 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#execute()
279 */
280 @Override
281 public void execute() {
282 alreadyExec++;
283 finished = true;
284 }
285
286 public void reset() {
287 finished = false;
288 alreadyExec = 0;
289 }
290 }
291
292 /**
293 * The commands between start and stop are repeated
294 *
295 * @author Dominik Appl
296 */
297 class RepeatStopCommand extends ModelCommand {
298 private final int execTimes;
299
300 private int alreadyExec;
301
302 /**
303 * @param execTimes
304 */
305 public RepeatStopCommand(int execTimes) {
306 this.execTimes = execTimes;
307 alreadyExec = 0;
308 }
309
310 public String toString() {
311 return "End Repeat (" + execTimes + " exec)";
312 }
313
314 /*
315 * (non-Javadoc)
316 *
317 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
318 */
319 @Override
320 public String finshedMessage() {
321 return "Loop iteration finished.(" + alreadyExec + "/" + execTimes
322 + ")";
323 }
324
325 /*
326 * (non-Javadoc)
327 *
328 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
329 */
330 @Override
331 public String startMessage() {
332 return null;
333 }
334
335 /*
336 * (non-Javadoc)
337 *
338 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#execute()
339 */
340 @Override
341 public void execute() {
342 alreadyExec++;
343 if (alreadyExec == execTimes)
344 finished = true;
345 }
346
347 public void reset() {
348 finished = false;
349 alreadyExec = 0;
350 }
351 }
352
353 class StartCommand extends ModelCommand {
354 public String toString() {
355 return "------- START MODELLING -------";
356 }
357
358 /*
359 * (non-Javadoc)
360 *
361 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
362 */
363 @Override
364 public String finshedMessage() {
365 return "Starting execution...";
366 }
367
368 }
369
370 class StopCommand extends ModelCommand {
371 public String toString() {
372 return "------- MODELLING FINISHED -------";
373 }
374
375 /*
376 * (non-Javadoc)
377 *
378 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
379 */
380 @Override
381 public String finshedMessage() {
382 return "Finished execution";
383 }
384
385 /*
386 * (non-Javadoc)
387 *
388 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
389 */
390 @Override
391 public String startMessage() {
392 return null;
393 }
394 }
395
396 class ModelStepCommand extends ModelCommand {
397 private ModelControlFrame_Basic controlFrame;
398
399 private final Lock lock = new ReentrantLock();
400
401 private final Condition threadStillRunning = lock.newCondition();
402
403 private String name;
404
405 private XuluModel model;
406
407 private final int execTimes;
408
409 private int finishedExecutions = 0;
410
411 public void reset() {
412 finishedExecutions = 0;
413 }
414
415 /**
416 *
417 */
418 public ModelStepCommand(ModelListObject mlo, int execTimes) {
419 this.execTimes = execTimes;
420 if (!(mlo.getFrame() instanceof ModelControlFrame_Basic))
421 throw new UnsupportedOperationException(
422 "The modelframe must be an instance of ModelControlFrame_Basic");
423 controlFrame = (ModelControlFrame_Basic) mlo.getFrame();
424 name = mlo.getName();
425 model = mlo.getModel();
426 }
427
428 public void execute() {
429 // check first if the model must be initialised
430 if (!model.isInitialised() && !model.isRunning()) {
431 controlFrame.setModelResources();
432 controlFrame.getControlContainer().init();
433 }
434 lock.lock();
435 try {
436 WorkingThreadAdapter adapter = new WorkingThreadAdapter() {
437 /*
438 * (non-Javadoc)
439 *
440 * @see schmitzm.lang.WorkingThreadAdapter#threadPaused(schmitzm.lang.WorkingThread)
441 */
442 @Override
443 public void threadPaused(WorkingThread thread) {
444 try {
445 lock.lock();
446 // signal finished if the step is finished
447 threadStillRunning.signal();
448 } finally {
449 lock.unlock();
450 }
451 }
452
453 /*
454 * (non-Javadoc)
455 *
456 * @see schmitzm.lang.WorkingThreadAdapter#threadStopped(schmitzm.lang.WorkingThread)
457 */
458 @Override
459 public void threadStopped(WorkingThread thread) {
460 try {
461 lock.lock();
462 // signal finished if the step is finished
463 threadStillRunning.signal();
464 } finally {
465 lock.unlock();
466 }
467 }
468 };
469 controlFrame.getControlContainer().getModelThread()
470 .addThreadListener(adapter);
471 controlFrame.getControlContainer().step();
472 // wait for the model step to finish
473 threadStillRunning.await();
474 controlFrame.getControlContainer().getModelThread()
475 .removeThreadListener(adapter);
476 finishedExecutions++;
477 } catch (InterruptedException e) {
478 // TODO Auto-generated catch block
479 e.printStackTrace();
480 } finally {
481 lock.unlock();
482 }
483 }
484
485 public void stop() {
486 if (!model.isStopped())
487 controlFrame.getControlContainer().stop();
488 // try {
489 // controlFrame.getControlContainer().getModelThread().join();
490 // } catch (InterruptedException e) {
491 // // TODO Auto-generated catch block
492 // e.printStackTrace();
493 // }
494 }
495
496 @Override
497 public boolean hasFinished() {
498 return finishedExecutions >= execTimes;
499 }
500
501 /*
502 * (non-Javadoc)
503 *
504 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#toString()
505 */
506 @Override
507 public String toString() {
508 return name + " (" + execTimes + " exec)";
509 }
510
511 /*
512 * (non-Javadoc)
513 *
514 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#finshedMessage()
515 */
516 @Override
517 public String finshedMessage() {
518 return "...finished";
519 }
520
521 /*
522 * (non-Javadoc)
523 *
524 * @see appl.plugin.multimodelcontrol.MultiModelControlHandler.ModelCommand#startMessage()
525 */
526 @Override
527 public String startMessage() {
528 return "Executing step of " + name;
529 }
530
531 }
532
533 /*
534 * (non-Javadoc)
535 *
536 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
537 */
538 public void actionPerformed(ActionEvent e) {
539 if (e.getSource() == frame.addStepCommand) {
540 handleAddNewStep();
541 }
542 if (e.getSource() == frame.newOverAllStep) {
543 handleRepeatStep();
544 }
545 if (e.getSource() == frame.startButton) {
546 startInterpreting();
547 }
548 if (e.getSource() == frame.stopButton) {
549 if (interpretingThread != null) {
550 interpretingThread.stopThread();
551 }
552 // ToDO: dispose all models
553
554 }
555 if (e.getSource() == frame.clearModelSteps) {
556 int delIdx = frame.syncCommandList.getSelectedIndex();
557 // do not delete first or last entry
558 if (delIdx > 0 && delIdx < commandListModel.getSize() - 1)
559 commandListModel.remove(delIdx);
560 frame.syncCommandList.setSelectedIndex(delIdx);
561
562 }
563 }
564
565 /**
566 *
567 */
568 private void handleAddNewStep() {
569 if (checkInsertAllowed()) {
570 if (getSelectedModelListObject() == null) {
571 JOptionPane.showMessageDialog(null, "No model selected",
572 "No model selected", JOptionPane.ERROR_MESSAGE);
573 return;
574 }
575 int selIdx = frame.syncCommandList.getSelectedIndex();
576 int execTimes = 1;
577 // get execution times from user
578 try {
579 string = JOptionPane.showInputDialog(frame,
580 "How many steps do you want to execute for this enty?",
581 1);
582 execTimes = Integer.valueOf(string);
583 if (execTimes <= 0)
584 throw new UnsupportedOperationException(
585 "Only positive number allowed!");
586 } catch (Exception ex) {
587 JOptionPane.showMessageDialog(null,
588 "Only positive number allowed", "Error",
589 JOptionPane.ERROR_MESSAGE);
590 return;
591 }
592 commandListModel.add(selIdx + 1, new ModelStepCommand(
593 getSelectedModelListObject(), execTimes));
594 // select new entry
595 frame.syncCommandList.setSelectedIndex(selIdx + 1);
596 }
597 }
598
599 /**
600 *
601 */
602 protected void handleModelListDoubleClick() {
603 ModelListObject selectedModelListObject = getSelectedModelListObject();
604 if (selectedModelListObject != null) {
605 selectedModelListObject.getFrame().setVisible(true);
606 selectedModelListObject.getFrame().toFront();
607 }
608
609 }
610
611 /**
612 *
613 */
614 private void handleRepeatStep() {
615 if (checkInsertAllowed()) {
616 int selIdx = frame.syncCommandList.getSelectedIndex();
617 int execTimes = 1;
618 // get execution times from user
619 try {
620 string = JOptionPane.showInputDialog(frame,
621 "How many steps do you want to execute for this enty?",
622 1);
623 execTimes = Integer.valueOf(string);
624 if (execTimes <= 0)
625 throw new UnsupportedOperationException(
626 "Only positive numbers allowed!");
627 } catch (Exception ex) {
628 JOptionPane.showMessageDialog(null,
629 "Only positive numbers allowed", "Error",
630 JOptionPane.ERROR_MESSAGE);
631 return;
632 }
633 commandListModel.add(selIdx + 1, new RepeatStartCommand(execTimes));
634 commandListModel.add(selIdx + 2, new RepeatStopCommand(execTimes));
635
636 // select new entry
637 frame.syncCommandList.setSelectedIndex(selIdx + 1);
638 }
639 }
640
641 private void startInterpreting() {
642 // clear console and start Thread
643 frame.console.setText("");
644 interpretingThread = new InterpretingThread();
645 interpretingThread.start();
646
647 }
648
649 public void toggleGUI(boolean enabled) {
650 frame.modelList.setEnabled(enabled);
651 frame.addStepCommand.setEnabled(enabled);
652 frame.newOverAllStep.setEnabled(enabled);
653 frame.clearModelSteps.setEnabled(enabled);
654 if (enabled)
655 frame.syncCommandList.setSelectionBackground(Color.LIGHT_GRAY);
656 else
657 frame.syncCommandList.setSelectionBackground(Color.red);
658 }
659
660 /**
661 * insert is allowed if its not the last position
662 */
663 private boolean checkInsertAllowed() {
664 if (commandListModel.getSize() - 1 > frame.syncCommandList
665 .getSelectedIndex())
666 return true;
667 JOptionPane.showMessageDialog(null,
668 "You can add nothing after the end command!", "Error",
669 JOptionPane.ERROR_MESSAGE);
670 return false;
671 }
672
673 /**
674 * Interprets the commandlist
675 *
676 * @author Dominik Appl
677 */
678 class InterpretingThread extends Thread {
679
680 private boolean exit;
681
682 private ModelCommand currentCommand;
683
684 /**
685 * Creates a new Thread
686 */
687 public InterpretingThread() {
688 exit = false;
689 }
690
691 /**
692 * stops the Thread execution
693 */
694 public void stopThread() {
695 exit = true;
696 if (currentCommand != null)
697 currentCommand.stop();
698 }
699
700 public void run() {
701 toggleGUI(false);
702 // reset all commands
703 for (int i = 0; i < frame.syncCommandList.getModel().getSize(); i++)
704 ((ModelCommand) frame.syncCommandList.getModel()
705 .getElementAt(i)).reset();
706 // select first element
707 try {
708 frame.syncCommandList.setSelectedIndex(0);
709 int currentIdx = 0;
710 while (exit != true) {
711 currentCommand = (ModelCommand) commandListModel
712 .getElementAt(currentIdx);
713 // if the current command is an end of of a global loop
714 // than go back in the list until the start of the loop is
715 // found
716 if (currentCommand instanceof RepeatStopCommand) {
717 currentCommand.execute();
718 // if the all steps are done, just go on
719 if (currentCommand.hasFinished()) {
720 currentIdx++;
721 currentCommand = (ModelCommand) commandListModel
722 .getElementAt(currentIdx);
723 }
724 // else do the repetition by decreasing the index
725 // until the RepeatStartCommand is reached
726 else {
727 while (!(currentCommand instanceof RepeatStartCommand)) {
728 currentIdx--;
729 // if some structure error occured:
730 if (currentIdx <= 0) {
731 JOptionPane
732 .showMessageDialog(
733 frame,
734 "Something is wrong with the command structure. Do not use nested loops or other komplex structures!");
735 exit = true;
736 break;
737 }
738 currentCommand = (ModelCommand) commandListModel
739 .getElementAt(currentIdx);
740 }
741 }
742
743 }
744 if (currentCommand.startMessage() != null)
745 consoleStream.print(currentCommand.startMessage());
746 frame.syncCommandList.setSelectedIndex(currentIdx);
747 currentCommand.execute();
748 if (currentCommand.finshedMessage() != null)
749 consoleStream.println(currentCommand.finshedMessage());
750 // if the command has finished executing, get the next
751 // command
752 if (currentCommand.hasFinished())
753 currentIdx++;
754 if (currentIdx == commandListModel.getSize())
755 exit = true;
756 }
757 } catch (Exception e) {
758 e.printStackTrace();
759 } finally {
760 toggleGUI(true);
761 }
762 }
763 }
764
765 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26