001    /*
002     * Created by IntelliJ IDEA.
003     * User: Wei Wang
004     * Date: 2002-9-6
005     * Time: 15:53:23
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.GridLayout;
014    import java.awt.Rectangle;
015    import java.awt.event.ActionEvent;
016    import java.awt.event.ActionListener;
017    import java.awt.event.KeyEvent;
018    import java.awt.event.KeyListener;
019    import java.util.ArrayList;
020    import java.util.HashSet;
021    
022    import javax.swing.BorderFactory;
023    import javax.swing.Box;
024    import javax.swing.BoxLayout;
025    import javax.swing.DefaultListModel;
026    import javax.swing.JButton;
027    import javax.swing.JColorChooser;
028    import javax.swing.JDialog;
029    import javax.swing.JLabel;
030    import javax.swing.JList;
031    import javax.swing.JPanel;
032    import javax.swing.JScrollPane;
033    import javax.swing.event.ListSelectionEvent;
034    import javax.swing.event.ListSelectionListener;
035    
036    import EVolve.Scene;
037    import EVolve.exceptions.NoDataPlotException;
038    import EVolve.util.unifyutils.Unification;
039    import EVolve.visualization.AutoImage;
040    import EVolve.visualization.Dimension;
041    import EVolve.visualization.ReferenceDimension;
042    import EVolve.visualization.Visualization;
043    
044    public class SynchronousOverlapper extends OverlapVisualization{
045        private final String name = "SynchronousOverlapper";
046        private Visualization overlappedVisualization;
047        private JList availableList,overlappableList;
048        private DefaultListModel modelList;
049        private ArrayList candidates;
050        private boolean shift_ctrl_pressed;
051    
052        public SynchronousOverlapper() {
053            super();
054            colorList = new ArrayList();
055            dialog = null;
056            overlappedVisualization = null;
057            candidates = new ArrayList();
058            modelList = new DefaultListModel();
059            xMax = 0;
060        }
061    
062        public String getName() {
063            return name;
064        }
065    
066        public void createDialog() {
067            shift_ctrl_pressed = false;
068            colorList.clear();
069            visualizationList.clear();
070            modelList.removeAllElements();
071            dialog = new JDialog(Scene.getFrame(), "Overlap Visualizations...", true);
072            dialog.setBounds(new Rectangle(500,400));
073    
074            Box boxMain = new Box(BoxLayout.Y_AXIS);
075            boxMain.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(),
076                    "Choose Visualizations to be overlapped"));
077            dialog.getContentPane().add(boxMain,BorderLayout.CENTER);
078    
079            Box boxLabels = new Box(BoxLayout.X_AXIS);
080            boxLabels.add(new JLabel("Available visualizations:"));
081            boxLabels.add(Box.createHorizontalStrut(130));
082            boxLabels.add(new JLabel("Overlappable visualizations:"));
083    
084            JPanel boxLists = new JPanel(new GridLayout(1,2,25,2));
085            DefaultListModel modelAvail = new DefaultListModel();
086            availableList = new JList(modelAvail);
087            ArrayList arr = Scene.getVisualizationManager().getVisualizationList();
088            for (int i=0; i<arr.size(); i++) {
089                modelAvail.addElement((((Visualization)arr.get(i)).getWindow().getTitle()));
090            }
091            availableList.addListSelectionListener(new ListSelectionListener() {
092                public void valueChanged(ListSelectionEvent e){
093                    updateOverlappableList();
094                }
095            });
096    
097            overlappableList = new JList(modelList);
098            overlappableList.addKeyListener(new KeyListener(){
099                public void keyPressed(KeyEvent e) {
100                    if ((e.getKeyCode() == KeyEvent.VK_SHIFT) || (e.getKeyCode()==KeyEvent.VK_CONTROL)) {
101                        shift_ctrl_pressed = true;
102                    }
103                }
104                public void keyReleased(KeyEvent e) {
105                    if ((e.getKeyCode() == KeyEvent.VK_SHIFT) || (e.getKeyCode()==KeyEvent.VK_CONTROL)) {
106                        shift_ctrl_pressed = false;
107                    }
108                }
109                public void keyTyped(KeyEvent e) { }
110            });
111            overlappableList.addListSelectionListener(new ListSelectionListener() {
112                public void valueChanged(ListSelectionEvent e){
113                    if ((!shift_ctrl_pressed)&&(!e.getValueIsAdjusting()) && overlappableList.isFocusOwner())
114                        selectColor();
115                }
116            });
117            JScrollPane scrollPane1 = new JScrollPane(availableList);
118            JScrollPane scrollPane2 = new JScrollPane(overlappableList);
119            boxLists.add(scrollPane1);
120            boxLists.add(scrollPane2);
121    
122            boxMain.add(Box.createVerticalStrut(-65));
123            boxMain.add(boxLabels);
124            boxMain.add(Box.createVerticalStrut(-65));
125            boxMain.add(boxLists);
126            boxMain.add(Box.createVerticalStrut(10));
127    
128            Box boxOkCancel = new Box(BoxLayout.X_AXIS);
129            JButton buttonOK = new JButton("OK");
130            JButton buttonCancel = new JButton("Cancel");
131    
132            buttonOK.addActionListener(new ActionListener(){
133                public void actionPerformed(ActionEvent e){
134                    onOK();
135                }
136            });
137            buttonCancel.addActionListener(new ActionListener(){
138                public void actionPerformed(ActionEvent e){
139                    onCancel();
140                }
141            });
142    
143            boxOkCancel.add(Box.createHorizontalStrut(180));
144            boxOkCancel.add(buttonOK);
145            boxOkCancel.add(Box.createHorizontalStrut(20));
146            boxOkCancel.add(buttonCancel);
147    
148            dialog.getContentPane().add(boxOkCancel,BorderLayout.SOUTH);
149            //dialog.setResizable(false);
150        }
151    
152        private void selectColor() {
153            int index = overlappableList.getSelectedIndex();
154    
155            if (index != -1) {
156                Color newColor = JColorChooser.showDialog(Scene.getFrame(), "Choose a color", Color.black);
157                if (newColor != null) {
158                    colorList.add(index+1,newColor);
159                    colorList.remove(index+2);
160                    modelList.removeAllElements();
161                    for (int i=0; i<candidates.size(); i++) {
162                        if (colorList.get(i+1) == null)
163                            modelList.addElement(((Visualization)candidates.get(i)).getWindow().getTitle());
164                        else
165                            modelList.addElement("<html><font color=#" + getColorHex((Color)colorList.get(i+1)) + ">"
166                                                 +((Visualization)candidates.get(i)).getWindow().getTitle() +" </font></html>" );
167                    }
168                    overlappableList.setSelectedIndex(index);
169                } else {
170                    newColor = Color.black;
171                }
172            }
173        }
174    
175        private void updateOverlappableList() {
176            ArrayList arr = Scene.getVisualizationManager().getVisualizationList();
177            overlappedVisualization = (Visualization)arr.get(availableList.getSelectedIndex());
178    
179            candidates.clear();
180            colorList.clear();
181            overlappableList.removeAll();
182            modelList.removeAllElements();
183            colorList.add(null);
184            for (int i=0; i<arr.size(); i++) {
185                Visualization visual =(Visualization)arr.get(i);
186                if (visual.getVisualizationID() == overlappedVisualization.getVisualizationID()) continue;
187                if (isOverlapable(visual)) {
188                    modelList.addElement(visual.getWindow().getTitle());
189                    colorList.add(null);
190                    candidates.add(visual);
191                }
192            }
193        }
194    
195        private void onOK() {
196            int[] indexes = overlappableList.getSelectedIndices();
197            visualizationList.clear();
198    
199            if (indexes.length == 0) {
200                Scene.showErrorMessage("Please select visualizations to be linked");
201                return;
202            }
203    
204            visualizationList.add(overlappedVisualization);
205            for (int i=0; i<indexes.length; i++) {
206                visualizationList.add(candidates.get(indexes[i]));
207            }
208    
209            ArrayList newColorList = new ArrayList();
210            newColorList.add(null);
211            for (int i=0; i<modelList.size(); i++) {
212                for (int j=0; j<indexes.length;j++) {
213                    if (i==indexes[j]) {
214                        newColorList.add(colorList.get(i+1));
215                        break;
216                    }
217                }
218            }
219            colorList = newColorList;
220            dialog.setVisible(false);
221            noEntityAvailable = false;
222    
223            // visualize viz if the user has not visualize them yet
224            ArrayList tobeViz = new ArrayList();
225    
226            for (int i=0; i<visualizationList.size(); i++) {
227                Visualization visual = (Visualization)visualizationList.get(i);
228                AutoImage image = visual.getImage();
229                if (image == null) {
230                    Scene.showErrorMessage("Please visualize all visualizations you want to overlap first.");
231                    return;
232                    //tobeViz.add(visual);
233                }
234            }
235    
236    
237            /*if (tobeViz.size() != 0) {
238                int dataSourceId = Scene.getDataSourceManager().getCurrentDataSourceId();
239                for (int i=0; i<tobeViz.size(); i++) {
240                    Visualization visual = (Visualization)visualizationList.get(i);
241                    if (visual.getDataSourceId() != dataSourceId) {
242                        Scene.showErrorMessage("Visualizations belong to different data sources, please\n" +
243                                               "try to first visualize them and then overlap them again.");
244                        return;
245                    }
246                }
247                Scene.getVisualizationManager().prepareForLinkedViz(tobeViz,0);
248                Scene.visualize();
249            }*/
250    
251            overlappedVisualize();
252        }
253    
254        private void onCancel() {
255            dialog.setVisible(false);
256        }
257    
258        public boolean isOverlapable(Visualization visualToBeOverlapped) {
259            if (overlappedVisualization.getInterval() != visualToBeOverlapped.getInterval())
260                return false;
261    
262            for (int i=0; i<2; i++) {
263                if ((overlappedVisualization.getLinkableDimension(i) == null)||
264                   (visualToBeOverlapped.getLinkableDimension(i) == null))
265                {
266                    if ((overlappedVisualization.getDimension()[i] instanceof ReferenceDimension) ||
267                        visualToBeOverlapped.getDimension()[i] instanceof ReferenceDimension)
268                        return false;
269    
270                    if (!overlappedVisualization.getDimension()[i].getName().equals(visualToBeOverlapped.getDimension()[i].getName()))
271                        return false;
272    
273                } else {
274                    if (overlappedVisualization.getDimension()[i].getDataFilter().getTargetType() !=
275                        visualToBeOverlapped.getDimension()[i].getDataFilter().getTargetType())
276                        return false;
277                }
278            }
279    
280            if ((visualToBeOverlapped.getSubjectDefinition().getName().equals(overlappedVisualization.getSubjectDefinition().getName())) &&
281                (visualToBeOverlapped.getFactory().getName().equals(overlappedVisualization.getFactory().getName())) &&
282                (visualToBeOverlapped.getDataSourceId() == overlappedVisualization.getDataSourceId()))
283                return false;
284    
285            return true;
286        }
287    
288        public void overlappedVisualize() {
289            fullEntitySet = new HashSet[2];
290            fullEntitySet[0] = new HashSet();
291            fullEntitySet[1] = new HashSet();
292    
293            xMax = 0;
294    
295            if (((Visualization)visualizationList.get(0)).getDimension()[0] instanceof ReferenceDimension)
296                Unification.getUnifiedEntity(fullEntitySet[0],visualizationList,0);
297            if (((Visualization)visualizationList.get(0)).getDimension()[1] instanceof ReferenceDimension)
298                Unification.getUnifiedEntity(fullEntitySet[1],visualizationList,1);
299    
300    
301            if (window instanceof EVolve.Window) {
302                Scene.getUIManager().removeWindow(window);
303                window = null;
304            }
305    
306            unifyVisualizations();
307    
308            newOverlappedVisualization(this);
309    
310            sort();
311            enableSortMenu();
312        }
313    
314        private void unifyVisualizations() {
315    
316            for (int i=0; i<visualizationList.size(); i++) {
317                Visualization visual = (Visualization)visualizationList.get(i);
318    
319                Color newColor = (Color)colorList.get(i);
320                Unification.changeColor(visual.getImage(),newColor);
321    
322                for (int j=0; j<fullEntitySet.length; j++) {
323                    Dimension dim = visual.getDimension()[j];
324                    if (fullEntitySet[j].size() > 0) {
325                        ((ReferenceDimension)dim).linkEntities(fullEntitySet[j]);
326                        try {
327                            ((ReferenceDimension)dim).visualize();
328                        } catch (NoDataPlotException e) {
329                            Scene.showErrorMessage(e.getMessage());
330                        }
331                    }
332                }
333            }
334        }
335    }