427
428 public int getColumnCount() {
429 return COLUMN_COUNT;
430 }
431
432 public String getColumnName(int columnIndex) {
433 if (columnIndex >= colNames.length)
434 throw new IndexOutOfBoundsException();
435 else
436 return columnIndex == 0 ? colNames[0] : uif.getI18NString("br.runtime.show.status.mit");
437 }
438
439 public Object getValueAt(int row, int column) {
440 if (column == 0) {
441 synchronized (liveData) {
442 return liveData.get(row);
443 }
444 } else if (column == 1) {
445 synchronized (liveData) {
446 if ((liveData.get(row)) instanceof TestResult)
447 return (getSelectedProperty((TestResult) (liveData.get(row))));
448 else
449 // should not happen
450 return uif.getI18NString("br.list.notAvailable.txt");
451 }
452 } else
453 throw new IndexOutOfBoundsException(
454 "Index into filtered out table is out of range: " + row
455 + ", " + column);
456 }
457
458 public boolean isCellEditable(int rowIndex, int colIndex) {
459 return false;
460 }
461
462 // ---------- Custom methods for this model ----------
463 /**
464 * @param suppressNotify
465 * Actively request that no update be scheduled.
466 */
467 void addTest(Object tr, boolean suppressNotify) {
468 synchronized (vLock) {
469 // make sure this item is not already in the list
470 if (!inQueue.contains(tr) && !liveData.contains(tr))
471 inQueue.addElement(tr);
472 } // sync
473
474 // try not to saturate the GUI event thread
475 if (!suppressNotify && !isUpdateScheduled) {
476 TableNotifier tn = new TableNotifier(subpanelNode, this);
477 pendingEvents.addElement(tn);
478 EventQueue.invokeLater(tn);
479 }
480 }
481
482 /**
483 * Sorts data in the table
484 *
485 * @param v
486 * Current tests list
487 * @param column
488 * Number of column sorting to be applied to
489 * @param mode
490 * Indicates ascending (0) or descending (1) sorting
491 */
492 void sortTests(LinkedList v, int column, boolean mode) {
493 synchronized (vLock) {
494 inQueue = sort(v, mode);
495
496 TableNotifier tn = new TableNotifier(subpanelNode, this);
497 pendingEvents.addElement(tn);
498 EventQueue.invokeLater(tn);
499 }
500 }
501
502 /**
503 * Remove the given test from the list. Ignored if the test is not in
504 * the list.
505 */
506 void removeTest(Object tr) {
507 synchronized (vLock) {
508 rmQueue.addElement(tr);
509 // try not to saturate the GUI event thread
510 if (!isUpdateScheduled) {
511 TableNotifier tn = new TableNotifier(subpanelNode, this);
512
513 pendingEvents.addElement(tn);
514 EventQueue.invokeLater(tn);
515 }
516 } // sync
517
518 }
519
520 void reset() {
521 synchronized (vLock) {
522 init();
523 }
524
525 // force GUI to update the now empty list
526 notifyDone();
552 return ((TestResult) tst).getProperty(show) == null ? uif.getI18NString("br.list.notAvailable.txt")
553 : ((TestResult) tst).getProperty(show);
554 } catch (TestResult.Fault f) {
555 }
556 return (""); // should not be here
557 }
558
559 private void init() {
560 // discard all pending events
561 // this is necessary to ensure that update events which haven't
562 // been processed are not processed after the model has changed
563 // arguably, this should be solved by putting this init() onto
564 // the event thread
565 synchronized (pendingEvents) {
566 for (int i = 0; i < pendingEvents.size(); i++) {
567 TableNotifier tn = (TableNotifier) (pendingEvents.get(i));
568 tn.cancel();
569 } // for
570 }
571
572 inQueue = new Vector();
573 rmQueue = new Vector();
574 liveData = new LinkedList();
575
576 isUpdateScheduled = false;
577 }
578
579 private Vector sort(LinkedList v, boolean mode) {
580
581 o = new Object[v.size()];
582
583 if (SORTING_COLUMN == 0)
584 o = v.toArray();
585 else if (SORTING_COLUMN == 1) {
586 for (int i = 0; i < v.size(); i++) {
587 if (v.get(i) instanceof TestResult)
588 o[i] = getSelectedProperty((TestResult) v.get(i));
589 else
590 o[i] = ""; // should not happen
591 }
592 } else {
593 throw new JavaTestError("Internal error: invalid "
594 + "column number specified: " + SORTING_COLUMN);
595 }
596
597 rows = new Sorter[o.length];
598
599 for (int i = 0; i < rows.length; i++) {
600 rows[i] = new Sorter();
601 rows[i].index = i;
602 }
603
604 Arrays.sort(rows);
605
606 int[] aaa = new int[v.size()];
607 for (int i = 0; i < rows.length; i++) {
608 if (mode) // ascending
609 aaa[i] = rows[i].index;
610 else
611 // descending
612 aaa[i] = rows[rows.length - i - 1].index;
613 }
614
615 Vector temp = new Vector(v.size());
616
617 for (int i = 0; i < v.size(); i++)
618 temp.addElement(v.get(aaa[i]));
619
620 return temp;
621 }
622
623 private class Sorter implements Comparable {
624 public int index;
625
626 public int compareTo(Object other) {
627 Sorter otherRow = (Sorter) other;
628 if (o[index] instanceof TestResult) {
629 return ((Comparable) ((TestResult) o[index]).getTestName()).
630 compareTo(((TestResult) o[otherRow.index]).getTestName());
631 } else if (o[index] instanceof String) {
632 return ((Comparable) o[index]).compareTo(o[otherRow.index]);
633 } else {
634 return index - otherRow.index; // should not happen
635 }
664 synchronized (liveData) {
665 firstNew = liveData.size();
666 if (inQueue.size() < BATCH_SIZE) {
667 if (sortingRequested) {
668 liveData.clear();
669 liveData.addAll(inQueue);
670 sortingRequested = false;
671 } else {
672 liveData.addAll(inQueue);
673 inQueue.setSize(0);
674 }
675 table.repaint();
676 lastNew = liveData.size() - 1;
677 } else { // only add some of the new items
678 if (sortingRequested) {
679 liveData.clear();
680 sortingRequested = false;
681 }
682
683 for (int i = 0; i < BATCH_SIZE; i++) {
684 Object o = inQueue.remove(0);
685
686 liveData.add(o);
687 }
688
689 // schedule a future update
690 if (!isUpdateScheduled) {
691 TableNotifier tn = new TableNotifier(
692 subpanelNode, this);
693 pendingEvents.addElement(tn);
694 EventQueue.invokeLater(tn);
695 }
696 table.repaint();
697 lastNew = liveData.size() - 1;
698 }
699 } // sync
700 // dispatch update range event to Swing
701 if (listenerList.getListenerCount() > 0) {
702 TableModelEvent e = new TableModelEvent(this,
703 firstNew, lastNew,
704 TableModelEvent.ALL_COLUMNS,
718
719 // this clears the "please wait" message if needed
720 if (table.getSelectedRow() == -1 && inQueue.size() == 0)
721 showMessage("");
722 } // sync
723 }
724
725 if (debug)
726 Debug.println("BP_TL.LT - goLive() finished");
727 }
728
729 /**
730 * Remove tests in the removal queue from the live data or the incoming
731 * data. vLock should be locked when you call this method
732 */
733 private void processRemoveQueue() {
734 if (rmQueue.size() == 0)
735 return;
736
737 while (rmQueue.size() > 0) {
738 TestResult target = (TestResult) (rmQueue.remove(0));
739 int targetIndex = liveData.indexOf(target);
740 if (targetIndex != -1) {
741 synchronized (liveData) {
742 // necessary for proper synchronization
743 // should not be a problem really, based on how other
744 // locking is done, all work on liveData occurs in
745 // goLive()
746 targetIndex = liveData.indexOf(target);
747
748 // only should happen if the item disappears
749 if (targetIndex == -1)
750 continue;
751
752 liveData.remove(targetIndex);
753
754 // WARNING: since we are continually changing the
755 // contents of
756 // the data, you must notify the observers synchronously
757 // to get
758 // proper results
819 }
820 }
821
822 private void notifyDone() {
823 if (listenerList.getListenerCount() > 0) {
824 // may want to buffer these messages
825 TableModelEvent e = new TableModelEvent(this);
826 // switch event onto AWT event thread
827 TableNotifier tn = new TableNotifier(e, mod);
828 pendingEvents.addElement(tn);
829 EventQueue.invokeLater(tn);
830 }
831 }
832
833 private String[] colNames;
834
835 // must sync. on vLock anytime you access inQueue or liveData
836 private final Object vLock = new Object(); // lock for inQueue &
837 // rmQueue
838
839 private Vector inQueue; // queue of items to be added to live data
840
841 private Vector rmQueue; // queue of items to be removed from live data
842
843 private LinkedList liveData; // to allow manual synchronization
844
845 Vector pendingEvents = new Vector();
846
847 volatile boolean isUpdateScheduled; // are updates waiting in inQueue or
848 // rmQueue
849
850 private static final int BATCH_SIZE = 100;
851
852 private static final int COLUMN_COUNT = 2;
853
854 private Sorter[] rows;
855
856 private Object[] o;
857
858 private int SORTING_COLUMN = -1;
859
860 private boolean SORTING_MODE = false;
861 }
862
863 private class CacheObserver extends TT_NodeCache.TT_NodeCacheObserver {
864 CacheObserver(int state) {
865 super();
1340 private TableCellRenderer renderer;
1341 private InputListener listener;
1342 private JTextArea infoTL;
1343 private boolean rowHeightSet;
1344
1345 private static final int ROW_HEIGHT_PADDING = 3;
1346 private static final int WAIT_DIALOG_DELAY = 3000; // 3 second delay
1347
1348 private JPopupMenu popupTable, popupHeader;
1349 private JMenu showDescrMenu, showRunMenu, sortMenu;
1350
1351 private Harness harness;
1352 private ExecModel execModel;
1353
1354 private boolean debug = Debug.getBoolean(BP_TestListSubpanel.class);
1355
1356 private boolean sortingRequested = false;
1357
1358 private String show = TestResult.EXEC_STATUS;
1359
1360 private Vector[] newData;
1361
1362 private boolean updateRequired;
1363 }
|
427
428 public int getColumnCount() {
429 return COLUMN_COUNT;
430 }
431
432 public String getColumnName(int columnIndex) {
433 if (columnIndex >= colNames.length)
434 throw new IndexOutOfBoundsException();
435 else
436 return columnIndex == 0 ? colNames[0] : uif.getI18NString("br.runtime.show.status.mit");
437 }
438
439 public Object getValueAt(int row, int column) {
440 if (column == 0) {
441 synchronized (liveData) {
442 return liveData.get(row);
443 }
444 } else if (column == 1) {
445 synchronized (liveData) {
446 if ((liveData.get(row)) instanceof TestResult)
447 return getSelectedProperty(liveData.get(row));
448 else
449 // should not happen
450 return uif.getI18NString("br.list.notAvailable.txt");
451 }
452 } else
453 throw new IndexOutOfBoundsException(
454 "Index into filtered out table is out of range: " + row
455 + ", " + column);
456 }
457
458 public boolean isCellEditable(int rowIndex, int colIndex) {
459 return false;
460 }
461
462 // ---------- Custom methods for this model ----------
463 /**
464 * @param suppressNotify
465 * Actively request that no update be scheduled.
466 */
467 void addTest(TestResult tr, boolean suppressNotify) {
468 synchronized (vLock) {
469 // make sure this item is not already in the list
470 if (!inQueue.contains(tr) && !liveData.contains(tr))
471 inQueue.addElement(tr);
472 } // sync
473
474 // try not to saturate the GUI event thread
475 if (!suppressNotify && !isUpdateScheduled) {
476 TableNotifier tn = new TableNotifier(subpanelNode, this);
477 pendingEvents.addElement(tn);
478 EventQueue.invokeLater(tn);
479 }
480 }
481
482 /**
483 * Sorts data in the table
484 *
485 * @param v
486 * Current tests list
487 * @param column
488 * Number of column sorting to be applied to
489 * @param mode
490 * Indicates ascending (0) or descending (1) sorting
491 */
492 void sortTests(LinkedList<TestResult> v, int column, boolean mode) {
493 synchronized (vLock) {
494 inQueue = sort(v, mode);
495
496 TableNotifier tn = new TableNotifier(subpanelNode, this);
497 pendingEvents.addElement(tn);
498 EventQueue.invokeLater(tn);
499 }
500 }
501
502 /**
503 * Remove the given test from the list. Ignored if the test is not in
504 * the list.
505 */
506 void removeTest(TestResult tr) {
507 synchronized (vLock) {
508 rmQueue.addElement(tr);
509 // try not to saturate the GUI event thread
510 if (!isUpdateScheduled) {
511 TableNotifier tn = new TableNotifier(subpanelNode, this);
512
513 pendingEvents.addElement(tn);
514 EventQueue.invokeLater(tn);
515 }
516 } // sync
517
518 }
519
520 void reset() {
521 synchronized (vLock) {
522 init();
523 }
524
525 // force GUI to update the now empty list
526 notifyDone();
552 return ((TestResult) tst).getProperty(show) == null ? uif.getI18NString("br.list.notAvailable.txt")
553 : ((TestResult) tst).getProperty(show);
554 } catch (TestResult.Fault f) {
555 }
556 return (""); // should not be here
557 }
558
559 private void init() {
560 // discard all pending events
561 // this is necessary to ensure that update events which haven't
562 // been processed are not processed after the model has changed
563 // arguably, this should be solved by putting this init() onto
564 // the event thread
565 synchronized (pendingEvents) {
566 for (int i = 0; i < pendingEvents.size(); i++) {
567 TableNotifier tn = (TableNotifier) (pendingEvents.get(i));
568 tn.cancel();
569 } // for
570 }
571
572 inQueue = new Vector<>();
573 rmQueue = new Vector<>();
574 liveData = new LinkedList<>();
575
576 isUpdateScheduled = false;
577 }
578
579 private Vector<TestResult> sort(LinkedList<TestResult> v, boolean mode) {
580
581 o = new Object[v.size()];
582
583 if (SORTING_COLUMN == 0)
584 o = v.toArray();
585 else if (SORTING_COLUMN == 1) {
586 for (int i = 0; i < v.size(); i++) {
587 if (v.get(i) instanceof TestResult)
588 o[i] = getSelectedProperty((TestResult) v.get(i));
589 else
590 o[i] = ""; // should not happen
591 }
592 } else {
593 throw new JavaTestError("Internal error: invalid "
594 + "column number specified: " + SORTING_COLUMN);
595 }
596
597 rows = new Sorter[o.length];
598
599 for (int i = 0; i < rows.length; i++) {
600 rows[i] = new Sorter();
601 rows[i].index = i;
602 }
603
604 Arrays.sort(rows);
605
606 int[] aaa = new int[v.size()];
607 for (int i = 0; i < rows.length; i++) {
608 if (mode) // ascending
609 aaa[i] = rows[i].index;
610 else
611 // descending
612 aaa[i] = rows[rows.length - i - 1].index;
613 }
614
615 Vector<TestResult> temp = new Vector<>(v.size());
616
617 for (int i = 0; i < v.size(); i++)
618 temp.addElement(v.get(aaa[i]));
619
620 return temp;
621 }
622
623 private class Sorter implements Comparable {
624 public int index;
625
626 public int compareTo(Object other) {
627 Sorter otherRow = (Sorter) other;
628 if (o[index] instanceof TestResult) {
629 return ((Comparable) ((TestResult) o[index]).getTestName()).
630 compareTo(((TestResult) o[otherRow.index]).getTestName());
631 } else if (o[index] instanceof String) {
632 return ((Comparable) o[index]).compareTo(o[otherRow.index]);
633 } else {
634 return index - otherRow.index; // should not happen
635 }
664 synchronized (liveData) {
665 firstNew = liveData.size();
666 if (inQueue.size() < BATCH_SIZE) {
667 if (sortingRequested) {
668 liveData.clear();
669 liveData.addAll(inQueue);
670 sortingRequested = false;
671 } else {
672 liveData.addAll(inQueue);
673 inQueue.setSize(0);
674 }
675 table.repaint();
676 lastNew = liveData.size() - 1;
677 } else { // only add some of the new items
678 if (sortingRequested) {
679 liveData.clear();
680 sortingRequested = false;
681 }
682
683 for (int i = 0; i < BATCH_SIZE; i++) {
684 TestResult o = inQueue.remove(0);
685
686 liveData.add(o);
687 }
688
689 // schedule a future update
690 if (!isUpdateScheduled) {
691 TableNotifier tn = new TableNotifier(
692 subpanelNode, this);
693 pendingEvents.addElement(tn);
694 EventQueue.invokeLater(tn);
695 }
696 table.repaint();
697 lastNew = liveData.size() - 1;
698 }
699 } // sync
700 // dispatch update range event to Swing
701 if (listenerList.getListenerCount() > 0) {
702 TableModelEvent e = new TableModelEvent(this,
703 firstNew, lastNew,
704 TableModelEvent.ALL_COLUMNS,
718
719 // this clears the "please wait" message if needed
720 if (table.getSelectedRow() == -1 && inQueue.size() == 0)
721 showMessage("");
722 } // sync
723 }
724
725 if (debug)
726 Debug.println("BP_TL.LT - goLive() finished");
727 }
728
729 /**
730 * Remove tests in the removal queue from the live data or the incoming
731 * data. vLock should be locked when you call this method
732 */
733 private void processRemoveQueue() {
734 if (rmQueue.size() == 0)
735 return;
736
737 while (rmQueue.size() > 0) {
738 TestResult target = rmQueue.remove(0);
739 int targetIndex = liveData.indexOf(target);
740 if (targetIndex != -1) {
741 synchronized (liveData) {
742 // necessary for proper synchronization
743 // should not be a problem really, based on how other
744 // locking is done, all work on liveData occurs in
745 // goLive()
746 targetIndex = liveData.indexOf(target);
747
748 // only should happen if the item disappears
749 if (targetIndex == -1)
750 continue;
751
752 liveData.remove(targetIndex);
753
754 // WARNING: since we are continually changing the
755 // contents of
756 // the data, you must notify the observers synchronously
757 // to get
758 // proper results
819 }
820 }
821
822 private void notifyDone() {
823 if (listenerList.getListenerCount() > 0) {
824 // may want to buffer these messages
825 TableModelEvent e = new TableModelEvent(this);
826 // switch event onto AWT event thread
827 TableNotifier tn = new TableNotifier(e, mod);
828 pendingEvents.addElement(tn);
829 EventQueue.invokeLater(tn);
830 }
831 }
832
833 private String[] colNames;
834
835 // must sync. on vLock anytime you access inQueue or liveData
836 private final Object vLock = new Object(); // lock for inQueue &
837 // rmQueue
838
839 private Vector<TestResult> inQueue; // queue of items to be added to live data
840
841 private Vector<TestResult> rmQueue; // queue of items to be removed from live data
842
843 private LinkedList<TestResult> liveData; // to allow manual synchronization
844
845 Vector<TableNotifier> pendingEvents = new Vector<>();
846
847 volatile boolean isUpdateScheduled; // are updates waiting in inQueue or
848 // rmQueue
849
850 private static final int BATCH_SIZE = 100;
851
852 private static final int COLUMN_COUNT = 2;
853
854 private Sorter[] rows;
855
856 private Object[] o;
857
858 private int SORTING_COLUMN = -1;
859
860 private boolean SORTING_MODE = false;
861 }
862
863 private class CacheObserver extends TT_NodeCache.TT_NodeCacheObserver {
864 CacheObserver(int state) {
865 super();
1340 private TableCellRenderer renderer;
1341 private InputListener listener;
1342 private JTextArea infoTL;
1343 private boolean rowHeightSet;
1344
1345 private static final int ROW_HEIGHT_PADDING = 3;
1346 private static final int WAIT_DIALOG_DELAY = 3000; // 3 second delay
1347
1348 private JPopupMenu popupTable, popupHeader;
1349 private JMenu showDescrMenu, showRunMenu, sortMenu;
1350
1351 private Harness harness;
1352 private ExecModel execModel;
1353
1354 private boolean debug = Debug.getBoolean(BP_TestListSubpanel.class);
1355
1356 private boolean sortingRequested = false;
1357
1358 private String show = TestResult.EXEC_STATUS;
1359
1360 private Vector<TestResult>[] newData;
1361
1362 private boolean updateRequired;
1363 }
|