001 /** 002 * Created by IntelliJ IDEA. 003 * User: Wei Wang 004 * Date: Nov 30, 2002 005 * Time: 2:13:56 PM 006 */ 007 008 package EVolve.visualization.XYViz.ValValViz; 009 010 import java.awt.*; 011 import java.awt.event.*; 012 import java.util.*; 013 import javax.swing.*; 014 import EVolve.Scene; 015 import EVolve.data.Element; 016 import EVolve.data.Entity; 017 import EVolve.util.ThreadChooser; 018 import EVolve.util.xmlutils.datastructures.SerializedVisualization; 019 import EVolve.util.painters.RandomPainter; 020 import EVolve.visualization.Dimension; 021 import EVolve.visualization.*; 022 023 public class StackViz extends ValueValueVisualization{ 024 private ArrayList menuList; 025 private JMenuItem itemChangeThread; 026 private HashMap methodStacks; 027 private ThreadChooser td; 028 private JTextField textBegin, textEnd; 029 private Stack stack; 030 private int event; 031 private JCheckBox chkSelectTimeFrame, chkSelectOccurredEntities; 032 private static JCheckBox selectionOptions[] = null; 033 private String selected; 034 protected static int SELECT_OPTION = 0x0011; 035 private JLabel toEventNo; 036 037 038 public StackViz() { 039 super(); 040 041 menuList = new ArrayList(); 042 imageMap = new HashMap(); 043 methodStacks = new HashMap(); 044 td = new ThreadChooser(imageMap,false); 045 046 interval = 1; 047 beginCall = 0; 048 endCall = 300; 049 } 050 051 public Dimension[] createDimension() { 052 Dimension [] returnDimension = new Dimension[3]; 053 054 xAxis = new ValueDimension(); 055 entityIdFilter = new ReferenceDimension(); 056 filter2 = new ReferenceDimension(); 057 058 returnDimension[0] = xAxis; 059 returnDimension[1] = entityIdFilter; 060 returnDimension[2] = filter2; 061 062 return returnDimension; 063 } 064 065 protected void updateConfiguration() { 066 try { 067 beginCall = Integer.parseInt(textBegin.getText()); 068 endCall = Integer.parseInt(textEnd.getText()); 069 070 canvas.setName("Time - Invocations", "Stack"); 071 super.updateConfiguration(); 072 } catch (NumberFormatException e) { 073 Scene.showErrorMessage("Begin call and end call must be an integer and smaller than "+Integer.MAX_VALUE+"."); 074 configure(); 075 }; 076 } 077 078 public void restoreConfiguration(SerializedVisualization config) { 079 080 beginCall = Long.parseLong(config.BeginEvent); 081 endCall = Long.parseLong(config.EndEvent); 082 textBegin.setText(config.BeginEvent); 083 textEnd.setText(config.EndEvent); 084 super.restoreConfiguration(config); 085 } 086 087 public SerializedVisualization getCurrentConfiguration() { 088 SerializedVisualization data = super.getCurrentConfiguration(); 089 090 data.BeginEvent = String.valueOf(beginCall); 091 data.EndEvent = String.valueOf(endCall); 092 data.xAxis = xAxis.getName(); 093 data.yAxis = entityIdFilter.getName(); 094 data.zAxis = filter2.getName(); 095 096 return data; 097 } 098 099 public void preVisualize() { 100 xMax = 0; 101 event = 0; 102 stack = null; 103 image = null; 104 imageMap.clear(); 105 methodStacks.clear(); 106 currentThread = -1; 107 getSelection(); 108 installPainter(); 109 super.preVisualize(); 110 } 111 112 public void receiveElement(Element element) { 113 long methodId = entityIdFilter.getField(element); 114 long threadId = filter2.getField(element); 115 long callno = xAxis.getField(element) - 1; 116 117 countEvents(callno); 118 119 switchThread(threadId); 120 121 if ((callno*2<beginCall*2) || (callno*2>endCall*2+1)) { 122 if (element.isOptional()) {// method return; 123 if (!stack.empty()) stack.pop(); 124 } else 125 stack.push(new Long(methodId)); 126 return; 127 } 128 129 event++; 130 if (!element.isOptional()) // method enter; 131 stack.push(new Long(methodId)); 132 133 for (int j=0;j<stack.size();j++) { 134 painter.paint(image,callno-beginCall,j,((Long)stack.get(j)).intValue()); 135 } 136 137 if (element.isOptional()) {// method return; 138 if (!stack.empty()) stack.pop(); 139 } 140 } 141 142 public void visualize() { 143 if (imageMap.size() == 0 ) return; 144 while (selected==null) { 145 selected = td.showDialog(); 146 if (selected != null) { 147 image = (AutoImage)imageMap.get(new Long(selected.substring(7,selected.length()))); 148 canvas.setName("Time - "+ xAxis.getDataFilter().getName() + "(" + event/2 +" events)", "Stack"); 149 sort(); 150 selected = null; 151 break; 152 } 153 } 154 } 155 156 public void makeSelection() { 157 preMakeSelection(); 158 if (selectionName==null) return; 159 160 /*if (SELECT_OPTION == 0) { 161 Scene.showErrorMessage("No data is to be selected."); 162 return; 163 }*/ 164 165 if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) { 166 Scene.showErrorMessage("The active data source used currently is different from \n" + 167 "this visualization, please choose \"" + 168 Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\"."); 169 return; 170 } 171 172 int x1 = canvas.getStartX(); 173 int x2 = canvas.getEndX(); 174 int y1 = canvas.getEndY(); 175 int y2 = canvas.getStartY(); 176 177 if (!normalOrientation) { 178 int temp; 179 temp = x1; 180 x1 = y1; 181 y1 = temp; 182 temp = x2; 183 x2 = y2; 184 y2 = temp; 185 } 186 187 if (((x1<0)&&(x2<0)) || ((x1>=timeMap.size()))&&(x2>=timeMap.size())) 188 return; 189 190 if (x1 < 0) x1 = 0; 191 192 if (x2 > timeMap.size()) 193 x2 = (timeMap.size()-1); 194 195 196 long start, end; 197 if ((SELECT_OPTION & 0x000f) == 0) { 198 start = 0; 199 end = Long.MAX_VALUE; 200 } else { 201 long eventInterval[] = (long[])timeMap.get((int)(x1+beginCall)); 202 start = eventInterval[1]; 203 eventInterval = (long[])timeMap.get((int)(x2+beginCall)); 204 end = eventInterval[1]; 205 } 206 207 if (y1 < 0) y1 = 0; 208 209 int methodId; 210 ArrayList idList = new ArrayList(); 211 for (int i = x1; i <= x2; i++) { 212 for (int j = y1; j <= y2; j++) { 213 if (normalOrientation) 214 methodId = (int)getEntityId(i,j); 215 else 216 methodId = (int)getEntityId(j,i); 217 if ((methodId == -1)||(idList.contains(new Integer(methodId)))) continue; 218 idList.add(new Integer(methodId)); 219 } 220 } 221 222 223 int selection[] = null; 224 225 if ((SELECT_OPTION & 0x00f0) == 0x0010) { 226 selection = new int[idList.size()]; 227 for (int i=0; i<selection.length; i++) 228 selection[i] = ((Integer)idList.get(i)).intValue(); 229 } else { 230 selection = new int[entityIdFilter.getEntityNumber()]; 231 for (int i=0; i<selection.length; i++) 232 selection[i] = i; 233 } 234 235 entityIdFilter.makeSelection(selectionName,subjectDefinition.getType(),selection,start,end,timeMap); 236 } 237 238 protected String mouseMove(int x, int y) { 239 int X = canvas.getImageX(x); 240 int Y = canvas.getImageY(y); 241 242 if ((X>=0) && (Y >= 0) && (image != null)) { 243 if (image.getSortedColor(null,null,X,Y)==null) 244 Scene.setStatus(" "); 245 else 246 Scene.setStatus(getEntityName(X,Y)+" "+X+":"+Y); 247 } else { 248 Scene.setStatus(" "); 249 } 250 return null; 251 } 252 253 protected ArrayList createOptionalMenu() { 254 if (menuList.size() > 0) return null; 255 256 menuList.clear(); 257 itemChangeThread = new JMenuItem("Switch thread..."); 258 itemChangeThread.setMnemonic(KeyEvent.VK_T); 259 itemChangeThread.addActionListener(new ActionListener() { 260 public void actionPerformed(ActionEvent e) { 261 visualize(); 262 } 263 }); 264 265 menuList.add(itemChangeThread); 266 return menuList; 267 } 268 269 private String getEntityName(int x, int y) { 270 String returnVal = ""; 271 int mappedId = (int)getEntityId(x,y); 272 Entity entity = entityIdFilter.getEntityFromInt(mappedId); 273 274 if (entity != null) returnVal = entity.getName(); 275 return returnVal; 276 } 277 278 private long getEntityId(int x, int y) { 279 Color color = (Color)image.getSortedColor(null,null,x,y); 280 if ((color == null)||(painter == null)) return -1; 281 return ((RandomPainter)painter).getKeyFromColor(color); 282 } 283 284 protected void switchThread(long threadId) { 285 if (currentThread != threadId) { 286 stack = (Stack)methodStacks.get(new Long(threadId)); 287 if (stack == null) { 288 stack = new Stack(); 289 methodStacks.put(new Long(threadId),stack); 290 } 291 super.switchThread(threadId); 292 } 293 } 294 295 protected void installPainter() { 296 painter = new RandomPainter(); 297 } 298 299 public JCheckBox[] createSelectionOptions() { 300 if (selectionOptions!=null) return selectionOptions; 301 302 chkSelectTimeFrame = new JCheckBox("Time Frame"); 303 chkSelectTimeFrame.setMnemonic(KeyEvent.VK_T); 304 chkSelectTimeFrame.addActionListener(new ActionListener() { 305 public void actionPerformed(ActionEvent e) { 306 boolean selected = chkSelectTimeFrame.isSelected(); 307 SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME); 308 } 309 }); 310 chkSelectTimeFrame.setSelected(true); 311 312 chkSelectOccurredEntities = new JCheckBox("Occurred Entities"); 313 chkSelectOccurredEntities.setMnemonic(KeyEvent.VK_O); 314 chkSelectOccurredEntities.addActionListener(new ActionListener() { 315 public void actionPerformed(ActionEvent e) { 316 boolean selected = chkSelectOccurredEntities.isSelected(); 317 SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES); 318 } 319 }); 320 chkSelectOccurredEntities.setSelected(true); 321 322 selectionOptions = new JCheckBox[2]; 323 selectionOptions[0] = chkSelectTimeFrame; 324 selectionOptions[1] = chkSelectOccurredEntities; 325 326 return selectionOptions; 327 } 328 329 protected JPanel createConfigurationPanel() { 330 JPanel returnVal = new JPanel(new GridLayout(1, 1, 5, 5)); 331 JPanel panelEvent = new JPanel(new GridLayout(2,2)); 332 333 Box panelBottom = new Box(BoxLayout.Y_AXIS); 334 returnVal.add(panelBottom); 335 336 textBegin = new JTextField(String.valueOf(beginCall)); 337 textEnd = new JTextField(String.valueOf(endCall)); 338 panelEvent.add(new JLabel("From Call No:")); 339 panelEvent.add(textBegin); 340 341 toEventNo = new JLabel("To Call No:"); 342 panelEvent.add(toEventNo); 343 panelEvent.add(textEnd); 344 panelBottom.add(panelEvent); 345 346 return returnVal; 347 } 348 349 protected void updateComboSubject() { 350 super.updateComboSubject(); 351 String range = String.valueOf(Scene.getDataManager().getDataSource().getNumberOfEvents(elementDefinition[comboSubject.getSelectedIndex()].getName())); 352 toEventNo.setText("To Call No:("+range+")"); 353 } 354 355 public Object clone() { 356 StackViz o = (StackViz)super.clone(); 357 o.dimension[0] = o.xAxis; 358 o.dimension[1] = o.entityIdFilter; 359 o.dimension[2] = o.filter2; 360 361 362 o.td = new ThreadChooser(o.imageMap,false); 363 364 o.methodStacks = new HashMap(); 365 Iterator it = methodStacks.keySet().iterator(); 366 while (it.hasNext()) { 367 Object key = it.next(); 368 Stack newStack = new Stack(), oldStack = (Stack)methodStacks.get(key); 369 o.methodStacks.put(key,newStack); 370 for (int i=0; i<oldStack.size(); i++) 371 newStack.add(oldStack.get(i)); 372 } 373 374 o.menuList = new ArrayList(); 375 o.createDialog(); 376 return o; 377 } 378 379 }