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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 60 - (hide annotations)
Sun Oct 4 16:54:52 2009 UTC (15 years, 2 months ago) by alfonx
File size: 20205 byte(s)
* organized imports
1 mojays 2 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 alfonx 60 import appl.parallel.gui.ParallelControlPanelEngine;
22 mojays 2 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 alfonx 33 * @return the actually selected ModelListObject from the model list
172 mojays 2 */
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