001    /**
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: Feb 9, 2003
005     * Time: 5:21:17 PM
006     */
007    
008    package EVolve.visualization.XYViz.ValValViz;
009    
010    import java.awt.*;
011    import java.awt.event.*;
012    import java.awt.image.BufferedImage;
013    import java.util.*;
014    import javax.swing.*;
015    import EVolve.Scene;
016    import EVolve.data.Element;
017    import EVolve.data.Entity;
018    import EVolve.exceptions.NoDataPlotException;
019    import EVolve.util.painters.*;
020    import EVolve.util.xmlutils.datastructures.SerializedVisualization;
021    import EVolve.visualization.*;
022    import EVolve.visualization.Dimension;
023    
024    public class EventViz extends ValueValueVisualization{
025        private JTextField textBegin,textEnd,textBoxSize;
026        private int boxSize = 10;
027        private ArrayList menuList;
028        private JCheckBox chkSelectX, chkSelectTimeFrame, selectionOptions[] = null;
029        private JMenuItem itemReArrange;
030        private static int SELECT_OPTION = 0x0011;
031        private JComboBox comboPainter,comboPredictor;
032        private Painter[] painters;
033        private int selectedPainter;
034        private PredictorFactory[] factory; // predictor factories
035        private Predictor[] predictor; // predictors
036        private AutoImage entityMapImage;
037        private final int PredictionPainter = 0, RandomColorPainter = 1, DefaultPainter = 2;
038        private JLabel toEventNo;
039    
040            public EventViz() {
041                    super();
042                    menuList = new ArrayList();
043    
044                    beginCall = 0;
045                    endCall = 300;
046                    interval = 1;
047                    selectedPainter = 0;
048                    flipMagnifier = false;
049            }
050    
051        public EventViz(PredictorFactory[] factory) {
052            super();
053            menuList = new ArrayList();
054    
055            beginCall = 0;
056            endCall = 300;
057            interval = 1;
058            selectedPainter = 0;
059            painters = createPainters();
060            this.factory = factory;
061            flipMagnifier = false;
062        }
063    
064        private Painter[] createPainters() {
065            Painter[] painters = new Painter[3];
066            painters[0] = new EventPredictionPainter();
067            painters[1] = new RandomPainter();
068            painters[2] = new DefaultPainter();
069            return painters;
070        }
071    
072        public void restoreConfiguration(SerializedVisualization config) {
073    
074            beginCall = Long.parseLong(config.BeginEvent);
075            endCall = Long.parseLong(config.EndEvent);
076            boxSize = Integer.parseInt(config.BlockSize);
077            for (int i=0; i<painters.length; i++) {
078                if (painters[i].getName().equals(config.PainterName)) {
079                    selectedPainter = i;
080                    comboPainter.setSelectedIndex(i);
081                    break;
082                }
083            }
084    
085            textBoxSize.setText(config.BlockSize);
086            textBegin.setText(config.BeginEvent);
087            textEnd.setText(config.EndEvent);
088            super.restoreConfiguration(config);
089        }
090    
091        protected void updateConfiguration() {
092    
093            try {
094                beginCall = Integer.parseInt(textBegin.getText());
095                endCall = Integer.parseInt(textEnd.getText());
096                boxSize = Integer.parseInt(textBoxSize.getText());
097    
098                super.updateConfiguration();
099            } catch (NumberFormatException e) {
100                Scene.showErrorMessage("Begin call and end call must be an integer and smaller than "+Integer.MAX_VALUE+".");
101                configure();
102            };
103    
104        }
105    
106        public SerializedVisualization getCurrentConfiguration() {
107            SerializedVisualization data = super.getCurrentConfiguration();
108            data.xAxis = xAxis.getName();
109            data.yAxis = entityIdFilter.getName();
110            data.zAxis = filter2.getName();
111            data.PredictorName = comboPredictor != null ? factory[comboPredictor.getSelectedIndex()].getName() :
112                                                          factory[0].getName();
113            data.BeginEvent = String.valueOf(beginCall);
114            data.EndEvent = String.valueOf(endCall);
115            data.BlockSize = String.valueOf(boxSize);
116            data.PainterName = painters[selectedPainter].getName();
117    
118            return data;
119        }
120    
121        public Dimension[] createDimension() {
122            Dimension [] returnDimension = new Dimension[3];
123    
124            xAxis = new ValueDimension();
125            entityIdFilter = new ReferenceDimension();
126            filter2 = new ReferenceDimension();
127    
128            returnDimension[0] = xAxis;
129            returnDimension[1] = entityIdFilter;
130            returnDimension[2] = filter2;
131    
132            return returnDimension;
133        }
134    
135        protected Component createPanel() {
136            Component returnVal = super.createPanel();
137            canvas.setPanelFlag(AxesPanel.Null);
138            canvas.setZoomingSize(50,50);
139            flipMagnifier = false;
140            addMagnifier(canvas,flipMagnifier);
141    
142            return returnVal;
143        }
144    
145        public void preVisualize() {
146            super.preVisualize();
147            image = new AutoShapeImage(new EVolve.util.painters.shapes.Box(0,0,boxSize,boxSize));
148            entityMapImage = new AutoShapeImage(new EVolve.util.painters.shapes.Box(0,0,boxSize,boxSize));
149            canvas.setShapeSize(boxSize);
150            if (selectedPainter == 0) {
151                predictor = new Predictor[entityIdFilter.getMaxEntityNumber()];
152                for (int i = 0; i < predictor.length; i++) {
153                    if (comboPredictor == null)
154                        predictor[i] = factory[0].createPredictor();
155                    else
156                        predictor[i] = factory[comboPredictor.getSelectedIndex()].createPredictor();
157                }
158            }
159            getSelection();
160            installPainter();
161        }
162    
163        protected void receiveElement(Element element) {
164            if (element.isOptional()) return;
165    
166            long no = xAxis.getField(element) - 1;
167            long traceId = entityIdFilter.getField(element);
168            long z = filter2.getField(element);
169    
170            countEvents(no);
171            if ((no < beginCall)||(no > endCall)) {
172                return;
173            }
174            if (selectedPainter != RandomColorPainter)
175                painters[1].paint(entityMapImage,(no-beginCall)%(panel.getWidth()/boxSize),
176                                 (no-beginCall)/(panel.getWidth()/boxSize),traceId);
177    
178            if (selectedPainter == PredictionPainter) {// prediction color painter
179                painter.paint(image,no-beginCall,traceId,filter2.getEntityFromInt((int)z).getId());
180            } else {
181                painter.paint(image,(no-beginCall)%(panel.getWidth()/boxSize),
182                             (no-beginCall)/(panel.getWidth()/boxSize),traceId);
183            }
184        }
185    
186        public void visualize() {
187            sort();
188        }
189    
190        public void sort() {
191            try {
192                int width = panel.getWidth() - ((JScrollPane)panel).getVerticalScrollBar().getWidth();
193                canvas.setShapeSize(boxSize);
194                ((AutoShapeImage)image).reArrange(width,boxSize);
195                if (selectedPainter != 1) ((AutoShapeImage)entityMapImage).reArrange(width,boxSize);
196                BufferedImage result = image.getImage();
197                canvas.setImage(result);
198                canvas.setPreferredSize(new java.awt.Dimension(result.getWidth(),result.getHeight()));
199                canvas.revalidate();
200                canvas.repaint();
201            } catch (NoDataPlotException e) {
202                Scene.showErrorMessage(e.getMessage());
203            }
204        }
205    
206        protected String mouseMove(int x,int y) {
207            int X = canvas.getImageX(x);
208            int Y = canvas.getImageY(y);
209            AutoShapeImage aImage = (AutoShapeImage)image;
210            if (selectedPainter != 1)
211                aImage = (AutoShapeImage)entityMapImage;
212            Color color= (aImage == null) ? null : (Color)aImage.getColor(X/boxSize,Y/boxSize);
213            if (color != null) {
214                int mappedId = (int)((RandomPainter)painters[1]).getKeyFromColor(color);
215                Entity entity = entityIdFilter.getEntityFromInt(mappedId);
216                if (entity != null) {
217                    Scene.setStatus(entity.getName()
218                                    + " " + xAxis.getDataFilter().getName()+":"+ (x/boxSize + aImage.getW() * (y/boxSize)));
219                }
220            } else {
221                Scene.setStatus(" ");
222            }
223            return null;
224        }
225    
226        public void makeSelection() {
227            preMakeSelection();
228            if (selectionName==null) return;
229    
230            int w = image.getW();
231            int startX = canvas.getStartX()/boxSize;
232            int endX = canvas.getEndX()/boxSize;
233            int startY = canvas.getStartY()/boxSize;
234            int endY = canvas.getEndY()/boxSize;
235    
236            if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
237                Scene.showErrorMessage("The active data source used currently is different from \n" +
238                                       "this visualization, please choose \"" +
239                                       Scene.getDataSourceManager().getUsedDataSourceName(dataSourceId)+"\".");
240                return;
241            }
242    
243            long start = startX+startY*w;
244            long end = endX+endY*w;
245            long eventInterval[] = findEventInterval(start+beginCall, end+beginCall);
246            start = eventInterval[0];
247            end = eventInterval[1];
248    
249            ArrayList idList = new ArrayList();
250    
251            AutoShapeImage aImage = (AutoShapeImage)image;
252            if (selectedPainter != 1)
253                aImage = (AutoShapeImage)entityMapImage;
254    
255            for (int i=startX; i<=endX; i++) {
256                for (int j=startY; j<=endY; j++) {
257                    Long id = new Long(((RandomPainter)painters[RandomColorPainter]).getKeyFromColor((Color)aImage.getColor(i,j)));
258                    if (!idList.contains(id))
259                        idList.add(id);
260                }
261            }
262    
263            int selection[] = null;
264            if ((SELECT_OPTION & 0x00f0) == SELECT_OCCURRED_ENTITIES) {
265                selection = new int[idList.size()];
266                for (int i=0; i<selection.length; i++)
267                    selection[i] = ((Long)idList.get(i)).intValue();
268            } else {
269                selection = new int[entityIdFilter.getEntityNumber()];
270                for (int i=0; i<selection.length; i++)
271                    selection[i] = i;
272            }
273            if ((SELECT_OPTION & 0x000f) == 0x0000) {
274                start = 0;
275                end = Long.MAX_VALUE;
276            }
277            entityIdFilter.selectComparator(1);
278            entityIdFilter.makeSelection(selectionName,subjectDefinition.getType(),selection,start,end,timeMap);
279        }
280    
281        public JCheckBox[] createSelectionOptions() {
282            if (selectionOptions != null) return selectionOptions;
283    
284            chkSelectTimeFrame = new JCheckBox("Time Frame");
285            chkSelectTimeFrame.setMnemonic(KeyEvent.VK_T);
286            chkSelectTimeFrame.addActionListener(new ActionListener() {
287                public void actionPerformed(ActionEvent e) {
288                    boolean selected = chkSelectTimeFrame.isSelected();
289                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_TIME_FRAME);
290                }
291            });
292            chkSelectTimeFrame.setSelected(true);
293    
294            chkSelectX = new JCheckBox("Occurred Entitiies");
295            chkSelectX.setMnemonic(KeyEvent.VK_O);
296            chkSelectX.addActionListener(new ActionListener() {
297                public void actionPerformed(ActionEvent e) {
298                    boolean selected = chkSelectX.isSelected();
299                    SELECT_OPTION = switchOption(selected, SELECT_OPTION, SELECT_OCCURRED_ENTITIES);
300                }
301            });
302            chkSelectX.setSelected(true);
303    
304            selectionOptions = new JCheckBox[2];
305            selectionOptions[0] = chkSelectTimeFrame;
306            selectionOptions[1] = chkSelectX;
307    
308            return selectionOptions;
309        }
310    
311        public int getBoxSize() {
312            return boxSize;
313        }
314    
315        protected void installPainter() {
316            painters = createPainters();
317            painter = painters[selectedPainter];
318            if (selectedPainter == 0)
319                ((EventPredictionPainter)painter).setParameters(predictor,filter2.getDataFilter().getTargetType(),panel.getWidth()/boxSize);
320        }
321    
322        protected ArrayList createOptionalMenu() {
323            if (menuList.size() > 0) return null;
324    
325            menuList.clear();
326            itemReArrange = new JMenuItem("Rearrange");
327            itemReArrange.setMnemonic(KeyEvent.VK_R);
328            itemReArrange.addActionListener(new ActionListener() {
329                public void actionPerformed(ActionEvent e) {
330                    String newSize = (String)JOptionPane.showInputDialog(Scene.getFrame(),
331                            "Input new size for rectangles:",
332                            "Rearrange",
333                            JOptionPane.QUESTION_MESSAGE, null, null, String.valueOf(boxSize));
334                    if (newSize!=null) {
335                        boxSize = Integer.parseInt(newSize);
336                        if (selectedPainter != 1)
337                            ((AutoShapeImage)entityMapImage).reArrange(panel.getWidth(),boxSize);
338                        sort();
339                    }
340                }
341            });
342    
343            menuList.add(itemReArrange);
344            return menuList;
345        }
346    
347        public Object clone() {
348            EventViz o = (EventViz)super.clone();
349            o.dimension[0] = o.xAxis;
350            o.dimension[1] = o.entityIdFilter;
351            o.dimension[2] = o.filter2;
352            o.createDialog();
353            o.createMenu();
354            o.menuList = new ArrayList();
355            o.updateMenu();
356            o.painters = new Painter[3];
357            for (int i=0; i<o.painters.length; i++)
358                o.painters[i] = (Painter)painters[i].clone();
359            o.entityMapImage = (AutoShapeImage)entityMapImage.clone();
360    
361            return o;
362        }
363    
364     /**
365     *  customize UI
366     */
367        protected void createDialog() {
368            dialog = new JDialog(Scene.getFrame(), "Configure", true);
369    
370            JPanel panelTitle = new JPanel(new FlowLayout());
371            dialog.getContentPane().add(panelTitle, BorderLayout.NORTH);
372    
373            panelTitle.add(new JLabel("Title: "));
374    
375            textName = new JTextField(name, 12);
376            panelTitle.add(textName);
377    
378            JPanel panelMain = new JPanel(new BorderLayout());
379            panelMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Choose subject & dimensions"));
380            dialog.getContentPane().add(panelMain, BorderLayout.CENTER);
381    
382            JPanel panelName = new JPanel(new GridLayout(definition.getDimensionDefinition().length , 1, 5, 5));
383            panelMain.add(panelName, BorderLayout.WEST);
384    
385            panelName.add(new JLabel(" Subject:      "));
386            for (int i = 0; i < definition.getDimensionDefinition().length - 1; i++) {
387                panelName.add(new JLabel(" " + definition.getDimensionDefinition()[i].getName() + ":      "));
388            }
389    
390            JPanel panelCombo = new JPanel(new GridLayout(definition.getDimensionDefinition().length, 1, 5, 5));
391            panelMain.add(panelCombo, BorderLayout.CENTER);
392    
393            comboSubject = new JComboBox();
394            for (int i = 0; i < elementDefinition.length; i++) {
395                comboSubject.addItem(elementDefinition[i].getName());
396            }
397            comboSubject.addActionListener(new ActionListener() {
398                public void actionPerformed(ActionEvent e) {
399                    updateComboSubject();
400                }
401            });
402            panelCombo.add(comboSubject);
403    
404            comboDimension = new JComboBox[definition.getDimensionDefinition().length];
405            for (int i = 0; i < comboDimension.length; i++) {
406                comboDimension[i] = new JComboBox();
407                comboDimension[i].addActionListener(new ActionListener() {
408                    public void actionPerformed(ActionEvent e) {
409                        updateComboDimension();
410                    }
411                });
412            }
413            for (int i = 0; i < comboDimension.length - 1; i++)
414                panelCombo.add(comboDimension[i]);
415    
416            JPanel returnVal = new JPanel(new GridLayout(1, 1, 5, 5));
417            JPanel panelEvent = new JPanel(new GridLayout(6,2));
418    
419            Box panelBottom = new Box(BoxLayout.Y_AXIS);
420            returnVal.add(panelBottom);
421    
422            comboPredictor = new JComboBox();
423            for (int i = 0; i < factory.length; i++) {
424                comboPredictor.addItem(factory[i].getName());
425            }
426    
427            comboPainter = new JComboBox();
428            for (int i = 0; i < painters.length; i++) {
429                comboPainter.addItem(painters[i].getName());
430            }
431            comboPainter.addActionListener(new ActionListener() {
432                public void actionPerformed(ActionEvent e) {
433                    selectedPainter = comboPainter.getSelectedIndex();
434                    if (selectedPainter == 0) {
435                        comboPredictor.setEnabled(true);
436                        comboDimension[comboDimension.length-1].setEnabled(true);
437                    } else {
438                        comboPredictor.setEnabled(false);
439                        comboDimension[comboDimension.length-1].setEnabled(false);
440                    }
441                }
442            });
443            comboPainter.setSelectedIndex(selectedPainter);
444    
445            textBegin = new JTextField(String.valueOf(beginCall));
446            textEnd = new JTextField(String.valueOf(endCall));
447            textBoxSize = new JTextField(String.valueOf(boxSize));
448    
449            panelEvent.add(new JLabel("Painter used:  "));
450            panelEvent.add(comboPainter);
451            panelEvent.add(new JLabel(definition.getDimensionDefinition()[comboDimension.length -1].getName() + ":   "));
452            panelEvent.add(comboDimension[comboDimension.length -1]);
453            panelEvent.add(new JLabel("Predictor: "));
454            panelEvent.add(comboPredictor);
455            panelEvent.add(new JLabel("From Event No:"));
456            panelEvent.add(textBegin);
457    
458            String range = String.valueOf(Scene.getDataManager().getDataSource().getNumberOfEvents(elementDefinition[comboSubject.getSelectedIndex()].getName()));
459            toEventNo = new JLabel("To Event No:("+range+")");
460            panelEvent.add(toEventNo);
461            panelEvent.add(textEnd);
462            panelEvent.add(new JLabel("Box Size:"));
463            panelEvent.add(textBoxSize);
464    
465            panelBottom.add(panelEvent);
466    
467            updateComboSubject();
468    
469            panelMain.add(returnVal, BorderLayout.SOUTH);
470    
471            JPanel panelButton = new JPanel(new FlowLayout());
472            dialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
473    
474            JButton buttonApply = new JButton("Apply");
475            buttonApply.addActionListener(new ActionListener() {
476                public void actionPerformed(ActionEvent e) {
477                    dialogApply();
478                }
479            });
480            panelButton.add(buttonApply);
481    
482            JButton buttonCancel = new JButton("Cancel");
483            buttonCancel.addActionListener(new ActionListener() {
484                public void actionPerformed(ActionEvent e) {
485                    dialogCancel();
486                }
487            });
488            panelButton.add(buttonCancel);
489    
490            //*************
491            for (int i=0; i<comboSubject.getItemCount(); i++) {
492                if ((comboSubject.getItemAt(i)).equals(subjectDefinition.getName())) {
493                    comboSubject.setSelectedIndex(i);
494                    break;
495                }
496            }
497            for (int i=0;i<comboDimension.length;i++) {
498                for (int j =0 ; j<comboDimension[i].getItemCount();j++) {
499                    if (comboDimension[i].getItemAt(j).equals(dimension[i].getDataFilter().getName())) {
500                        comboDimension[i].setSelectedIndex(j);
501                        break;
502                    }
503                }
504            }
505        }
506    
507    }