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    }