001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026: package org.cougaar.mlm.plugin.sample;
027:
028: import java.awt.Color;
029: import java.awt.Component;
030: import java.awt.Container;
031: import java.awt.Graphics;
032: import java.awt.GridBagConstraints;
033: import java.awt.GridBagLayout;
034: import java.awt.Insets;
035: import java.awt.event.ActionEvent;
036: import java.awt.event.ActionListener;
037: import java.text.DateFormat;
038: import java.text.DecimalFormat;
039: import java.text.FieldPosition;
040: import java.text.NumberFormat;
041: import java.text.SimpleDateFormat;
042: import java.util.Comparator;
043: import java.util.Enumeration;
044: import java.util.Iterator;
045: import java.util.SortedMap;
046: import java.util.TreeMap;
047:
048: import javax.swing.ButtonGroup;
049: import javax.swing.Icon;
050: import javax.swing.JButton;
051: import javax.swing.JCheckBox;
052: import javax.swing.JFrame;
053: import javax.swing.JLabel;
054: import javax.swing.JRadioButton;
055: import javax.swing.JScrollPane;
056: import javax.swing.JTable;
057: import javax.swing.SwingUtilities;
058: import javax.swing.table.AbstractTableModel;
059: import javax.swing.table.TableCellRenderer;
060: import javax.swing.table.TableColumnModel;
061:
062: import org.cougaar.core.blackboard.IncrementalSubscription;
063: import org.cougaar.mlm.plugin.UICoordinator;
064: import org.cougaar.planning.ldm.plan.AllocationResult;
065: import org.cougaar.planning.ldm.plan.PlanElement;
066: import org.cougaar.planning.ldm.plan.PlanElementSet;
067: import org.cougaar.planning.ldm.plan.Task;
068: import org.cougaar.planning.plugin.legacy.SimplePlugin;
069: import org.cougaar.util.UnaryPredicate;
070:
071: /**
072: *
073: */
074:
075: public class CompletionAssessor extends SimplePlugin {
076: private static final boolean BRIEF = false; // True for task id only
077:
078: public static final int KIND_UNDISPOSED = 0; // No plan element
079: public static final int KIND_UNKNOWN = 1; // No allocation result
080: public static final int KIND_INCOMPLETE = 2; // Confidence < 100%
081: public static final int KIND_FAILURE = 3; // Allocation failure
082: public static final int KIND_SUCCESS = 4; // Allocation success
083: public static final int NKINDS = 5;
084:
085: private static class MyPrivateState implements java.io.Serializable {
086: boolean undisposedEnabled = true;
087: boolean unknownEnabled = true;
088: boolean incompleteEnabled = true;
089: boolean failureEnabled = true;
090: boolean successEnabled = false;
091: boolean estimatedEnabled = true;
092: boolean onDemandEnabled = true;
093: }
094:
095: /** frame displaying messages **/
096: private JFrame frame;
097:
098: private static DateFormat logTimeFormat = new SimpleDateFormat(
099: "yyyy/MM/dd HH:mm:ss.SSS");
100:
101: static NumberFormat confidenceFormat = NumberFormat
102: .getPercentInstance();
103:
104: private static DecimalFormat labelCountFormat = new DecimalFormat(
105: "####0");
106:
107: private static String formatLabel(int count, String kind) {
108: try {
109: return (labelCountFormat.format(count, new StringBuffer(),
110: new FieldPosition(NumberFormat.INTEGER_FIELD))
111: .append(" ").append(kind).append(" tasks")
112: .substring(0));
113: } catch (Exception e) {
114: e.printStackTrace();
115: return "bogus";
116: }
117: }
118:
119: static class TaskComparator implements Comparator {
120: public int compare(Object o1, Object o2) {
121: if (!(o1 instanceof Task) || !(o2 instanceof Task)) {
122: throw new IllegalArgumentException("Not a Task");
123: }
124: Task task1 = (Task) o1;
125: Task task2 = (Task) o2;
126: return task1.getUID().toString().compareTo(
127: task2.getUID().toString());
128: }
129: }
130:
131: static TaskComparator taskComparator = new TaskComparator();
132:
133: class MyModel extends AbstractTableModel {
134: private TreeMap elements = new TreeMap(taskComparator);
135: private Task[] elementArray = null;
136: private boolean[] includedKinds = new boolean[NKINDS]; // The kinds currently included in elementArray
137:
138: public synchronized boolean contains(Task task) {
139: return elements.containsKey(task);
140: }
141:
142: public int getKind(Task task) {
143: Wrapper wrapper = (Wrapper) elements.get(task);
144: if (wrapper == null)
145: return KIND_UNDISPOSED;
146: return wrapper.getKind();
147: }
148:
149: public synchronized void add(Task task) {
150: if (!contains(task)) {
151: Wrapper wrapper = new Wrapper(task);
152: elements.put(task, wrapper);
153: int previousRow = -1;
154: SortedMap headMap = elements.headMap(task);
155: if (headMap.size() > 0) {
156: Task previousTask = (Task) headMap.lastKey();
157: Wrapper previousWrapper = (Wrapper) headMap
158: .get(previousTask);
159: previousRow = previousWrapper.getRow();
160: }
161: if (includedKinds[wrapper.getKind()]) {
162: elementArray = null;
163: int row = previousRow + 1;
164: fireTableRowsInserted(row, row);
165: } else {
166: wrapper.setRow(previousRow);
167: }
168: }
169: }
170:
171: public synchronized void remove(Task task) {
172: if (contains(task)) {
173: Wrapper wrapper = (Wrapper) elements.remove(task);
174: if (includedKinds[wrapper.getKind()]) {
175: elementArray = null;
176: int row = wrapper.getRow();
177: fireTableRowsDeleted(row, row);
178: }
179: }
180: }
181:
182: public synchronized void change(Task task) {
183: if (contains(task)) {
184: Wrapper wrapper = (Wrapper) elements.get(task);
185: boolean wasIncluded = includedKinds[wrapper.getKind()];
186: change(wrapper);
187: boolean isIncluded = includedKinds[wrapper.getKind()];
188: if (isIncluded) {
189: if (wasIncluded) {
190: fireTableRowsUpdated(wrapper.getRow(), wrapper
191: .getRow());
192: } else {
193: elementArray = null;
194: int row = wrapper.getRow() + 1;
195: fireTableRowsInserted(row, row);
196: }
197: } else {
198: if (wasIncluded) {
199: elementArray = null;
200: int row = wrapper.getRow();
201: fireTableRowsDeleted(row, row);
202: } else {
203: // No visibility change
204: }
205: }
206: }
207: }
208:
209: private void change(Wrapper wrapper) {
210: wrapper.updateKind();
211: }
212:
213: public synchronized void removeAll() {
214: elements.clear();
215: elementArray = null;
216: fireTableDataChanged();
217: }
218:
219: public synchronized void changeAll() {
220: for (Iterator iterator = elements.values().iterator(); iterator
221: .hasNext();) {
222: change((Wrapper) iterator.next());
223: }
224: elementArray = null;
225: fireTableDataChanged();
226: }
227:
228: private int getKindCount(int kind) {
229: int count = 0;
230: for (Iterator iter = elements.values().iterator(); iter
231: .hasNext();) {
232: Wrapper wrapper = (Wrapper) iter.next();
233: if (wrapper.getKind() == kind) {
234: count++;
235: }
236: }
237: return count;
238: }
239:
240: public int getUndisposedCount() {
241: return getKindCount(KIND_UNDISPOSED);
242: }
243:
244: public int getUnknownCount() {
245: return getKindCount(KIND_UNKNOWN);
246: }
247:
248: public int getIncompleteCount() {
249: return getKindCount(KIND_INCOMPLETE);
250: }
251:
252: public int getFailureCount() {
253: return getKindCount(KIND_FAILURE);
254: }
255:
256: public int getSuccessCount() {
257: return getKindCount(KIND_SUCCESS);
258: }
259:
260: public synchronized int getRowCount() {
261: insureElementArray();
262: return elementArray.length;
263: }
264:
265: public int getColumnCount() {
266: return 4;
267: }
268:
269: public Class getColumnClass(int column) {
270: switch (column) {
271: case 0:
272: return Boolean.class;
273: case 1:
274: return String.class;
275: case 2:
276: return Task.class;
277: case 3:
278: return PlanElement.class;
279: default:
280: return String.class;
281: }
282: }
283:
284: public String getColumnName(int column) {
285: switch (column) {
286: case 0:
287: return "Ok";
288: case 1:
289: return "Conf";
290: case 2:
291: return "Task";
292: case 3:
293: return "Disposition";
294: }
295: return null;
296: }
297:
298: private void insureElementArray() {
299: if (elementArray == null) {
300: includedKinds[KIND_UNDISPOSED] = myPrivateState.undisposedEnabled;
301: includedKinds[KIND_UNKNOWN] = myPrivateState.unknownEnabled;
302: includedKinds[KIND_INCOMPLETE] = myPrivateState.incompleteEnabled;
303: includedKinds[KIND_FAILURE] = myPrivateState.failureEnabled;
304: includedKinds[KIND_SUCCESS] = myPrivateState.successEnabled;
305: int count = 0;
306: for (Iterator iter = elements.values().iterator(); iter
307: .hasNext();) {
308: Wrapper wrapper = (Wrapper) iter.next();
309: wrapper.setRow(count);
310: if (includedKinds[wrapper.getKind()]) {
311: count++;
312: }
313: }
314: elementArray = new Task[count];
315: count = 0;
316: for (Iterator iter = elements.values().iterator(); iter
317: .hasNext();) {
318: Wrapper wrapper = (Wrapper) iter.next();
319: if (includedKinds[wrapper.getKind()]) {
320: elementArray[count++] = wrapper.getTask();
321: }
322: }
323: }
324: }
325:
326: public synchronized Task getTask(int row) {
327: insureElementArray();
328: if (row >= elementArray.length)
329: return null;
330: return elementArray[row];
331: }
332:
333: public synchronized Object getValueAt(int row, int column) {
334: Task task = getTask(row);
335: Object result = "<null>";
336: PlanElement pe = getPlanElement(task);
337: switch (column) {
338: case 0:
339: if (pe == null) {
340: result = Boolean.FALSE;
341: } else {
342: AllocationResult ar = getAllocationResult(pe);
343: if (ar == null) {
344: result = Boolean.TRUE;
345: } else {
346: result = new Boolean(ar.isSuccess());
347: }
348: }
349: break;
350:
351: case 1:
352: if (pe == null) {
353: result = "??";
354: } else {
355: AllocationResult ar = getAllocationResult(pe);
356: if (ar == null) {
357: result = "??";
358: } else {
359: result = confidenceFormat.format(ar
360: .getConfidenceRating());
361: }
362: }
363: break;
364:
365: case 2:
366: result = task;
367: break;
368:
369: case 3:
370: if (pe == null) {
371: result = "Not Disposed";
372: } else {
373: result = pe;
374: }
375: break;
376: }
377: return result;
378: }
379: }
380:
381: private AllocationResult getAllocationResult(PlanElement pe) {
382: if (showEstimated.isSelected()) {
383: return pe.getEstimatedResult();
384: } else {
385: return pe.getReportedResult();
386: }
387: }
388:
389: private class Wrapper {
390: private int kind;
391: private Task task;
392: private int row = -1;
393:
394: Wrapper(Task task) {
395: this .task = task;
396: updateKind();
397: }
398:
399: private void updateKind() {
400: PlanElement pe = getPlanElement(task);
401: if (pe == null) {
402: kind = KIND_UNDISPOSED;
403: } else {
404: AllocationResult ar = getAllocationResult(pe);
405: if (ar == null) {
406: kind = KIND_UNKNOWN;
407: } else if (ar.getConfidenceRating() < 1.0) {
408: kind = KIND_INCOMPLETE;
409: } else if (ar.isSuccess()) {
410: kind = KIND_SUCCESS;
411: } else {
412: kind = KIND_FAILURE;
413: }
414: }
415: }
416:
417: public int getKind() {
418: return kind;
419: }
420:
421: public Task getTask() {
422: return task;
423: }
424:
425: public int getRow() {
426: return row;
427: }
428:
429: public void setRow(int newRow) {
430: row = newRow;
431: }
432: }
433:
434: /** Display Allocation Results **/
435: static class WhiteBlankIcon implements Icon {
436: public int getIconHeight() {
437: return 13;
438: }
439:
440: public int getIconWidth() {
441: return 13;
442: }
443:
444: public void paintIcon(Component c, Graphics g, int x, int y) {
445: g.setColor(Color.black);
446: g.drawRect(x, y, 11, 11);
447: g.setColor(Color.white);
448: g.drawRect(x + 1, y + 1, 11, 11);
449: }
450: }
451:
452: static class WhiteCheckIcon extends WhiteBlankIcon implements Icon {
453: public void paintIcon(Component c, Graphics g, int x, int y) {
454: super .paintIcon(c, g, x, y);
455: g.setColor(Color.white);
456: g.drawLine(x + 3, y + 5, x + 3, y + 9);
457: g.drawLine(x + 4, y + 5, x + 4, y + 9);
458: g.drawLine(x + 5, y + 7, x + 9, y + 3);
459: g.drawLine(x + 5, y + 8, x + 9, y + 4);
460: }
461: }
462:
463: Icon whiteCheckIcon = new WhiteCheckIcon();
464: Icon whiteBlankIcon = new WhiteBlankIcon();
465: JRadioButton showEstimated = new JRadioButton(
466: "Show Estimated Result");
467: JRadioButton showReported = new JRadioButton("Show Reported Result");
468: ButtonGroup showGroup = new ButtonGroup();
469: JRadioButton showOnDemand = new JRadioButton("Show On Demand");
470: JRadioButton showContinuously = new JRadioButton(
471: "Show Continuously");
472: ButtonGroup demandGroup = new ButtonGroup();
473: JButton updateButton = new JButton("Update");
474: JCheckBox undisposedCountLabel = new JCheckBox(formatLabel(0,
475: "undisposed"), whiteBlankIcon, true);
476: JCheckBox unknownCountLabel = new JCheckBox(formatLabel(0,
477: "unknown"), whiteBlankIcon, true);
478: JCheckBox incompleteCountLabel = new JCheckBox(formatLabel(0,
479: "incomplete"), null, true);
480: JCheckBox failureCountLabel = new JCheckBox(
481: formatLabel(0, "failed"), whiteBlankIcon, true);
482: JCheckBox successCountLabel = new JCheckBox(formatLabel(0,
483: "successful"), whiteBlankIcon, false);
484: MyModel model;
485: JTable table;
486: JScrollPane pane;
487:
488: static JTable createTable(MyModel model) {
489: try {
490: return new JTable(model);
491: } catch (RuntimeException e) {
492: e.printStackTrace();
493: }
494: return null;
495: }
496:
497: /** Subscription to hold collection of input tasks **/
498: private PlanElementSet planElementSet = new PlanElementSet();
499: private IncrementalSubscription myPlanElements;
500:
501: /** Look for dispositions **/
502: private static UnaryPredicate planElementP = new UnaryPredicate() {
503: public boolean execute(Object o) {
504: return (o instanceof PlanElement);
505: }
506: };
507:
508: /** Look for tasks **/
509: private IncrementalSubscription myTasks;
510: private static UnaryPredicate taskP = new UnaryPredicate() {
511: public boolean execute(Object o) {
512: return o instanceof Task;
513: }
514: };
515:
516: /** Look for private state **/
517: private MyPrivateState myPrivateState;
518: private IncrementalSubscription myState;
519: private static UnaryPredicate stateP = new UnaryPredicate() {
520: public boolean execute(Object o) {
521: return o instanceof MyPrivateState;
522: }
523: };
524:
525: private void fixedWidth(TableColumnModel columnModel, int column,
526: int width) {
527: columnModel.getColumn(column).setPreferredWidth(width);
528: columnModel.getColumn(column).setMaxWidth(width);
529: columnModel.getColumn(column).setMinWidth(width);
530: }
531:
532: private Color getForeground(int kind) {
533: switch (kind) {
534: default:
535: case KIND_UNDISPOSED:
536: return Color.white;
537: case KIND_UNKNOWN:
538: return Color.white;
539: case KIND_INCOMPLETE:
540: return Color.black;
541: case KIND_FAILURE:
542: return Color.white;
543: case KIND_SUCCESS:
544: return Color.white;
545: }
546: }
547:
548: private Color getBackground(int kind) {
549: switch (kind) {
550: case KIND_UNDISPOSED:
551: return new Color(150, 0, 150);
552: case KIND_UNKNOWN:
553: return new Color(0, 0, 200);
554: case KIND_INCOMPLETE:
555: return Color.yellow;
556: case KIND_FAILURE:
557: return new Color(200, 0, 0);
558: case KIND_SUCCESS:
559: return new Color(0, 150, 0);
560: default:
561: return Color.white;
562: }
563: }
564:
565: /** GUI to display failed disposition info **/
566: private void createGUI() {
567: model = new MyModel();
568: table = createTable(model);
569: pane = new JScrollPane(table,
570: JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
571: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
572: TableColumnModel columnModel = table.getColumnModel();
573: fixedWidth(columnModel, 0, 20);
574: fixedWidth(columnModel, 1, 40);
575: table.setAutoResizeMode(table.AUTO_RESIZE_LAST_COLUMN);
576: TableCellRenderer renderer = new TableCellRenderer() {
577: private JLabel taskLabel = null;
578:
579: public Component getTableCellRendererComponent(
580: JTable table, Object value, boolean isSelected,
581: boolean hasFocus, int row, int column) {
582: Task task = model.getTask(row);
583: if (taskLabel == null) {
584: taskLabel = new JLabel();
585: taskLabel.setFont(table.getFont());
586: taskLabel.setOpaque(true);
587: taskLabel.setForeground(Color.black);
588: taskLabel.setBackground(Color.white);
589: }
590: int kind = model.getKind(task);
591: taskLabel.setForeground(getForeground(kind));
592: taskLabel.setBackground(getBackground(kind));
593: if (value != null) {
594: taskLabel.setText(value.toString());
595: taskLabel.setToolTipText(value.toString());
596: } else {
597: taskLabel.setText("<null>");
598: taskLabel.setToolTipText("");
599: }
600: return taskLabel;
601: }
602: };
603: table.setDefaultRenderer(Task.class, renderer);
604: table.setDefaultRenderer(PlanElement.class, renderer);
605: table.setDefaultRenderer(String.class, renderer);
606: frame = new JFrame(getMessageAddress() + " Completion Assessor");
607: Container panel = frame.getContentPane();
608: panel.setLayout(new GridBagLayout());
609: GridBagConstraints gbc = new GridBagConstraints();
610: Insets buttonInsets = new Insets(0, 5, 0, 5);
611: Insets paneInsets = new Insets(0, 0, 0, 0);
612: gbc.insets = buttonInsets;
613: gbc.weightx = 0.0;
614: gbc.fill = GridBagConstraints.HORIZONTAL;
615: gbc.gridx = 0;
616: gbc.gridy = 0;
617: undisposedCountLabel.setSelectedIcon(whiteCheckIcon);
618: undisposedCountLabel
619: .setBackground(getBackground(KIND_UNDISPOSED));
620: undisposedCountLabel
621: .setForeground(getForeground(KIND_UNDISPOSED));
622: undisposedCountLabel
623: .setToolTipText("Tasks which have not been disposed");
624: panel.add(undisposedCountLabel, gbc);
625: gbc.gridy = 1;
626: unknownCountLabel.setSelectedIcon(whiteCheckIcon);
627: unknownCountLabel.setBackground(getBackground(KIND_UNKNOWN));
628: unknownCountLabel.setForeground(getForeground(KIND_UNKNOWN));
629: unknownCountLabel
630: .setToolTipText("Tasks with no allocation result");
631: panel.add(unknownCountLabel, gbc);
632: gbc.gridy = 2;
633: incompleteCountLabel
634: .setBackground(getBackground(KIND_INCOMPLETE));
635: incompleteCountLabel
636: .setForeground(getForeground(KIND_INCOMPLETE));
637: incompleteCountLabel
638: .setToolTipText("Tasks with confidence ratind < 100%");
639: panel.add(incompleteCountLabel, gbc);
640: gbc.gridy = 3;
641: failureCountLabel.setSelectedIcon(whiteCheckIcon);
642: failureCountLabel.setBackground(getBackground(KIND_FAILURE));
643: failureCountLabel.setForeground(getForeground(KIND_FAILURE));
644: failureCountLabel
645: .setToolTipText("Tasks with failed disposition");
646: panel.add(failureCountLabel, gbc);
647: gbc.gridy = 4;
648: successCountLabel.setSelectedIcon(whiteCheckIcon);
649: successCountLabel.setBackground(getBackground(KIND_SUCCESS));
650: successCountLabel.setForeground(getForeground(KIND_SUCCESS));
651: successCountLabel
652: .setToolTipText("Tasks with successful disposition");
653: panel.add(successCountLabel, gbc);
654: gbc.gridx = 1;
655: gbc.gridy = 0;
656: panel.add(showEstimated, gbc);
657: gbc.gridy = 1;
658: panel.add(showReported, gbc);
659: showGroup.add(showEstimated);
660: showGroup.add(showReported);
661: gbc.gridy = 2;
662: panel.add(showOnDemand, gbc);
663: gbc.gridy = 3;
664: panel.add(showContinuously, gbc);
665: demandGroup.add(showContinuously);
666: demandGroup.add(showOnDemand);
667: gbc.gridy = 4;
668: panel.add(updateButton, gbc);
669: ActionListener updateAction = new ActionListener() {
670: public void actionPerformed(ActionEvent e) {
671: update();
672: }
673: };
674: updateButton.addActionListener(updateAction);
675: updateButton.setEnabled(false);
676:
677: undisposedCountLabel.addActionListener(new ActionListener() {
678: public void actionPerformed(ActionEvent e) {
679: setUndisposedEnabled(undisposedCountLabel.isSelected());
680: }
681: });
682: unknownCountLabel.addActionListener(new ActionListener() {
683: public void actionPerformed(ActionEvent e) {
684: setUnknownEnabled(unknownCountLabel.isSelected());
685: }
686: });
687: incompleteCountLabel.addActionListener(new ActionListener() {
688: public void actionPerformed(ActionEvent e) {
689: setIncompleteEnabled(incompleteCountLabel.isSelected());
690: }
691: });
692: failureCountLabel.addActionListener(new ActionListener() {
693: public void actionPerformed(ActionEvent e) {
694: setFailureEnabled(failureCountLabel.isSelected());
695: }
696: });
697: successCountLabel.addActionListener(new ActionListener() {
698: public void actionPerformed(ActionEvent e) {
699: setSuccessEnabled(successCountLabel.isSelected());
700: }
701: });
702: showEstimated.addActionListener(new ActionListener() {
703: public void actionPerformed(ActionEvent e) {
704: setEstimatedEnabled(showEstimated.isSelected());
705: }
706: });
707: showReported.addActionListener(new ActionListener() {
708: public void actionPerformed(ActionEvent e) {
709: setEstimatedEnabled(!showReported.isSelected());
710: }
711: });
712: showOnDemand.addActionListener(new ActionListener() {
713: public void actionPerformed(ActionEvent e) {
714: setOnDemandEnabled(showOnDemand.isSelected());
715: }
716: });
717: showContinuously.addActionListener(new ActionListener() {
718: public void actionPerformed(ActionEvent e) {
719: setOnDemandEnabled(!showContinuously.isSelected());
720: }
721: });
722: undisposedCountLabel
723: .setSelected(myPrivateState.undisposedEnabled);
724: unknownCountLabel.setSelected(myPrivateState.unknownEnabled);
725: incompleteCountLabel
726: .setSelected(myPrivateState.incompleteEnabled);
727: failureCountLabel.setSelected(myPrivateState.failureEnabled);
728: successCountLabel.setSelected(myPrivateState.successEnabled);
729: showEstimated.setSelected(myPrivateState.estimatedEnabled);
730: showReported.setSelected(!myPrivateState.estimatedEnabled);
731: showOnDemand.setSelected(myPrivateState.onDemandEnabled);
732: showContinuously.setSelected(!myPrivateState.onDemandEnabled);
733:
734: gbc.insets = paneInsets;
735: gbc.gridx = 0;
736: gbc.gridy = 5;
737: gbc.gridheight = 1;
738: gbc.gridwidth = 4;
739: gbc.fill = GridBagConstraints.BOTH;
740: gbc.weightx = 1.0;
741: gbc.weighty = 1.0;
742: panel.add(pane, gbc);
743: frame.pack();
744: UICoordinator.setBounds(frame);
745: frame.setVisible(true);
746: }
747:
748: public void unload() {
749: super .unload();
750: frame.dispose();
751: }
752:
753: private void setUndisposedEnabled(boolean v) {
754: if (v != myPrivateState.undisposedEnabled) {
755: myPrivateState.undisposedEnabled = v;
756: buttonsChanged();
757: }
758: }
759:
760: private void setUnknownEnabled(boolean v) {
761: if (v != myPrivateState.unknownEnabled) {
762: myPrivateState.unknownEnabled = v;
763: buttonsChanged();
764: }
765: }
766:
767: private void setIncompleteEnabled(boolean v) {
768: if (v != myPrivateState.incompleteEnabled) {
769: myPrivateState.incompleteEnabled = v;
770: buttonsChanged();
771: }
772: }
773:
774: private void setFailureEnabled(boolean v) {
775: if (v != myPrivateState.failureEnabled) {
776: myPrivateState.failureEnabled = v;
777: buttonsChanged();
778: }
779: }
780:
781: private void setSuccessEnabled(boolean v) {
782: if (v != myPrivateState.successEnabled) {
783: myPrivateState.successEnabled = v;
784: buttonsChanged();
785: }
786: }
787:
788: private void setEstimatedEnabled(boolean v) {
789: if (v != myPrivateState.estimatedEnabled) {
790: myPrivateState.estimatedEnabled = v;
791: buttonsChanged();
792: }
793: }
794:
795: private void setOnDemandEnabled(boolean v) {
796: if (v != myPrivateState.onDemandEnabled) {
797: myPrivateState.onDemandEnabled = v;
798: buttonsChanged();
799: }
800: }
801:
802: private void buttonsChanged() {
803: changeAll();
804: openTransaction();
805: publishChange(myPrivateState);
806: closeTransactionDontReset();
807: }
808:
809: /**
810: * Overrides the setupSubscriptions() in the SimplePlugin.
811: */
812: protected void setupSubscriptions() {
813: getSubscriber().setShouldBePersisted(false);
814: myState = (IncrementalSubscription) subscribe(stateP);
815: if (!didRehydrate()) {
816: publishAdd(new MyPrivateState());
817: }
818: }
819:
820: private void setupMainSubscriptions() {
821: myPlanElements = (IncrementalSubscription) subscribe(
822: planElementP, planElementSet, true);
823: myTasks = (IncrementalSubscription) subscribe(taskP);
824: }
825:
826: private void updateLabels() {
827: undisposedCountLabel.setText(formatLabel(model
828: .getUndisposedCount(), "undisposed"));
829: unknownCountLabel.setText(formatLabel(model.getUnknownCount(),
830: "unknown"));
831: incompleteCountLabel.setText(formatLabel(model
832: .getIncompleteCount(), "incomplete"));
833: failureCountLabel.setText(formatLabel(model.getFailureCount(),
834: "failed"));
835: successCountLabel.setText(formatLabel(model.getSuccessCount(),
836: "successful"));
837: }
838:
839: private PlanElement getPlanElement(Task task) {
840: return planElementSet.findPlanElement(task);
841: }
842:
843: private void addToModel(final Task task) {
844: SwingUtilities.invokeLater(new Runnable() {
845: public void run() {
846: model.add(task);
847: updateLabels();
848: }
849: });
850: }
851:
852: private void changeInModel(final Task task) {
853: SwingUtilities.invokeLater(new Runnable() {
854: public void run() {
855: if (model.contains(task)) {
856: model.change(task);
857: updateLabels();
858: }
859: }
860: });
861: }
862:
863: private void removeFromModel(final Task task) {
864: SwingUtilities.invokeLater(new Runnable() {
865: public void run() {
866: model.remove(task);
867: updateLabels();
868: }
869: });
870: }
871:
872: private void removeAllFromModel() {
873: SwingUtilities.invokeLater(new Runnable() {
874: public void run() {
875: model.removeAll();
876: updateLabels();
877: }
878: });
879: }
880:
881: private void changeInModel(PlanElement pe) {
882: Task task = pe.getTask();
883: if (task != null) {
884: changeInModel(task);
885: } else {
886: SwingUtilities.invokeLater(new Runnable() {
887: public void run() {
888: model.changeAll();
889: updateLabels();
890: }
891: });
892: }
893: }
894:
895: private void changeAll() {
896: SwingUtilities.invokeLater(new Runnable() {
897: public void run() {
898: model.changeAll();
899: updateLabels();
900: }
901: });
902: }
903:
904: private void addTasks(Enumeration tasks) {
905: while (tasks.hasMoreElements()) {
906: addToModel((Task) tasks.nextElement());
907: }
908: }
909:
910: private void changeTasks(Enumeration tasks) {
911: while (tasks.hasMoreElements()) {
912: changeInModel((Task) tasks.nextElement());
913: }
914: }
915:
916: private void removeTasks(Enumeration tasks) {
917: while (tasks.hasMoreElements()) {
918: removeFromModel((Task) tasks.nextElement());
919: }
920: }
921:
922: private void changeDispositions(Enumeration dispositions) {
923: while (dispositions.hasMoreElements()) {
924: changeInModel((PlanElement) dispositions.nextElement());
925: }
926: }
927:
928: /* CCV2 execute method */
929: /* This will be called every time a alloc matches the above predicate */
930: /* Note: Failed Dispositions only come through on the changed list.
931: Since Dispositions are changed by other Plugins after we see them
932: here, we need to keep track of the ones we've seen so we don't
933: act on them more than once.
934: */
935: public synchronized void execute() {
936: if (myPrivateState == null) {
937: if (myState.hasChanged()) {
938: checkMyState(myState.getAddedList());
939: }
940: }
941: if (myPrivateState != null) {
942: if (!myPrivateState.onDemandEnabled) {
943: addTasks(myTasks.getAddedList());
944: changeTasks(myTasks.getChangedList());
945: removeTasks(myTasks.getRemovedList());
946: changeDispositions(myPlanElements.getAddedList());
947: changeDispositions(myPlanElements.getChangedList());
948: changeDispositions(myPlanElements.getRemovedList());
949: } else if (myTasks.hasChanged()
950: || myPlanElements.hasChanged()) {
951: updateButton.setEnabled(true);
952: }
953: }
954: }
955:
956: private void checkMyState(Enumeration states) {
957: while (states.hasMoreElements()) {
958: myPrivateState = (MyPrivateState) states.nextElement();
959: createGUI();
960: setupMainSubscriptions();
961: unsubscribe(myState);
962: myState = null;
963: update();
964: break;
965: }
966: }
967:
968: private void update() {
969: updateButton.setEnabled(false);
970: removeAllFromModel();
971: addTasks(myTasks.elements());
972: changeDispositions(myPlanElements.elements());
973: }
974: }
|