001    /* EVolve - an Extensible Software Visualization Framework
002     * Copyright (C) 2001-2002 Qin Wang
003     *
004     * This library is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU Library General Public
006     * License as published by the Free Software Foundation; either
007     * version 2 of the License, or (at your option) any later version.
008     *
009     * This library is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
012     * Library General Public License for more details.
013     *
014     * You should have received a copy of the GNU Library General Public
015     * License along with this library; if not, write to the
016     * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
017     * Boston, MA 02111-1307, USA.
018     */
019    
020    /*
021     * EVolve is distributed at http://www.sable.mcgill.ca/EVolve/
022     */
023    
024    package EVolve.visualization;
025    
026    import java.awt.*;
027    import java.awt.event.*;
028    import java.util.*;
029    import javax.swing.*;
030    import EVolve.Scene;
031    import EVolve.data.ElementDefinition;
032    import EVolve.exceptions.NoDataPlotException;
033    import EVolve.util.phasedetectors.PhaseOperation;
034    import EVolve.util.xmlutils.datastructures.SerializedVisualization;
035    import EVolve.visualization.VizFactory.VisualizationFactory;
036    import EVolve.visualization.XYViz.XYVisualization;
037    
038    public class VisualizationManager {
039        private VisualizationFactory[] factory;
040        private ArrayList visualizationList;
041        private ArrayList toVisualize;
042        private Visualization[][] visualization;
043    
044        private JDialog dialog;
045        private JList listVisualization;
046        private DefaultListModel model;
047    
048        private boolean phaseDetectorEnabled;
049        private PhaseOperation phaseOperation;
050    
051        public VisualizationManager(VisualizationFactory[] factory) {
052            this.factory = factory;
053            this.visualizationList = new ArrayList();
054            this.toVisualize = new ArrayList();
055            this.dialog = null;
056            phaseDetectorEnabled = false;
057            phaseOperation = new PhaseOperation();
058        }
059    
060        public void init() {
061            ArrayList newVisualizationList = new ArrayList();
062            ArrayList newToVisualize = new ArrayList();
063    
064            for (int i=0; i<visualizationList.size(); i++) {
065                Visualization visual = (Visualization)visualizationList.get(i);
066                if (visual.getDataSourceId() != Scene.getDataSourceManager().getCurrentDataSourceId())
067                    newVisualizationList.add(visual);
068            }
069    
070            for (int i=0; i<toVisualize.size(); i++) {
071                Visualization visual = (Visualization)toVisualize.get(i);
072                if (visual.getDataSourceId() != Scene.getDataSourceManager().getCurrentDataSourceId())
073                    newToVisualize.add(visual);
074            }
075            visualizationList = newVisualizationList;
076            toVisualize = newToVisualize;
077        }
078    
079        private void createDialog() {
080            dialog = new JDialog(Scene.getFrame(), "Select Visualizations", true);
081            model = new DefaultListModel();
082            listVisualization = new JList(model);
083            listVisualization.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
084    
085            JScrollPane scrollPane = new JScrollPane(listVisualization);
086            scrollPane.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Choose visualizations"));
087            dialog.getContentPane().add(scrollPane, BorderLayout.CENTER);
088    
089            JPanel panelButton = new JPanel(new FlowLayout());
090            dialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
091    
092            JButton buttonApply = new JButton("Apply");
093            buttonApply.addActionListener(new ActionListener() {
094                public void actionPerformed(ActionEvent e) {
095                    dialogApply();
096                }
097            });
098            panelButton.add(buttonApply);
099    
100            JButton buttonCancel = new JButton("Cancel");
101            buttonCancel.addActionListener(new ActionListener() {
102                public void actionPerformed(ActionEvent e) {
103                    dialogCancel();
104                }
105            });
106            panelButton.add(buttonCancel);
107        }
108    
109        public String[] getFactoryName() {
110            ArrayList list = new ArrayList();
111            for (int i = 0; i < factory.length; i++) {
112                ElementDefinition[] temp = Scene.getDataManager().getElementDefinition(factory[i].getDefinition());
113                if (temp.length != 0) {
114                    list.add(factory[i]);
115                }
116            }
117    
118            String[] returnVal = new String[list.size()];
119            for (int i = 0; i < returnVal.length; i++) {
120                returnVal[i] = ((VisualizationFactory)(list.get(i))).getName();
121            }
122            return returnVal;
123        }
124    
125        public Visualization newVisualization(String name) {
126            Visualization newVisualization = null;
127    
128            for (int i = 0; i < factory.length; i++) {
129                if (name.equals(factory[i].getName())) {
130                    newVisualization = factory[i].createVisualization();
131                    newVisualization.setName(name);
132                    newVisualization.setDataSourceId(Scene.getDataSourceManager().getCurrentDataSourceId());
133                    newVisualization.setFactory(factory[i]);
134                    newVisualization.setDefinition(factory[i].getDefinition());
135                    break;
136                }
137            }
138            visualizationList.add(newVisualization);
139            toVisualize.add(newVisualization);
140            Scene.getUIManager().addVisualization(newVisualization);
141            return newVisualization;
142        }
143    
144        public void removeVisualization(Visualization visualization) {
145            visualizationList.remove(visualization);
146            toVisualize.remove(visualization);
147        }
148    
149        public void preVisualize() {
150            if (dialog == null) {
151                createDialog();
152            }
153    
154            int[] selected = new int[toVisualize.size()];
155            int selectedCounter = 0;
156    
157            model.removeAllElements();
158    
159            for (int i = 0; i < visualizationList.size(); i++) {
160                model.addElement(((Visualization)(visualizationList.get(i))).getName());
161                if (toVisualize.indexOf(visualizationList.get(i)) != -1) {
162                    selected[selectedCounter] = i;
163                    selectedCounter++;
164                }
165            }
166    
167            listVisualization.setSelectedIndices(selected);
168    
169            Scene.getUIManager().showDialog(dialog, 270, 360);
170        }
171    
172        public void receiveEvent(EVolve.data.Event event) {
173            int currentDsourceId = Scene.getDataSourceManager().getCurrentDataSourceId();
174            for (int i = 0; i < visualization[event.getType()].length; i++) {
175                int dataSourceId = visualization[event.getType()][i].getDataSourceId();
176                if (dataSourceId == currentDsourceId)
177                    visualization[event.getType()][i].receiveElement(event);
178            }
179        }
180    
181        public void visualize() {
182            try {
183                for (int i = 0; i < visualization.length; i++) {
184                    for (int j = 0; j < visualization[i].length; j++) {
185                        int dataSourceId = visualization[i][j].getDataSourceId();
186                        if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId())
187                                continue;
188    
189                        for (int k = 0; k < visualization[i][j].getDimension().length; k++) {
190                            if (visualization[i][j].getDimension()[k] instanceof ReferenceDimension) {
191                                ((ReferenceDimension)(visualization[i][j].getDimension()[k])).visualize();
192                            }
193                        }
194                        visualization[i][j].visualize();
195                        visualization[i][j].updateMenu();
196                        visualization[i][j].enableSortMenu();
197                    }
198                }
199            } catch (NoDataPlotException e) { //a non-fatal exception, show message and then ignore it
200                Scene.showErrorMessage(e.getMessage());
201            }
202    
203        }
204    
205        private void dialogApply() {
206            dialog.setVisible(false);
207    
208            toVisualize.clear();
209    
210            int[] selected = listVisualization.getSelectedIndices();
211    
212            for (int i = 0; i < selected.length; i++) {
213                toVisualize.add(visualizationList.get(selected[i]));
214            }
215    
216            if (toVisualize.size() != 0) {
217                prepareListToBeVisualized();
218                Scene.visualize();
219            }
220        }
221    
222        private void dialogCancel() {
223            dialog.setVisible(false);
224        }
225    
226        public ArrayList getVisualizationType() {
227            ArrayList returnVal = new ArrayList();
228            for (int i = 0; i < visualizationList.size(); i++) {
229                String s = "" + ((Visualization)(visualizationList.get(i))).getSubjectDefinition().getType() + "";
230                if (returnVal.indexOf(s) == -1) {
231                    returnVal.add(s);
232                }
233            }
234    
235            return returnVal;
236        }
237    
238        public VisualizationFactory getFactory(String name) {
239            VisualizationFactory retFac = null;
240            for (int i = 0; i < factory.length; i++) {
241                if (name.equals(factory[i].getName())) {
242                    retFac = factory[i];
243                    break;
244                }
245            }
246            return retFac;
247        }
248    
249        public void autoPreVisualize(SerializedVisualization conf) {
250            Visualization visual= (Visualization)visualizationList.get(0);
251    
252            visual.restoreConfiguration(conf);
253    
254            toVisualize.clear();
255    
256            toVisualize.add(visualizationList.get(0));
257    
258            if (toVisualize.size() != 0) {
259                prepareListToBeVisualized();
260            }
261        }
262    
263        public void autoSaveResult(String path, String dataFn) {
264            Visualization visual= (Visualization)visualizationList.get(0);
265            visual.autoSave(path,dataFn);
266        }
267    
268        public ArrayList getVisualizationList() {
269            return visualizationList;
270        }
271    
272        public ArrayList getVisualizationList(int dataSourceId) {
273            ArrayList list = new ArrayList();
274            int dsourceId = Scene.getDataSourceManager().getCurrentDataSourceId();
275    
276            for (int i=0; i<visualizationList.size(); i++) {
277                Visualization visual = (Visualization)visualizationList.get(i);
278                if (visual.getDataSourceId() == dsourceId)
279                    list.add(visual);
280            }
281            return list;
282        }
283    
284        public void prepareListToBeVisualized() {
285            visualization = new Visualization[Scene.getDataManager().getElementDefinition().length][];
286            for (int i = 0; i < visualization.length; i++) {
287                ArrayList list = new ArrayList();
288                for (int j = 0; j < toVisualize.size(); j++) {
289                    if (((Visualization)(toVisualize.get(j))).getSubjectDefinition().getType() == i) {
290                        list.add(toVisualize.get(j));
291                    }
292                }
293                visualization[i] = new Visualization[list.size()];
294                for (int j = 0; j < visualization[i].length; j++) {
295                    visualization[i][j] = (Visualization)(list.get(j));
296                    visualization[i][j].preVisualize();
297                    for (int k = 0; k < visualization[i][j].getDimension().length; k++) {
298                        visualization[i][j].getDimension()[k].preVisualize();
299                    }
300                }
301            }
302        }
303    
304        // following methods are used in predefined visualization
305        public void cleanup() {
306            Scene.getUIManager().clearWindowsList();
307            for (int i=0; i<visualizationList.size(); i++) {
308                Visualization visual =(Visualization) visualizationList.get(i);
309                visual.getWindow().dispose();
310            }
311            init();
312        }
313    
314        // following methods are used in linked visualization
315        public void addAllVisualizations() {
316            toVisualize.clear();
317            for (int i=0; i<visualizationList.size(); i++)
318                toVisualize.add(visualizationList.get(i));
319        }
320    
321        public void prepareForLinkedViz(ArrayList viz,int beginRepaint) {
322            toVisualize.clear();
323    
324            for (int i=beginRepaint; i< viz.size(); i++) {
325                toVisualize.add(viz.get(i));
326            }
327            if (toVisualize.size() != 0)
328                prepareListToBeVisualized();
329        }
330    
331        public Visualization prepareForAsynOverlapViz(String name) {
332            Visualization newVisualization = null;
333    
334            for (int i = 0; i < factory.length; i++) {
335                if (name.equals(factory[i].getName())) {
336                    newVisualization = factory[i].createVisualization();
337                    newVisualization.setName(name);
338                    newVisualization.setFactory(factory[i]);
339                    newVisualization.setDefinition(factory[i].getDefinition());
340                    break;
341                }
342            }
343            return newVisualization;
344        }
345    
346        public void visualizeNow() {
347            Visualization visual = getActiveVisualization();
348    
349            if (visual != null) {
350                int dataSourceId = visual.getDataSourceId();
351    
352                if (dataSourceId != Scene.getDataSourceManager().getCurrentDataSourceId()) {
353                    Scene.getUIManager().switchDataSource(dataSourceId);
354                }
355    
356                visualization = new Visualization[Scene.getDataManager().getElementDefinition().length][];
357                for (int i = 0; i < visualization.length; i++) {
358                    ArrayList list = new ArrayList();
359                    if (visual.getSubjectDefinition().getType() == i) {
360                        list.add(visual);
361                    }
362                    visualization[i] = new Visualization[list.size()];
363                    for (int j = 0; j < visualization[i].length; j++) {
364                        visualization[i][j] = (Visualization)(list.get(j));
365                        visualization[i][j].preVisualize();
366                        for (int l = 0; l < visualization[i][j].getDimension().length; l++) {
367                            (visualization[i][j].getDimension()[l]).preVisualize();
368                        }
369                    }
370                }
371    
372                Scene.visualize();
373            }
374       }
375    
376        public void cloneVisualization() {
377            Visualization visual = getActiveVisualization();
378    
379            if (visual == null) return;
380    
381            SerializedVisualization configuration = visual.getCurrentConfiguration();
382    
383            Visualization newViz = (Visualization)visual.clone();
384    
385            visualizationList.add(newViz);
386            toVisualize.add(newViz);
387            Scene.getUIManager().addVisualization(newViz);
388            configuration.WindowTitle += " - cloned";
389            newViz.setName(visual.getName()+" - cloned");
390            newViz.restoreConfiguration(configuration);
391    
392            try {
393                newViz.getWindow().setBounds(visual.getWindow().getBounds());
394                newViz.visualize();
395                newViz.updateMenu();
396                newViz.enableSortMenu();
397            } catch (Exception e) {
398                // when the clone object is not visualized yet, this
399                // harmless exception happens.
400            }
401        }
402    
403        public Visualization getActiveVisualization() {
404    
405            Visualization visual = null;
406    
407            for (int i=0; i<visualizationList.size(); i++) {
408                visual = (Visualization)visualizationList.get(i);
409                if (visual.getWindow().isSelected()) {
410                    return visual;
411                }
412                visual = null;
413            }
414    
415            return visual;
416        }
417    
418        public void enablePhaseDetector(boolean enabled) {
419            phaseDetectorEnabled = enabled;
420            for (int i=0; i<visualizationList.size(); i++) {
421                Visualization visual = (Visualization)visualizationList.get(i);
422    
423                if (visual instanceof TableViz) continue;
424    
425                ((XYVisualization)visual).enablePhaseDetector(enabled);
426            }
427        }
428    
429        public boolean isPhaseDetectorEnabled() {
430            return phaseDetectorEnabled;
431        }
432    
433        public void refreshPhases() {
434            for (int i=0; i<visualizationList.size(); i++) {
435                Visualization visual = (Visualization)visualizationList.get(i);
436                visual.sort();
437            }
438    
439        }
440    
441        public PhaseOperation getPhaseOperation() {
442            return phaseOperation;
443        }
444    
445        public ArrayList removeDataSource(int[] tobeRemoved) {
446            ArrayList dmList = Scene.getDataSourceManager().getDataManagerList();
447            HashMap idMap = new HashMap();
448    
449            int k=0;
450            for (int i=0; i<dmList.size(); i++) {
451                boolean remove = false;
452                for (int j=0; j<tobeRemoved.length; j++) {
453                    if (i==tobeRemoved[j]) {
454                        remove = true;
455                        k++;
456                    }
457                }
458                if (!remove)
459                    idMap.put(new Integer(i),new Integer(i-k));
460            }
461    
462            ArrayList newVisualizationList = new ArrayList();
463            ArrayList newWindowList = new ArrayList();
464            for (int i=0; i<visualizationList.size(); i++) {
465                Visualization visual = (Visualization)visualizationList.get(i);
466                int oldDatasourceId = visual.getDataSourceId();
467                if (!idMap.containsKey(new Integer(oldDatasourceId))) {
468                    EVolve.Window window = visual.getWindow();
469                    window.dispose();
470                } else {
471                    visual.setDataSourceId(((Integer)idMap.get(new Integer(oldDatasourceId))).intValue());
472                    newWindowList.add(visual.getWindow());
473                    newVisualizationList.add(visual);
474                }
475            }
476            visualizationList = newVisualizationList;
477    
478            return newWindowList;
479        }
480    }
481