001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-9-6
005     * Time: 15:53:41
006     * To change template for new class use 
007     * Code Style | Class Templates options (Tools | IDE Options).
008     */
009    package EVolve.util.overlappers;
010    
011    import java.awt.BorderLayout;
012    import java.awt.Color;
013    import java.awt.FlowLayout;
014    import java.awt.Rectangle;
015    import java.awt.event.ActionEvent;
016    import java.awt.event.ActionListener;
017    import java.io.File;
018    import java.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.HashSet;
021    import java.util.Iterator;
022    
023    import javax.swing.BorderFactory;
024    import javax.swing.Box;
025    import javax.swing.BoxLayout;
026    import javax.swing.DefaultListModel;
027    import javax.swing.JButton;
028    import javax.swing.JColorChooser;
029    import javax.swing.JDialog;
030    import javax.swing.JFileChooser;
031    import javax.swing.JLabel;
032    import javax.swing.JList;
033    import javax.swing.JPanel;
034    import javax.swing.JScrollPane;
035    import javax.swing.JTextField;
036    import javax.swing.filechooser.FileSystemView;
037    
038    import EVolve.Scene;
039    import EVolve.exceptions.EVolveException;
040    import EVolve.exceptions.NoDataPlotException;
041    import EVolve.util.predefinedutils.VisualizationSerializer;
042    import EVolve.util.xmlutils.datastructures.SerializedVisualization;
043    import EVolve.util.xmlutils.datastructures.SerializedData;
044    import EVolve.util.unifyutils.Unification;
045    import EVolve.visualization.ReferenceDimension;
046    import EVolve.visualization.Visualization;
047    import EVolve.visualization.XYViz.XYVisualization;
048    
049    public class AsynchronousOverlapper extends OverlapVisualization {
050        private final String name = "AsynchronousOverlapper";
051        private JList fileList,procList;
052        private JTextField txtConfName;
053        private HashSet setFile;
054        private ArrayList setProcessFiles;
055        private DefaultListModel procListModel,fileListModel;
056        private ArrayList[] entityList;
057        private ArrayList[] referenceDimList;
058    
059        public AsynchronousOverlapper() {
060            super();
061            dialog = null;
062            setProcessFiles = new ArrayList();
063            setFile = new HashSet();
064            colorList = new ArrayList();
065            entityList = new ArrayList[2];
066            entityList[0] = new ArrayList();
067            entityList[1] = new ArrayList();
068            referenceDimList = new ArrayList[2];
069            referenceDimList[0] = new ArrayList();
070            referenceDimList[1] = new ArrayList();
071        }
072    
073        public String getName() {
074            return name;
075        }
076    
077        public void createDialog() {
078            setFile.clear();
079            setProcessFiles.clear();
080            colorList.clear();
081            visualizationList.clear();
082            dialog = new JDialog(Scene.getFrame(),"Overlap Visualizations...",true);
083            dialog.setBounds(new Rectangle(500,400));
084    
085            JPanel batchName = new JPanel(new FlowLayout());
086            dialog.getContentPane().add(batchName,BorderLayout.NORTH);
087    
088            Box boxMain = new Box(BoxLayout.Y_AXIS);
089            boxMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
090                    "Choose data source(s) to be overlapped & Processing configuration"));
091            dialog.getContentPane().add(boxMain,BorderLayout.CENTER);
092    
093    
094            Box boxLabels = new Box(BoxLayout.X_AXIS);
095            JButton buttonGetDir = new JButton("Select Directory ..");
096            buttonGetDir.addActionListener(new ActionListener(){
097                public void actionPerformed(ActionEvent e){
098                        fillFileList();
099                }
100            });
101            boxLabels.add(buttonGetDir);
102            boxLabels.add(Box.createHorizontalGlue());
103            boxLabels.add(new JLabel("Processing List                             "));
104    
105            Box boxLists = new Box(BoxLayout.X_AXIS);
106            fileListModel = new DefaultListModel();
107            fileList = new JList(fileListModel);
108    
109            Box boxAddRemove = new Box(BoxLayout.Y_AXIS);
110            JButton buttonAdd = new JButton("  >  ");
111            buttonAdd.addActionListener(new ActionListener(){
112                public void actionPerformed(ActionEvent e){
113                    addFiles();
114                }
115            });
116            JButton buttonRemove = new JButton("  <  ");
117            buttonRemove.addActionListener(new ActionListener(){
118                public void actionPerformed(ActionEvent e){
119                    removeFiles();
120                }
121            });
122            boxAddRemove.add(Box.createVerticalStrut(40));
123            boxAddRemove.add(buttonAdd);
124            boxAddRemove.add(Box.createVerticalStrut(20));
125            boxAddRemove.add(buttonRemove);
126    
127            procListModel = new DefaultListModel();
128            procList = new JList(procListModel);
129    
130            JScrollPane scrollPane1 = new JScrollPane(fileList);
131            JScrollPane scrollPane2 = new JScrollPane(procList);
132            boxLists.add(scrollPane1);
133            boxLists.add(boxAddRemove);
134            boxLists.add(scrollPane2);
135    
136            boxMain.add(boxLabels);
137            boxMain.add(Box.createVerticalStrut(5));
138            boxMain.add(boxLists);
139    
140            Box boxConfig = new Box(BoxLayout.X_AXIS);
141            boxConfig.add(new JLabel("Choose configure file:"));
142            txtConfName = new JTextField(12);
143            boxConfig.add(Box.createHorizontalStrut(20));
144            boxConfig.add(txtConfName,BorderLayout.CENTER);
145            JButton buttonConfig = new JButton("...");
146            buttonConfig.addActionListener(new ActionListener(){
147                public void actionPerformed(ActionEvent e){
148                    txtConfName.setText(chooseConfig());
149                }
150            });
151            boxConfig.add(buttonConfig,BorderLayout.EAST);
152    
153            Box boxOkCancel = new Box(BoxLayout.X_AXIS);
154            JButton buttonOK = new JButton("OK");
155            JButton buttonCancel = new JButton("Cancel");
156            JButton buttonColor = new JButton("Coloring");
157    
158            buttonOK.addActionListener(new ActionListener(){
159                public void actionPerformed(ActionEvent e){
160                    onOK();
161                }
162            });
163            buttonCancel.addActionListener(new ActionListener(){
164                public void actionPerformed(ActionEvent e){
165                    onCancel();
166                }
167            });
168            buttonColor.addActionListener(new ActionListener(){
169                public void actionPerformed(ActionEvent e){
170                    selectColor();
171                }
172            });
173    
174            boxOkCancel.add(Box.createHorizontalStrut(25));
175            boxOkCancel.add(buttonColor);
176            boxOkCancel.add(Box.createHorizontalStrut(20));
177            boxOkCancel.add(buttonOK);
178            boxOkCancel.add(Box.createHorizontalStrut(20));
179            boxOkCancel.add(buttonCancel);
180    
181            Box boxBottom = Box.createVerticalBox();
182            boxBottom.add(Box.createVerticalStrut(12));
183            boxBottom.add(boxConfig);
184            boxBottom.add(Box.createVerticalStrut(30));
185            boxBottom.add(boxOkCancel);
186    
187    
188            dialog.getContentPane().add(boxBottom,BorderLayout.SOUTH);
189            //dialog.setResizable(false);
190    
191        }
192    
193        private void selectColor() {
194            int index = procList.getSelectedIndex();
195    
196            if (index != -1) {
197                Color newColor = JColorChooser.showDialog(Scene.getFrame(), "Choose a color", Color.black);
198                if (newColor != null) {
199                    colorList.add(index,newColor);
200                    colorList.remove(index+1);
201                    procListModel.removeAllElements();
202    
203                    for (int i=0; i<setProcessFiles.size(); i++) {
204                        if (colorList.get(i) == null)
205                            procListModel.addElement(setProcessFiles.get(i));
206                        else
207                            procListModel.addElement("<html><font color=#" + getColorHex((Color)colorList.get(i)) + ">"
208                                                 + setProcessFiles.get(i) +" </font></html>" );
209                    }
210                }
211            }
212        }
213    
214        private void onOK() {
215    
216            if (procListModel.size() < 2) {
217               Scene.showErrorMessage("Please select at least 2 data source.");
218               return;
219            }
220    
221            if (txtConfName.getText().trim().length() == 0) {
222                Scene.showErrorMessage("No configuration file selected!");
223                return;
224            }
225            dialog.setVisible(false);
226            noEntityAvailable = false;
227    
228            overlappedVisualize();
229        }
230    
231        private void onCancel() {
232            dialog.setVisible(false);
233        }
234    
235        private void addFiles() {
236            int[] selectIndex = fileList.getSelectedIndices();
237            ArrayList newColorList = new ArrayList();
238    
239            for (int i=0;i<selectIndex.length;i++) {
240                if (setProcessFiles.contains(fileListModel.getElementAt(selectIndex[i]))) continue;
241    
242                setProcessFiles.add(fileListModel.getElementAt(selectIndex[i]));
243                procListModel.addElement(fileListModel.getElementAt(selectIndex[i]));
244            }
245    
246            for (int i=0; i<setProcessFiles.size();i++) {
247                if (i<colorList.size())
248                    newColorList.add(i,colorList.get(i));
249                else
250                    newColorList.add(i,null);
251            }
252            colorList = newColorList;
253        }
254    
255        private void removeFiles() {
256            int[] selectIndex = procList.getSelectedIndices();
257    
258            for (int i=selectIndex.length -1 ;i>=0;i--) {
259                setProcessFiles.remove(selectIndex[i]);
260                colorList.remove(selectIndex[i]);
261                procListModel.removeElement(procListModel.getElementAt(selectIndex[i]));
262            }
263        }
264    
265        private String chooseConfig() {
266            JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastConfigDir());
267    
268            if(fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
269                File f = fc.getSelectedFile();
270                Scene.getUIManager().setLastConfigDir(f.getPath());
271                return (f.getPath());
272            }
273            else return "";
274        }
275    
276        private void fillFileList() {
277            JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastDataDir());
278            String path;
279    
280            fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
281    
282            fileListModel.removeAllElements();
283            if(fc.showOpenDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
284                path = fc.getSelectedFile().getAbsolutePath();
285                Scene.getUIManager().setLastDataDir(path);
286                File dir = new File(path);
287                FileSystemView fv = fc.getFileSystemView();
288                File[] fl = fv.getFiles(dir,false);
289                for (int i=0;i<fl.length;i++) {
290                    String fn = fl[i].getName();
291                    if (!fl[i].isFile() || !fn.endsWith(".dat") || setFile.contains(path+File.separator+fn))
292                        continue;
293                    setFile.add(path+File.separator+fn);
294                    fileListModel.addElement(path+File.separator+fn);
295                }
296            }
297    
298        }
299    
300        public boolean isOverlapable(Visualization visualToBeOverlapped) {
301            return true;
302        }
303    
304        public void preOverlappedVisualize() throws EVolveException{
305            String dataSource;
306            SerializedVisualization vizInfo = null;
307            Visualization visual;
308    
309            reset();
310            for (int i=0; i<procListModel.size(); i++) {
311                dataSource = (String)setProcessFiles.get(i);
312                Scene.setDataFilename(dataSource);
313                Scene.autoLoadDataSource();
314    
315                if (i == 0) {
316                    SerializedData data = VisualizationSerializer.v().getVizInfoFromDisk(txtConfName.getText().trim());
317                    vizInfo = (SerializedVisualization)data.SerializedVisualizations.get(0);
318                }
319    
320                visual = Scene.getVisualizationManager().newVisualization(vizInfo.FactoryName);
321    
322                visual.setName(vizInfo.VisualizationName);
323                visual.restoreConfiguration(vizInfo);
324                visualizationList.add(visual);
325    
326                Scene.getVisualizationManager().addAllVisualizations();
327                Scene.getVisualizationManager().prepareListToBeVisualized();
328                Scene.autoVisualize();
329    
330                for (int k=0; k< entityList.length; k++)
331                    if (visual.getDimension()[k] instanceof ReferenceDimension) {
332                        entityList[k].add(Scene.getDataManager().getEntity()[visual.getDimension()[k].getDataFilter().getTargetType()]);
333                        referenceDimList[k].add(visual.getDimension()[k]);
334                    }
335            }
336    
337        }
338    
339        public void overlappedVisualize() {
340            Visualization visual;
341    
342            Scene.getVisualizationManager().init();
343            Scene.getUIManager().init();
344    
345            if (window instanceof EVolve.Window) {
346                Scene.getUIManager().removeWindow(window);
347                window = null;
348            }
349            visualizationList.clear();
350            Scene.getUIManager().setDoNotRemoveWindow(true);
351            try {
352                preOverlappedVisualize();
353            } catch (EVolveException e) {
354                Scene.showErrorMessage(e.getMessage());
355                Scene.getUIManager().setDoNotRemoveWindow(false);
356                Scene.setDataFilename(null);
357                return;
358            }
359            Scene.getUIManager().setDoNotRemoveWindow(false);
360            Scene.setDataFilename(null);
361    
362    
363            unifyVisualizations();
364    
365            // begin drawing overlap
366            if (window instanceof EVolve.Window) {
367                Scene.getUIManager().removeWindow(window);
368                window = null;
369            }
370    
371            newOverlappedVisualization(this);
372    
373            int [] selectedIndex = new int[2];
374            int [] sortedDimension = new int[2];
375            visual = (Visualization)visualizationList.get(0);
376    
377            for (int i=0; i<fullEntitySet.length; i++) {
378                if (visual.getDimension()[i] instanceof ReferenceDimension) {
379    
380                    selectedIndex[i] = ((ReferenceDimension)visual.getDimension()[i]).getSelectedComparatorIndex();
381                    sortedDimension[i] = 1;
382                    break;
383                }
384            }
385    
386            sort();
387            enableSortMenu();
388        }
389    
390        private void unifyVisualizations() {
391            // now we begin unify all entities
392            HashMap standard[] = new HashMap[2];
393            standard[0] = new HashMap();
394            standard[1] = new HashMap();
395    
396            for (int i=0; i<entityList.length; i++) {
397                for (int j=0; j<entityList[i].size(); j++) {
398                    Unification.unifyEntities(standard[i],(HashMap)entityList[i].get(j));
399                }
400            }
401    
402            // dump the unified entities into a hashset
403            for (int i=0; i<standard.length; i++) {
404                Iterator it = standard[i].keySet().iterator();
405                fullEntitySet[i] = new HashSet();
406                while (it.hasNext()) {
407                    fullEntitySet[i].add(standard[i].get(it.next()));
408                }
409            }
410            // unifying entities done here
411    
412            Visualization visual;
413            for (int i=0; i<entityList.length; i++) {
414                if (entityList[i].size() == 0) continue; // not a reference dimension
415                for (int j=0; j<visualizationList.size(); j++) {
416                    visual = (Visualization)visualizationList.get(j);
417    
418                    ReferenceDimension dim = visual.getLinkableDimension(i);
419                    Color newColor = (Color)colorList.get(j);
420                    Unification.changeColor(visual.getImage(),newColor);
421    
422                    dim.linkEntities(fullEntitySet[i]);
423                    try {
424                        dim.visualize();
425                    } catch (NoDataPlotException e) {
426                        Scene.showErrorMessage(e.getMessage());
427                    }
428                    ((XYVisualization)visual).disablePopupMenu();
429                }
430            }
431        }
432    
433        private void reset() {
434            fullEntitySet = new HashSet[2];
435            fullEntitySet[0] = null;
436            fullEntitySet[1] = null;
437            for (int i= 0; i<entityList.length ; i++) {
438                entityList[i].clear();
439            }
440        }
441    }