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 EVolve.util.*;
011 import EVolve.util.Painters.RandomPainter;
012 import EVolve.data.*;
013 import EVolve.visualization.*;
014 import EVolve.Scene;
015 import javax.swing.*;
016 import java.util.*;
017 import java.awt.event.*;
018 import java.awt.*;
019
020 public class StackViz extends ValueValueVisualization{
021 private ArrayList menuList;
022 private JMenuItem itemChangeThread;
023 private HashMap methodStacks;
024 private ThreadChooser td;
025 private JTextField textBegin, textEnd, textName;
026 private Stack stack;
027 private int event;
028 private JMenuItem itemSelectTimeFrame, itemSelectOccurredEntities;
029 private static JMenuItem selectionMenu[] = null;
030 protected static int SELECT_OPTION = 0x0011;
031
032 public StackViz() {
033 super();
034 dataFilterName = new String[3];
035 dataFilterName[0] = "Invocations";
036 dataFilterName[1] = "Method";
037 dataFilterName[2] = "Thread";
038 subject = "Method Invocation";
039
040 menuList = new ArrayList();
041 imageMap = new HashMap();
042 methodStacks = new HashMap();
043 td = new ThreadChooser(imageMap,false);
044
045 interval = 1;
046 beginCall = 0;
047 endCall = 300;
048 }
049
050 protected void updateConfiguration() {
051 ((AxesPanel)panel).setName("Time - Invocations", "Stack");
052 super.updateConfiguration();
053 }
054
055 public HashMap getCurrentConfigure() {
056 HashMap configure = super.getCurrentConfigure();
057
058 configure.put("Interval", interval+";"+beginCall+","+endCall);
059
060 return configure;
061 }
062
063 public void preVisualize() {
064 xMax = 0;
065 event = 0;
066 stack = null;
067 image = null;
068 imageMap.clear();
069 methodStacks.clear();
070 threadFilter.preVisualize();
071 zAxis.preVisualize();
072 currentThread = -1;
073 getSelection();
074 installPainter();
075 super.preVisualize();
076 }
077
078 public void receiveElement(Element element) {
079 int methodId = zAxis.getField(element);
080 int threadId = threadFilter.getField(element);
081 int callno = xAxis.getField(element) - 1;
082
083 countEvents(callno/2);
084
085 switchThread(threadId);
086
087 if ((callno<beginCall*2) || (callno>endCall*2+1)) {
088 if (element.getField()[element.getField().length-1] == Integer.MAX_VALUE) {// method return;
089 if (!stack.empty()) stack.pop();
090 } else
091 stack.push(new Integer(methodId));
092 return;
093 }
094
095 event++;
096 if (element.getField()[element.getField().length-1] != Integer.MAX_VALUE) // method enter;
097 stack.push(new Integer(methodId));
098
099 for (int j=0;j<stack.size();j++) {
100 painter.paint(image,callno-beginCall*2,j,((Integer)stack.get(j)).intValue());
101 }
102
103 if (element.getField()[element.getField().length-1] == Integer.MAX_VALUE) {// method return;
104 if (!stack.empty()) stack.pop();
105 }
106 }
107
108 public void visualize() {
109 String selected = td.showDialog();
110 image = (AutoImage)imageMap.get(new Integer(selected.substring(7,selected.length())));
111 ((AxesPanel)panel).setName("Time - "+ xAxis.getDataFilter().getName() + "(" + event/2 +" events)", "Stack");
112 sort();
113 }
114
115 public void makeSelection() {
116 if (SELECT_OPTION == 0) {
117 Scene.showErrorMessage("No data is to be selected.");
118 return;
119 }
120
121 int x1 = ((AxesPanel)panel).getStartX();
122 int x2 = ((AxesPanel)panel).getEndX();
123 int y1 = ((AxesPanel)panel).getEndY();
124 int y2 = ((AxesPanel)panel).getStartY();
125
126 if (!normalOrientation) {
127 int temp;
128 temp = x1;
129 x1 = y1;
130 y1 = temp;
131 temp = x2;
132 x2 = y2;
133 y2 = temp;
134 }
135
136 if (x1 < 0) x1 = 0;
137
138 if (x2/2 > eventCounter.size())
139 x2 = (eventCounter.size()-1)*2;
140
141 int start, end;
142 if ((SELECT_OPTION & 0x000f) == 0) {
143 start = ((Integer)eventCounter.get(0)).intValue();
144 end = ((Integer)eventCounter.get(eventCounter.size()-1)).intValue();
145 } else {
146 start = ((Integer)eventCounter.get(x1/2)).intValue();
147 end = ((Integer)eventCounter.get(x2/2)).intValue();
148 }
149
150 if (y1 < 0) y1 = 0;
151
152 int methodId;
153 ArrayList idList = new ArrayList();
154 for (int i = x1; i <= x2; i++) {
155 for (int j = y1; j <= y2; j++) {
156 if (normalOrientation)
157 methodId = getEntityId(i,j);
158 else
159 methodId = getEntityId(j,i);
160 if ((methodId == -1)||(idList.contains(new Integer(methodId)))) continue;
161 idList.add(new Integer(methodId));
162 }
163 }
164
165
166 int selection[] = null;
167
168 if ((SELECT_OPTION & 0x00f0) == 0x0010) {
169 selection = new int[idList.size()];
170 for (int i=0; i<selection.length; i++)
171 selection[i] = ((Integer)idList.get(i)).intValue();
172 } else {
173 selection = new int[zAxis.getEntityNumber()];
174 for (int i=0; i<selection.length; i++)
175 selection[i] = i;
176 }
177
178 Scene.getFilter().addSelection(new Selection(zAxis.getDataFilter().getTargetType(), selection,start,end));
179 }
180
181 protected void mouseMove(int x, int y) {
182 int X = ((AxesPanel)panel).getImageX(x);
183 int Y = ((AxesPanel)panel).getImageY(y);
184
185 if ((X>=0) && (Y >= 0)) {
186 if (image.getSortedColor(null,null,X,Y)==null)
187 Scene.setStatus(" ");
188 else
189 Scene.setStatus(getEntityName(X,Y)+" "+X+":"+Y);
190 } else {
191 Scene.setStatus(" ");
192 }
193 }
194
195 protected ArrayList createOptionalMenu() {
196 if (menuList.size() > 0) return null;
197
198 menuList.clear();
199 itemChangeThread = new JMenuItem("Switch thread...");
200 itemChangeThread.setMnemonic(KeyEvent.VK_T);
201 itemChangeThread.addActionListener(new ActionListener() {
202 public void actionPerformed(ActionEvent e) {
203 visualize();
204 }
205 });
206
207 menuList.add(itemChangeThread);
208 return menuList;
209 }
210
211 protected void createDialog() {
212 dialog = new JDialog(Scene.getFrame(), "Configure", true);
213
214 JPanel panelTitle = new JPanel(new FlowLayout());
215 dialog.getContentPane().add(panelTitle, BorderLayout.NORTH);
216
217 panelTitle.add(new JLabel("Title: "));
218
219 textName = new JTextField(name, 12);
220 panelTitle.add(textName);
221
222 Box boxMain = new Box(BoxLayout.Y_AXIS);
223 boxMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
224 "Choose range"));
225 dialog.getContentPane().add(boxMain,BorderLayout.CENTER);
226
227 textBegin = new JTextField(String.valueOf(beginCall));
228 textEnd = new JTextField(String.valueOf(endCall));
229 boxMain.add(new JLabel("From Call No.:"));
230 boxMain.add(textBegin);
231 boxMain.add(new JLabel("To Call No:"));
232 boxMain.add(textEnd);
233
234 dialog.getContentPane().add(boxMain, BorderLayout.CENTER);
235
236 JPanel panelButton = new JPanel(new FlowLayout());
237 dialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
238
239 JButton buttonApply = new JButton("Apply");
240 buttonApply.addActionListener(new ActionListener() {
241 public void actionPerformed(ActionEvent e) {
242 dialogApply();
243 }
244 });
245 panelButton.add(buttonApply);
246
247 JButton buttonCancel = new JButton("Cancel");
248 buttonCancel.addActionListener(new ActionListener() {
249 public void actionPerformed(ActionEvent e) {
250 dialogCancel();
251 }
252 });
253 panelButton.add(buttonCancel);
254
255 }
256
257 private void dialogApply() {
258 try {
259 beginCall = new Integer(textBegin.getText()).intValue();
260 if (beginCall < 0) beginCall = 0;
261 endCall = new Integer(textEnd.getText()).intValue();
262 } catch (Exception e) {
263 Scene.showErrorMessage("Begin call and end call must be numerical.");
264 return;
265 }
266
267 window.setTitle(textName.getText());
268 name = textName.getText();
269 dialog.dispose();
270 dialog = null;
271 updateConfiguration();
272 }
273
274 private void dialogCancel() {
275 dialog.dispose();
276 dialog = null;
277 }
278
279 private String getEntityName(int x, int y) {
280 String returnVal = "";
281
282 returnVal = Scene.getDataManager().getEntity()[zAxis.getDataFilter().getTargetType()][getEntityId(x,y)].getName();
283 return returnVal;
284 }
285
286 private int getEntityId(int x, int y) {
287 Color color = image.getSortedColor(null,null,x,y);
288 if (color == null) return -1;
289 return ((RandomPainter)painter).getKeyFromColor(color);
290 }
291
292 protected void changeOrientation() {
293 if (normalOrientation)
294 ((AxesPanel)panel).setName("Stack","Number of invocation");
295 else
296 ((AxesPanel)panel).setName("Number of invocation" , "Stack");
297 super.changeOrientation();
298 sort();
299 }
300
301 protected void switchThread(int threadId) {
302 if (currentThread != threadId) {
303 stack = (Stack)methodStacks.get(new Integer(threadId));
304 if (stack == null) {
305 stack = new Stack();
306 methodStacks.put(new Integer(threadId),stack);
307 }
308 super.switchThread(threadId);
309 }
310 }
311
312 protected void installPainter() {
313 painter = new RandomPainter();
314 }
315
316 public JMenuItem[] createSelectionMenuItem() {
317 if (selectionMenu!=null) return selectionMenu;
318
319 itemSelectTimeFrame = new JCheckBoxMenuItem("Time Frame");
320 itemSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
321 itemSelectTimeFrame.addActionListener(new ActionListener() {
322 public void actionPerformed(ActionEvent e) {
323 boolean selected = itemSelectTimeFrame.isSelected();
324 SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
325 }
326 });
327 itemSelectTimeFrame.setSelected(true);
328
329 itemSelectOccurredEntities = new JCheckBoxMenuItem("Occurred Entities");
330 itemSelectOccurredEntities.setMnemonic(KeyEvent.VK_O);
331 itemSelectOccurredEntities.addActionListener(new ActionListener() {
332 public void actionPerformed(ActionEvent e) {
333 boolean selected = itemSelectOccurredEntities.isSelected();
334 SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
335 }
336 });
337 itemSelectOccurredEntities.setSelected(true);
338
339 selectionMenu = new JMenuItem[2];
340 selectionMenu[0] = itemSelectTimeFrame;
341 selectionMenu[1] = itemSelectOccurredEntities;
342
343 return selectionMenu;
344 }
345 }