00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 package com.meapsoft.visualizer;
00031
00032 import java.awt.Color;
00033 import java.awt.Point;
00034 import java.awt.Rectangle;
00035 import java.awt.event.ActionEvent;
00036 import java.awt.event.ActionListener;
00037 import java.awt.image.BufferedImage;
00038 import java.util.Vector;
00039
00040 import javax.swing.BoxLayout;
00041 import javax.swing.JButton;
00042 import javax.swing.JComboBox;
00043 import javax.swing.JLabel;
00044 import javax.swing.JPanel;
00045 import javax.swing.JTextField;
00046
00047 import com.meapsoft.EDLChunk;
00048 import com.meapsoft.EDLFile;
00049 import com.meapsoft.FeatChunk;
00050 import com.meapsoft.FeatFile;
00051 import com.meapsoft.MaxHeap;
00052 import com.meapsoft.gui.ColorMap;
00053
00054 public abstract class Renderer implements ActionListener
00055 {
00056 DrawingPanel drawingPanel;
00057
00058 String name = "none";
00059 EDLFile eDLFile;
00060 FeatFile featFile;
00061 int numColors = 256;
00062 ColorMap colormap = ColorMap.getJet(numColors);
00063
00064 Vector events;
00065
00066
00067 int numFeatures = 0;
00068 Vector featureDescriptions;
00069 int[] elementsPerFeature;
00070
00071
00072 double lowestFeatureValue[];
00073 double highestFeatureValue[];
00074 double featureValueSpan[];
00075 double colorMultipliers[];
00076
00077 double longestChunk = Double.MIN_VALUE;
00078 double shortestChunk = Double.MAX_VALUE;
00079
00080 double lastStartTime = 0.0;
00081 double totalTime = 0.0;
00082
00083 JPanel controlsPanel;
00084
00085 JComboBox featureSelector;
00086 JTextField rangeInput;
00087
00088
00089
00090
00091
00092 String[] optionBoxStrings;
00093
00094 JPanel labelsPanel;
00095 JLabel featureNameLabel;
00096 JLabel featureValueLabel;
00097 JLabel startTimeLabel;
00098 JLabel endTimeLabel;
00099 JLabel lengthLabel;
00100 JLabel destTimeLabel;
00101
00102
00103
00104
00105
00106 protected Rectangle dragRect = null;
00107 protected boolean dragShift = false;
00108
00109 public Renderer(FeatFile featFile, EDLFile eDLFile, String name)
00110 {
00111 this.eDLFile = eDLFile;
00112 this.featFile = featFile;
00113
00114 this.name = name;
00115
00116 parseFiles();
00117 }
00118
00119 public Renderer(Renderer r)
00120 {
00121 drawingPanel = r.drawingPanel;
00122 name = r.name;
00123 eDLFile = r.eDLFile;
00124 featFile = r.featFile;
00125 events = r.events;
00126
00127 numFeatures = r.numFeatures;
00128 featureDescriptions = r.featureDescriptions;
00129 elementsPerFeature = r.elementsPerFeature;
00130
00131 lowestFeatureValue = r.lowestFeatureValue;
00132 highestFeatureValue = r.highestFeatureValue;
00133 featureValueSpan = r.featureValueSpan;
00134 colorMultipliers = r.colorMultipliers;
00135
00136 longestChunk = r.longestChunk;
00137 shortestChunk = r.shortestChunk;
00138
00139 lastStartTime = r.lastStartTime;
00140 totalTime = r.totalTime;
00141
00142 updateColorMultipliers();
00143 }
00144
00145 public void setDrawingPanel(DrawingPanel dP)
00146 {
00147 drawingPanel = dP;
00148 }
00149
00150 public void setFiles(FeatFile featFile, EDLFile eDLFile)
00151 {
00152 if (featFile != null)
00153 this.featFile = featFile;
00154
00155 if (eDLFile != null)
00156 this.eDLFile = eDLFile;
00157
00158 parseFiles();
00159 }
00160
00161 public void parseFiles()
00162 {
00163 if (featFile == null)
00164 return;
00165
00166 events = new Vector();
00167
00168 int numChunks = featFile.chunks.size();
00169
00170 featureDescriptions = featFile.featureDescriptions;
00171 numFeatures = featureDescriptions.size();
00172
00173 elementsPerFeature = featFile.getFeatureLengths();
00174
00175 highestFeatureValue = new double[numFeatures];
00176 lowestFeatureValue = new double[numFeatures];
00177 featureValueSpan = new double[numFeatures];
00178 colorMultipliers = new double[numFeatures];
00179
00180 longestChunk = Double.MIN_VALUE;
00181 shortestChunk = Double.MAX_VALUE;
00182 lastStartTime = 0.0;
00183
00184 for (int i = 0; i < numFeatures; i++)
00185 {
00186 highestFeatureValue[i] = Double.MIN_VALUE;
00187 lowestFeatureValue[i] = Double.MAX_VALUE;
00188 featureValueSpan[i] = 0.0;
00189 colorMultipliers[i] = 0.0;
00190 }
00191
00192 for (int i = 0; i < numChunks; i++)
00193 {
00194
00195 FeatChunk fC = (FeatChunk) ((FeatChunk) featFile.chunks.elementAt(i)).clone();
00196 ChunkVisInfo cVI =
00197 new ChunkVisInfo(fC.srcFile, fC.startTime, fC.length, -1);
00198 cVI.addFeature(fC.getFeatures());
00199 events.add(cVI);
00200
00201 if (eDLFile != null)
00202 {
00203 int numEDLChunks = eDLFile.chunks.size();
00204
00205 for (int j = 0; j < numEDLChunks; j++)
00206 {
00207 EDLChunk eC = (EDLChunk) eDLFile.chunks.elementAt(j);
00208
00209 if (eC.startTime == cVI.startTime)
00210 cVI.dstTime = eC.dstTime;
00211 }
00212 }
00213
00214
00215 if (cVI.startTime > lastStartTime)
00216 {
00217 lastStartTime = cVI.startTime;
00218 totalTime = lastStartTime + cVI.length;
00219 }
00220
00221 if (cVI.dstTime > lastStartTime)
00222 {
00223 lastStartTime = cVI.dstTime;
00224 totalTime = lastStartTime + cVI.length;
00225 }
00226
00227 if (cVI.length < shortestChunk)
00228 shortestChunk = cVI.length;
00229
00230 if (cVI.length > longestChunk)
00231 longestChunk = cVI.length;
00232
00233 int currIndex = 0;
00234
00235 double[] features = cVI.getFeatures();
00236
00237 for (int k = 0; k < numFeatures; k++)
00238 {
00239 for (int m = 0; m < elementsPerFeature[k]; m++)
00240 {
00241
00242
00243 double value = features[currIndex];
00244
00245 if (value > highestFeatureValue[k])
00246 highestFeatureValue[k] = value;
00247
00248 if (value < lowestFeatureValue[k])
00249 lowestFeatureValue[k] = value;
00250
00251 currIndex++;
00252 }
00253
00254
00255
00256
00257
00258
00259 }
00260 }
00261
00262
00263
00264
00265
00266
00267
00268 updateColorMultipliers();
00269 }
00270
00271 public void updateOptionBoxStrings()
00272 {
00273 int numItems = numFeatures + 3;
00274 optionBoxStrings = new String[numItems];
00275 optionBoxStrings[0] = "start time";
00276 optionBoxStrings[1] = "dest time";
00277 optionBoxStrings[2] = "length";
00278
00279 for (int i = 0; i < numFeatures; i++)
00280 {
00281 String bigName = (String)featureDescriptions.elementAt(i);
00282 String[] name = bigName.split("[//.]");
00283 optionBoxStrings[i + 3] = name[name.length-1];
00284 }
00285 }
00286
00287 public void updateColorMultipliers()
00288 {
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 for (int i = 0; i < numFeatures; i++)
00373 {
00374 double lowValue = lowestFeatureValue[i] - lowestFeatureValue[i];
00375 double highValue = highestFeatureValue[i] - lowestFeatureValue[i];
00376
00377 featureValueSpan[i] = highValue - lowValue;
00378 colorMultipliers[i] = (numColors - 1.0)/featureValueSpan[i];
00379 }
00380
00381
00382
00383 }
00384
00385 public JPanel buildGUI(Color bgColor)
00386 {
00387 JPanel panel = new JPanel();
00388 panel.setBackground(bgColor);
00389
00390
00391
00392
00393 controlsPanel = new JPanel();
00394 controlsPanel.setBackground(bgColor);
00395
00396 JPanel zoomPanel = new JPanel();
00397 zoomPanel.setBackground(bgColor);
00398 zoomPanel.setLayout(new BoxLayout(zoomPanel, BoxLayout.Y_AXIS));
00399 zoomPanel.setAlignmentX((float) 0.5);
00400
00401 JLabel zL = new JLabel("zoom:");
00402 zL.setAlignmentX((float) 0.5);
00403 zL.setBackground(bgColor);
00404 zoomPanel.add(zL);
00405
00406 JPanel zoomInOutPanel = new JPanel();
00407 zoomInOutPanel.setAlignmentX((float) 0.5);
00408 zoomInOutPanel.setBackground(bgColor);
00409
00410 JButton zoomInButton = new JButton("+");
00411 zoomInButton.setBackground(bgColor);
00412 zoomInButton.setActionCommand("zoomIn");
00413 zoomInButton.addActionListener(this);
00414 zoomInOutPanel.add(zoomInButton);
00415
00416 JButton zoomOutButton = new JButton("-");
00417 zoomOutButton.setBackground(bgColor);
00418 zoomOutButton.setActionCommand("zoomOut");
00419 zoomOutButton.addActionListener(this);
00420 zoomInOutPanel.add(zoomOutButton);
00421
00422 zoomPanel.add(zoomInOutPanel);
00423
00424 JButton resetZoomButton = new JButton("reset");
00425 resetZoomButton.setBackground(bgColor);
00426 resetZoomButton.setAlignmentX((float) 0.5);
00427 resetZoomButton.setActionCommand("resetZoom");
00428 resetZoomButton.addActionListener(this);
00429 zoomPanel.add(resetZoomButton);
00430
00431 controlsPanel.add(zoomPanel);
00432
00433 JPanel selectionPanel = new JPanel();
00434 selectionPanel.setBackground(bgColor);
00435
00436
00437 JPanel clickedSelectorPanel = new JPanel();
00438 clickedSelectorPanel.setBackground(bgColor);
00439 clickedSelectorPanel.setLayout(new BoxLayout(clickedSelectorPanel, BoxLayout.Y_AXIS));
00440
00441 JLabel selectionLabel = new JLabel("selection control:");
00442 selectionLabel.setBackground(bgColor);
00443 clickedSelectorPanel.add(selectionLabel);
00444
00445 JButton selectAllButton = new JButton("select all");
00446 selectAllButton.setBackground(bgColor);
00447 selectAllButton.setActionCommand("selectAll");
00448 selectAllButton.addActionListener(this);
00449 clickedSelectorPanel.add(selectAllButton);
00450
00451 JButton selectNoneButton = new JButton("select none");
00452 selectNoneButton.setBackground(bgColor);
00453 selectNoneButton.setActionCommand("selectNone");
00454 selectNoneButton.addActionListener(this);
00455 clickedSelectorPanel.add(selectNoneButton);
00456
00457 JButton toggleAllButton = new JButton("invert selection");
00458 toggleAllButton.setBackground(bgColor);
00459 toggleAllButton.setActionCommand("invertAll");
00460 toggleAllButton.addActionListener(this);
00461 clickedSelectorPanel.add(toggleAllButton);
00462
00463 selectionPanel.add(clickedSelectorPanel);
00464
00465 JPanel rangeSelectorPanel = new JPanel();
00466 rangeSelectorPanel.setBackground(bgColor);
00467 rangeSelectorPanel.setLayout(new BoxLayout(rangeSelectorPanel, BoxLayout.Y_AXIS));
00468
00469 updateOptionBoxStrings();
00470
00471 featureSelector = new JComboBox(optionBoxStrings);
00472 featureSelector.setAlignmentX(0.0f);
00473 featureSelector.setMaximumSize(featureSelector.getPreferredSize());
00474 featureSelector.setBackground(bgColor);
00475 featureSelector.setActionCommand("rangeFilterSelectionChanged");
00476 featureSelector.addActionListener(this);
00477 rangeSelectorPanel.add(featureSelector);
00478
00479 rangeInput = new JTextField("0.00:1.00");
00480 rangeInput.setAlignmentX(0.0f);
00481
00482 rangeInput.setBackground(bgColor);
00483 rangeSelectorPanel.add(rangeInput);
00484
00485 JButton selectRangeButton = new JButton("apply selection filter");
00486 selectRangeButton.setAlignmentX(0.0f);
00487 selectRangeButton.setBackground(bgColor);
00488 selectRangeButton.setActionCommand("applyRangeFilter");
00489 selectRangeButton.addActionListener(this);
00490 rangeSelectorPanel.add(selectRangeButton);
00491
00492 selectionPanel.add(rangeSelectorPanel);
00493
00494 controlsPanel.add(selectionPanel);
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 labelsPanel = new JPanel();
00539 BoxLayout bL = new BoxLayout(labelsPanel, BoxLayout.X_AXIS);
00540 labelsPanel.setLayout(bL);
00541 labelsPanel.setBackground(bgColor);
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 panel.add(controlsPanel);
00565
00566 return panel;
00567 }
00568
00569 public abstract void draw(BufferedImage image, int width, int height);
00570
00571
00572 public Vector getSelectedEDLChunks()
00573 {
00574 MaxHeap v = new MaxHeap();
00575 for (int i = 0; i < events.size(); i++)
00576 {
00577 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00578 if (cVI.selected)
00579 {
00580 EDLChunk c =
00581 new EDLChunk(cVI.srcFile, cVI.startTime, cVI.length,
00582 cVI.dstTime);
00583 c.comment = cVI.comment;
00584 v.add(c);
00585 }
00586 }
00587
00588
00589 v.sort();
00590
00591 return v;
00592 }
00593
00594
00595 public Vector getSelectedFeatChunks()
00596 {
00597 Vector v = new Vector();
00598 for (int i = 0; i < events.size(); i++)
00599 {
00600 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00601 if (cVI.selected)
00602 {
00603 FeatChunk c = new FeatChunk(cVI.srcFile, cVI.startTime,
00604 cVI.length);
00605 c.addFeature(cVI.getFeatures());
00606 c.comment = cVI.comment;
00607 v.add(c);
00608 }
00609 }
00610
00611 return v;
00612 }
00613
00614 public abstract Vector getChunkVisInfosForPoint(Point p);
00615
00616 public void toggleSelectedForPoint(Point p)
00617 {
00618 Vector chunks = getChunkVisInfosForPoint(p);
00619
00620 for (int i = 0; i < chunks.size(); i++)
00621 {
00622 ChunkVisInfo cVI = (ChunkVisInfo)chunks.elementAt(i);
00623
00624 if (cVI != null)
00625 {
00626 cVI.selected = !cVI.selected;
00627 }
00628 }
00629 }
00630
00631 public abstract int getFeatureNumberForPoint(Point p);
00632 public abstract String getFeatureNameForPoint(Point p);
00633 public abstract double getFeatureValueForPoint(Point p);
00634
00635 public abstract void rangeFilterSelectionChanged();
00636
00637 public void updateDragRect(Rectangle r, boolean dS)
00638 {
00639 dragRect = r;
00640 dragShift = dS;
00641 drawingPanel.repaint();
00642 }
00643
00644 public abstract void setDragRect(Rectangle r, boolean dS);
00645
00646 public void selectAll()
00647 {
00648 int numEvents = events.size();
00649
00650 for (int i = 0; i < numEvents; i++)
00651 {
00652 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00653 cVI.selected = true;
00654 }
00655
00656 ActionEvent a = new ActionEvent(this, 0, "numChunksSelectedChanged");
00657 drawingPanel.actionListener.actionPerformed(a);
00658 }
00659
00660 public void selectNone()
00661 {
00662 int numEvents = events.size();
00663
00664 for (int i = 0; i < numEvents; i++)
00665 {
00666 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00667 cVI.selected = false;
00668 }
00669 ActionEvent a = new ActionEvent(this, 0, "numChunksSelectedChanged");
00670 drawingPanel.actionListener.actionPerformed(a);
00671 }
00672
00673 public void invertAll()
00674 {
00675 int numEvents = events.size();
00676
00677 for (int i = 0; i < numEvents; i++)
00678 {
00679 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00680 cVI.selected = !cVI.selected;
00681 }
00682 ActionEvent a = new ActionEvent(this, 0, "numChunksSelectedChanged");
00683 drawingPanel.actionListener.actionPerformed(a);
00684 }
00685
00686 public void applyFilterRange()
00687 {
00688 String[] numbers = rangeInput.getText().split(":");
00689 int whichFeature = featureSelector.getSelectedIndex();
00690 double low = 0.0;
00691 double high = 0.0;
00692
00693 try
00694 {
00695 low = new Double(numbers[0]).doubleValue();
00696 high = new Double(numbers[1]).doubleValue();
00697 }
00698 catch(java.lang.NumberFormatException e)
00699 {
00700 System.out.println("Please use the form 0.00:1.00 to indicate a selection range.");
00701 return;
00702 }
00703
00704
00705
00706
00707
00708
00709 if (low > high)
00710 {
00711 double tempLow = high;
00712 high = low;
00713 low = tempLow;
00714 }
00715
00716 int numEvents = events.size();
00717
00718 for (int i = 0; i < numEvents; i++)
00719 {
00720 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00721 cVI.selected = false;
00722
00723 if (whichFeature == 0)
00724 {
00725 if (cVI.startTime >= low && cVI.startTime <= high)
00726 cVI.selected = true;
00727 }
00728 else if (whichFeature == 1)
00729 {
00730 if (cVI.dstTime >= low && cVI.dstTime <= high)
00731 cVI.selected = true;
00732 }
00733 else if (whichFeature == 2)
00734 {
00735 if (cVI.length >= low && cVI.length <= high)
00736 cVI.selected = true;
00737 }
00738 else if (whichFeature >= 3)
00739 {
00740 int which = whichFeature - 3;
00741 int featNum[] = {0};
00742
00743 for (int j = 0; j < which; j++)
00744 featNum[0] += elementsPerFeature[j];
00745
00746 double features[] = cVI.getFeatures(featNum);
00747
00748 if (features[0] >= low && features[0] <= high)
00749 cVI.selected = true;
00750 }
00751
00752 }
00753 }
00754
00755 public int numChunksSelected()
00756 {
00757 int numChunksSelected = 0;
00758
00759 for (int i = 0; i < events.size(); i++)
00760 {
00761 ChunkVisInfo cVI = (ChunkVisInfo)events.elementAt(i);
00762 if (cVI.selected)
00763 numChunksSelected++;
00764 }
00765 return numChunksSelected;
00766 }
00767
00768 public void actionPerformed(ActionEvent arg0)
00769 {
00770 Object source = arg0.getSource();
00771
00772 String command = arg0.getActionCommand();
00773
00774
00775 if (command.equals("zoomIn"))
00776 drawingPanel.zoomIn();
00777 else if (command.equals("zoomOut"))
00778 drawingPanel.zoomOut();
00779 else if (command.equals("resetZoom"))
00780 drawingPanel.resetZoom();
00781 else if (command.equals("selectAll"))
00782 {
00783 selectAll();
00784 }
00785 else if (command.equals("selectNone"))
00786 {
00787 selectNone();
00788 }
00789 else if (command.equals("invertAll"))
00790 {
00791 invertAll();
00792 }
00793 else if (command.equals("applyRangeFilter"))
00794 {
00795 applyFilterRange();
00796 }
00797 else if (command.equals("rangeFilterSelectionChanged"))
00798 {
00799 rangeFilterSelectionChanged();
00800 }
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 drawingPanel.repaint();
00819 }
00820 }
00821
00822
00823