001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-9-6
005     * Time: 15:00:07
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util;
010    
011    import EVolve.visualization.*;
012    import EVolve.visualization.Dimension;
013    import EVolve.*;
014    import EVolve.data.*;
015    import javax.swing.*;
016    import javax.imageio.ImageWriter;
017    import javax.imageio.ImageIO;
018    import java.util.*;
019    import java.awt.*;
020    import java.awt.image.BufferedImage;
021    import java.awt.event.*;
022    import java.io.File;
023    import java.io.IOException;
024    
025    public abstract class OverlapVisualization {
026        protected JDialog dialog;
027        protected JPanel panel;
028        protected ArrayList visualizationList;
029        private String xAxisName,yAxisName;
030        protected EVolve.Window window;
031        protected int xMax;
032        protected ArrayList colorList;
033        protected Entity[][] maxEntity;
034        protected boolean noEntityAvailable;
035    
036        private JPopupMenu popup;
037        private JMenu menuSort;
038        private JMenuItem[][] itemSort;
039        private JMenu[] menuDimension;
040        private JMenuItem itemSave;
041        private ArrayList refLocation;
042        private Magnifier magnifier;
043        private AutoImage overlappedImage;
044        private boolean shift_pressed;
045    
046    
047        public abstract void createDialog();
048    
049        public abstract boolean isOverlapable(Visualization visualToBeOverlapped);
050    
051        public abstract void overlappedVisualize();
052    
053        public OverlapVisualization() {
054            visualizationList = new ArrayList();
055    
056            maxEntity = new Entity[2][];
057            maxEntity[0] = null;
058            maxEntity[1] = null;
059            noEntityAvailable = false;
060            shift_pressed = false;
061    
062            panel = createPanel();
063            addPopupTrigger(panel);
064        }
065    
066        public void showWindow() {
067            createDialog();
068            Scene.getUIManager().showDialog(dialog, dialog.getWidth(), dialog.getHeight());
069        }
070    
071        public void newOverlappedVisualization(OverlapVisualization oVisual) {
072            Visualization visual = (Visualization)visualizationList.get(0);
073            xAxisName = visual.getDimension()[0].getName();
074            yAxisName = visual.getDimension()[1].getName();
075            window = Scene.getUIManager().addOverlappedVisualization(oVisual);
076            createMenu();
077        }
078    
079        public JPanel getPanel() {
080            return panel;
081        }
082    
083        private JPanel createPanel() {
084            AxesPanel returnVal = new AxesPanel();
085    
086            magnifier = new Magnifier();
087            returnVal.addMouseMotionListener(new MouseMotionAdapter() {
088                public void mouseMoved(MouseEvent e) {
089                    if (e.isShiftDown()) shift_pressed = true;
090                    else shift_pressed = false;
091    
092                    if (e.isControlDown()) {
093                        magnifier.showWindow(overlappedImage,null,
094                                            ((AxesPanel)panel).getImageX(e.getX()),
095                                            ((AxesPanel)panel).getImageY(e.getY()));
096                        ((AxesPanel)panel).drawZoomingArea(e.getX(),e.getY());
097                    }
098                    mMoved(e.getX(), e.getY());
099                }
100            });
101    
102            returnVal.addMouseMotionListener(new MouseMotionAdapter() {
103                public void mouseDragged(MouseEvent e) {
104                    mMoved(e.getX(), e.getY());
105                }
106            });
107    
108            return returnVal;
109        }
110    
111        private void mMoved(int x, int y) {
112            int xIndex = ((AxesPanel)panel).getImageX(x);
113            int yIndex = ((AxesPanel)panel).getImageY(y);
114    
115            if (noEntityAvailable) {
116                Scene.setStatus("No entity information available when temporal viz overlapped.");
117            } else {
118                try {
119                    if (shift_pressed && (getOverlappedSortedColor(xIndex,yIndex)==null)) {
120                        Scene.setStatus("  ");
121                        return;
122                    }
123    
124                    if (maxEntity[0] == null) {
125                        if ((yIndex >= 0) && (yIndex < maxEntity[1].length)) {
126                            Scene.setStatus(getEntityName(1,yIndex));
127                        }
128                    } else {
129                        if ((xIndex >= 0) && (xIndex < maxEntity[0].length) && (yIndex >= 0) && (yIndex < maxEntity[1].length)) {
130                            Scene.setStatus("X: " + getEntityName(0,xIndex)
131                                             + "   Y: " + getEntityName(1,yIndex));
132                        }
133                    }
134                } catch (Exception e) {
135                    System.out.println("Exception");
136                }
137            }
138        }
139    
140        private void createMenu() {
141            popup = new JPopupMenu();
142    
143            menuSort = new JMenu("Sort");
144            menuSort.setMnemonic(KeyEvent.VK_S);
145            menuSort.setEnabled(false);
146            popup.add(menuSort);
147    
148            ArrayList tempList = new ArrayList();
149            Visualization visual = (Visualization)visualizationList.get(visualizationList.size()-1);
150            EVolve.visualization.Dimension [] dimension = visual.getDimension();
151            refLocation = new ArrayList();
152            for (int i = 0; i < dimension.length; i++) {
153                if (dimension[i] instanceof ReferenceDimension) {
154                    tempList.add(new Integer(i));
155                    refLocation.add(new Integer(i));
156                }
157            }
158    
159            ReferenceDimension[] referenceDimension = new ReferenceDimension[tempList.size()];
160            menuDimension = new JMenu[tempList.size()];
161            itemSort = new JMenuItem[tempList.size()][];
162            for (int i = 0; i < tempList.size(); i++) {
163                int j = ((Integer)(tempList.get(i))).intValue();
164                referenceDimension[i] = (ReferenceDimension)(dimension[j]);
165                menuDimension[i] = new JMenu(visual.getDefinition().getDimensionDefinition()[j].getName());
166                menuSort.add(menuDimension[i]);
167            }
168    
169            for (int i = 0; i < referenceDimension.length; i++) {
170                ArrayList comparatorList = referenceDimension[i].getComparator();
171                itemSort[i] = new JMenuItem[comparatorList.size()];
172                menuDimension[i].removeAll();
173                for (int j = 0; j < itemSort[i].length; j++) {
174                    itemSort[i][j] = new JMenuItem(((EntityComparator)(comparatorList.get(j))).getName());
175                    itemSort[i][j].addActionListener(new ActionListener() {
176                        public void actionPerformed(ActionEvent e) {
177                            selectComparator(e);
178                        }
179                    });
180                    menuDimension[i].add(itemSort[i][j]);
181                }
182            }
183    
184            itemSave = new JMenuItem("Save...");
185            itemSave.setMnemonic(KeyEvent.VK_V);
186            itemSave.addActionListener(new ActionListener() {
187                public void actionPerformed(ActionEvent e) {
188                    save();
189                }
190            });
191            popup.add(itemSave);
192        }
193    
194        protected void showPopup(MouseEvent e) {
195            popup.show(e.getComponent(), e.getX(), e.getY());
196        }
197    
198        protected void addPopupTrigger(Component component) {
199            component.addMouseListener(new MouseAdapter() {
200                public void mouseReleased(MouseEvent e) {
201                    if (e.isPopupTrigger()) {
202                        showPopup(e);
203                    }
204                }
205    
206                public void mousePressed(MouseEvent e) {
207                    if (e.isPopupTrigger()) {
208                        showPopup(e);
209                    }
210                }
211            });
212        }
213    
214        protected void enableSortMenu() {
215            menuSort.setEnabled(true);
216            Scene.getUIManager().enableFileMenus();
217        }
218    
219        protected String getColorHex(Color color) {
220            String returnVal = Integer.toHexString(color.getBlue());
221            if (returnVal.length() < 2) {
222                returnVal = "0" + returnVal;
223            }
224            returnVal = Integer.toHexString(color.getGreen()) + returnVal;
225            if (returnVal.length() < 4) {
226                returnVal = "0" + returnVal;
227            }
228            returnVal = Integer.toHexString(color.getRed()) + returnVal;
229            if (returnVal.length() < 6) {
230                returnVal = "0" + returnVal;
231            }
232    
233            return returnVal;
234        }
235    
236        private void save() {
237            BufferedImage image = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
238            panel.paint(image.getGraphics());
239            ImageWriter writer = (ImageWriter)(ImageIO.getImageWritersByFormatName("png").next());
240    
241            JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastResultDir());
242    
243            if (fc.showSaveDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
244                File file = fc.getSelectedFile();
245                Scene.getUIManager().setLastResultDir(file.getPath());
246                try {
247                    writer.setOutput(ImageIO.createImageOutputStream(file));
248                    writer.write(image);
249                } catch (IOException e) {}
250            }
251    
252        }
253    
254        public AutoImage getSortImage() {
255            Visualization visual = null;
256            overlappedImage = new AutoImage();
257            ReferenceDimension sortedDimension[] = new ReferenceDimension[2];
258    
259            xMax = Integer.MIN_VALUE;
260    
261            for (int i=0; i<visualizationList.size(); i++) {
262                AutoImage image;
263                sortedDimension[0] = null;
264                sortedDimension[1] = null;
265    
266                visual = (Visualization)visualizationList.get(i);
267    
268                for (int j=0; j<2; j++) {
269                    Dimension dim = visual.getDimension()[j];
270                    if (dim instanceof ReferenceDimension)
271                        sortedDimension[j] = (ReferenceDimension)dim;
272                }
273                image = visual.getImage().getSortedImage(sortedDimension[0],sortedDimension[1]);
274                int w = image.getW();
275                int h = image.getH();
276    
277                for (int j=0; j<w; j++) {
278                    for (int k=0; k<h; k++) {
279                        if (image.getColor(j,k) == null) continue;
280    
281                        if (overlappedImage.getColor(j,k) == null )
282                            overlappedImage.setColor(j,k,image.getColor(j,k));
283                        else
284                            overlappedImage.setColor(j,k,new Color(153,0,153));
285                    }
286                }
287                visual.visualize();
288                if (xMax < visual.getxMax()) xMax = visual.getxMax();
289            }
290    
291            String[] comparatorName = new String[2];
292            for (int i=0; i<2; i++) {
293                if (visual.getDimension()[i] instanceof ReferenceDimension) {
294                    comparatorName[i] = ((ReferenceDimension)visual.getDimension()[i]).getSelectedComparatorName();
295                } else {
296                    comparatorName[i] = "";
297                }
298            }
299    
300            visual = (Visualization)visualizationList.get(0);
301    
302            ((AxesPanel)panel).setName(timeHeader(visual.getDimension()[0]) + xAxisName + " (" + ((maxEntity[0] == null) ? xMax : maxEntity[0].length)+
303                                       ((comparatorName[0].length()==0) ? "" : ", "+ comparatorName[0]) + ")",
304                                       timeHeader(visual.getDimension()[1]) + yAxisName + " (" + maxEntity[1].length +
305                                       ((comparatorName[1].length()==0) ? "" : ", "+ comparatorName[1]) + ")");
306            return overlappedImage;
307        }
308    
309        public void sort() {
310            ((AxesPanel)panel).setImage(getSortImage().getImage());
311            panel.repaint();
312        }
313    
314        private void selectComparator(ActionEvent e) {
315            for (int i = 0; i < itemSort.length; i++) {
316                for (int j = 0; j < itemSort[i].length; j++) {
317                    if (itemSort[i][j] == e.getSource()) {
318                        if (itemSort[i][j].getText().equals("Temporal")) {
319                            noEntityAvailable = true;
320                        } else {
321                            noEntityAvailable = false;
322                        }
323                        for (int k=0; k<visualizationList.size(); k++) {
324                            Visualization visual = (Visualization)visualizationList.get(k);
325                            ReferenceDimension ref = (ReferenceDimension)visual.getDimension()[((Integer)refLocation.get(i)).intValue()];
326                            ref.selectComparator(j);
327                        }
328                        sort();
329                        return;
330                    }
331                }
332            }
333        }
334    
335        public void unregisterOverlappedVisualization(Visualization visual) {
336            for (int i=0;i<visualizationList.size();i++) {
337                if (((Visualization)visualizationList.get(i)).getVisualizationID() == visual.getVisualizationID()) {
338                    visualizationList.remove(i);
339                }
340            }
341            if (visualizationList.size() ==1) visualizationList.clear();
342        }
343    
344        private String getEntityName(int dim,int index) {
345            Entity entity = null;
346            for (int i=0; i<visualizationList.size(); i++) {
347                Visualization visual = (Visualization)visualizationList.get(i);
348                ReferenceDimension ref = (ReferenceDimension)visual.getDimension()[dim];
349                entity = ref.getEntity(index);
350                if (entity != null) {
351                    break;
352                }
353            }
354    
355            return (entity == null) ? null : entity.getName();
356        }
357    
358        private Color getOverlappedSortedColor(int x, int y) {
359            Color returnVal = null;
360            ReferenceDimension sortedDimension[] = new ReferenceDimension[2];
361            for (int i=0; i<visualizationList.size(); i++) {
362                Visualization visual = (Visualization)visualizationList.get(i);
363                for (int j=0; j<2; j++) {
364                    Dimension dim = visual.getDimension()[j];
365                    if (dim instanceof ReferenceDimension)
366                        sortedDimension[j] = (ReferenceDimension)dim;
367                }
368                returnVal = visual.getImage().getSortedColor(sortedDimension[0],sortedDimension[1],x,y);
369                if (returnVal != null) break;
370            }
371    
372            return returnVal;
373        }
374    
375        private String timeHeader(Dimension dim) {
376            String property[] = dim.getDataFilter().getProperty();
377    
378            if (property == null) return "";
379    
380            for (int i=0; i<property.length; i++) {
381                if (property[i].equals("time"))
382                    return "Time - ";
383            }
384            return "";
385        }
386    
387        public void cleanup() {
388            maxEntity = null;
389            itemSort = null;
390            menuDimension = null;
391            magnifier.cleanup();
392        }
393    }