/[xulu]/trunk/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java
ViewVC logotype

Annotation of /trunk/src/appl/plugin/multimodelcontrol/MultiModelControlHandler.java

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26