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;
025    
026    import EVolve.data.*;
027    import java.awt.*;
028    import java.awt.event.*;
029    import java.util.*;
030    import java.io.*;
031    import javax.swing.*;
032    
033    public class Filter {
034        private ArrayList selection;
035        private ArrayList field;
036    
037        private final JDialog dialog;
038        private JSplitPane splitMain, splitLeft;
039        private JList listSelection, listField, listEntity;
040        private DefaultListModel modelSelection, modelField, modelEntity;
041    
042        public Filter() {
043            selection = new ArrayList();
044            field = new ArrayList();
045    
046            dialog = new JDialog(Scene.getFrame(), "Filter", false);
047    
048            final CardLayout cardButton = new CardLayout();
049            final JPanel panelButton = new JPanel(cardButton);
050            dialog.getContentPane().add(panelButton, BorderLayout.SOUTH);
051    
052            // selection
053            modelSelection = new DefaultListModel();
054            listSelection = new JList(modelSelection);
055            listSelection.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
056            listSelection.addMouseListener(new MouseAdapter() {
057                public void mousePressed(MouseEvent e) {
058                    updateSelection();
059                    cardButton.show(panelButton, "Selection");
060                }
061            });
062    
063            JScrollPane scrollSelection = new JScrollPane(listSelection, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
064            scrollSelection.setBackground(Color.white);
065            scrollSelection.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Selections"));
066    
067            JPanel panelSelection = new JPanel(new FlowLayout());
068            panelButton.add(panelSelection, "Selection");
069    
070            JButton buttonDeselect = new JButton("Deselect");
071            buttonDeselect.addActionListener(new ActionListener() {
072                public void actionPerformed(ActionEvent e) {
073                    listSelection.clearSelection();
074                }
075            });
076            panelSelection.add(buttonDeselect);
077    
078            JButton buttonColor = new JButton("Coloring");
079            buttonColor.addActionListener(new ActionListener() {
080                public void actionPerformed(ActionEvent e) {
081                    color();
082                }
083            });
084            panelSelection.add(buttonColor);
085    
086            JButton buttonFilter = new JButton("Decoloring");
087            buttonFilter.addActionListener(new ActionListener() {
088                public void actionPerformed(ActionEvent e) {
089                    filter();
090                }
091            });
092            panelSelection.add(buttonFilter);
093    
094            JButton buttonRemove = new JButton("Remove");
095            buttonRemove.addActionListener(new ActionListener() {
096                public void actionPerformed(ActionEvent e) {
097                    remove();
098                }
099            });
100            panelSelection.add(buttonRemove);
101    
102            JButton buttonSelectionClose = new JButton("Close");
103            buttonSelectionClose.addActionListener(new ActionListener() {
104                public void actionPerformed(ActionEvent e) {
105                    dialog.setVisible(false);
106                }
107            });
108            panelSelection.add(buttonSelectionClose);
109    
110            // field
111            modelField = new DefaultListModel();
112            listField = new JList(modelField);
113            listField.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
114            listField.addMouseListener(new MouseAdapter() {
115                public void mousePressed(MouseEvent e) {
116                    updateField();
117                    cardButton.show(panelButton, "Field");
118                }
119            });
120    
121            JScrollPane scrollField = new JScrollPane(listField, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
122            scrollField.setBackground(Color.white);
123            scrollField.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Fields"));
124    
125            JPanel panelField = new JPanel(new FlowLayout());
126            panelButton.add(panelField, "Field");
127    
128            JButton buttonSelectAll = new JButton("Select All");
129            buttonSelectAll.addActionListener(new ActionListener() {
130                public void actionPerformed(ActionEvent e) {
131                    selectAll();
132                }
133            });
134            panelField.add(buttonSelectAll);
135    
136            JButton buttonClearAll = new JButton("Clear All");
137            buttonClearAll.addActionListener(new ActionListener() {
138                public void actionPerformed(ActionEvent e) {
139                    clearAll();
140                }
141            });
142            panelField.add(buttonClearAll);
143    
144            JButton buttonFieldClose = new JButton("Close");
145            buttonFieldClose.addActionListener(new ActionListener() {
146                public void actionPerformed(ActionEvent e) {
147                    dialog.setVisible(false);
148                }
149            });
150            panelField.add(buttonFieldClose);
151    
152            splitLeft = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollSelection, scrollField);
153            splitLeft.setDividerSize(2);
154    
155            // entity
156            modelEntity = new DefaultListModel();
157            listEntity = new JList(modelEntity);
158            listEntity.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
159            listEntity.addMouseListener(new MouseAdapter() {
160                public void mousePressed(MouseEvent e) {
161                    cardButton.show(panelButton, "Entity");
162                }
163            });
164    
165            JScrollPane scrollEntity = new JScrollPane(listEntity, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
166            scrollEntity.setBackground(Color.white);
167            scrollEntity.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(), "Entities"));
168    
169            JPanel panelEntity = new JPanel(new FlowLayout());
170            panelButton.add(panelEntity, "Entity");
171    
172            JButton buttonRemoveSelected = new JButton("Remove Selected");
173            buttonRemoveSelected.addActionListener(new ActionListener() {
174                public void actionPerformed(ActionEvent e) {
175                    removeSelected();
176                }
177            });
178            panelEntity.add(buttonRemoveSelected);
179    
180            JButton buttonRemoveUnselected = new JButton("Remove Unselected");
181            buttonRemoveUnselected.addActionListener(new ActionListener() {
182                public void actionPerformed(ActionEvent e) {
183                    removeUnselected();
184                }
185            });
186            panelEntity.add(buttonRemoveUnselected);
187    
188            JButton buttonEntityClose = new JButton("Close");
189            buttonEntityClose.addActionListener(new ActionListener() {
190                public void actionPerformed(ActionEvent e) {
191                    dialog.setVisible(false);
192                }
193            });
194            panelEntity.add(buttonEntityClose);
195    
196            splitMain = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitLeft, scrollEntity);
197            splitMain.setDividerSize(2);
198            dialog.getContentPane().add(splitMain, BorderLayout.CENTER);
199        }
200    
201        public void load() {
202            Scene.getUIManager().showDialog(dialog, Toolkit.getDefaultToolkit().getScreenSize().width / 2, Toolkit.getDefaultToolkit().getScreenSize().height * 3 / 4);
203            splitMain.setDividerLocation(0.5);
204            splitLeft.setDividerLocation(0.5);
205        }
206    
207        public void addSelection(Selection selection) {
208            String newName = (String)JOptionPane.showInputDialog(Scene.getFrame(),
209                    "Selection Options:\n"+Scene.getUIManager().getSelectionOptions() + "\nName of the selection:",
210                    "Add Selection",
211                    JOptionPane.QUESTION_MESSAGE, null, null, selection.getName());
212            if (newName != null) {
213                selection.setName(newName);
214    
215                this.selection.add(selection);
216                update();
217    
218                listSelection.setSelectedIndex(this.selection.size() - 1);
219                updateSelection();
220    
221                if (!dialog.isVisible()) {
222                    load();
223                }
224            }
225        }
226    
227        public void update() {
228            modelSelection.removeAllElements();
229            for (int i = 0; i < selection.size(); i++) {
230                Selection s = (Selection)(selection.get(i));
231                if (s.getColor() == null) {
232                    modelSelection.addElement("* " + s.getName() + " (" + Scene.getDataManager().getElementDefinition()[((Selection)(selection.get(i))).getEntityType()].getName() + ")");
233                } else {
234                    modelSelection.addElement("<html><font color=#" + getColorHex(s.getColor()) + ">" + s.getName() + " (" + Scene.getDataManager().getElementDefinition()[((Selection)(selection.get(i))).getEntityType()].getName() + ")</font></html>");
235                }
236            }
237        }
238    
239        private String getColorHex(Color color) {
240            String returnVal = Integer.toHexString(color.getBlue());
241            if (returnVal.length() < 2) {
242                returnVal = "0" + returnVal;
243            }
244            returnVal = Integer.toHexString(color.getGreen()) + returnVal;
245            if (returnVal.length() < 4) {
246                returnVal = "0" + returnVal;
247            }
248            returnVal = Integer.toHexString(color.getRed()) + returnVal;
249            if (returnVal.length() < 6) {
250                returnVal = "0" + returnVal;
251            }
252    
253            return returnVal;
254        }
255    
256        private void updateSelection() {
257            if (listSelection.getSelectedIndex() != -1) {
258                modelField.removeAllElements();
259                modelEntity.removeAllElements();
260    
261                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
262    
263                for (int i = 0; i < s.getSelected().length; i++) {
264                    modelEntity.addElement(s.getSelected()[i].getName());
265                }
266    
267                ArrayList vizType = Scene.getVisualizationManager().getVisualizationType();
268                field.clear();
269                ReferenceLink[] link = Scene.getDataManager().getReferenceLink();
270    
271                for (int i = 0; i < link.length; i++) {
272                    if ((vizType.indexOf("" + link[i].getSourceType() + "") != -1) && (link[i].getTargetType() == s.getEntityType())) {
273                        field.add(link[i]);
274                    }
275                }
276    
277                for (int i = 0; i < field.size(); i++) {
278                    modelField.addElement(((ReferenceLink)(field.get(i))).getName() + " (" + Scene.getDataManager().getElementDefinition()[((ReferenceLink)(field.get(i))).getSourceType()].getName() + ")");
279                }
280    
281                ArrayList selected = new ArrayList();
282                for (int i = 0; i < s.getLink().length; i++) {
283                    if (field.indexOf(s.getLink()[i]) != -1) {
284                        selected.add(new Integer(field.indexOf(s.getLink()[i])));
285                    }
286                }
287    
288                int[] selectedLink = new int[selected.size()];
289                for (int i = 0; i < selectedLink.length; i++) {
290                    selectedLink[i] = ((Integer)(selected.get(i))).intValue();
291                }
292                listField.setSelectedIndices(selectedLink);
293            }
294        }
295    
296        private void updateField() {
297            if (listSelection.getSelectedIndex() != -1) {
298                ReferenceLink[] newLink = new ReferenceLink[listField.getSelectedIndices().length];
299                for (int i = 0; i < newLink.length; i++) {
300                    newLink[i] = (ReferenceLink)(field.get(listField.getSelectedIndices()[i]));
301                }
302    
303                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
304                s.setLink(newLink);
305            }
306        }
307    
308        private void updateEntity() {
309            if (listSelection.getSelectedIndex() != -1) {
310                modelEntity.removeAllElements();
311    
312                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
313                for (int i = 0; i < s.getSelected().length; i++) {
314                    modelEntity.addElement(s.getSelected()[i].getName());
315                }
316            }
317        }
318    
319        private void color() {
320            if (listSelection.getSelectedIndex() != -1) {
321                Color newColor = JColorChooser.showDialog(Scene.getFrame(), "Choose a color", Color.black);
322                if (newColor != null) {
323                    int selected = listSelection.getSelectedIndex();
324                    ((Selection)(selection.get(selected))).setColor(newColor);
325                    update();
326    
327                    listSelection.setSelectedIndex(selected);
328                    updateSelection();
329                }
330            }
331        }
332    
333        private void filter() {
334            if (listSelection.getSelectedIndex() != -1) {
335                int selected = listSelection.getSelectedIndex();
336                ((Selection)(selection.get(selected))).setColor(null);
337                update();
338    
339                listSelection.setSelectedIndex(selected);
340                updateSelection();
341            }
342        }
343    
344        private void remove() {
345            if (listSelection.getSelectedIndex() != -1) {
346                selection.remove(listSelection.getSelectedIndex());
347                update();
348            }
349        }
350    
351        private void selectAll() {
352            if (listSelection.getSelectedIndex() != -1) {
353                int[] all = new int[modelField.size()];
354                for (int i = 0; i < all.length; i++) {
355                    all[i] = i;
356                }
357                listField.setSelectedIndices(all);
358                updateField();
359            }
360        }
361    
362        private void clearAll() {
363            if (listSelection.getSelectedIndex() != -1) {
364                listField.setSelectedIndices(new int[0]);
365                updateField();
366            }
367        }
368    
369        private void removeSelected() {
370            if (listSelection.getSelectedIndex() != -1) {
371                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
372                int[] index = listEntity.getSelectedIndices();
373                Entity[] newEntity = new Entity[s.getSelected().length - index.length];
374    
375                int j = 0;
376                int k = 0;
377                for (int i = 0; i < newEntity.length; i++) {
378                    while ((j < index.length) && (index[j] == k)) {
379                        j++;
380                        k++;
381                    }
382                    newEntity[i] = s.getSelected()[k];
383                    k++;
384                }
385                s.setSelected(newEntity);
386                updateEntity();
387            }
388        }
389    
390        private void removeUnselected() {
391            if (listSelection.getSelectedIndex() != -1) {
392                Selection s = (Selection)(selection.get(listSelection.getSelectedIndex()));
393                int[] index = listEntity.getSelectedIndices();
394                Entity[] newEntity = new Entity[index.length];
395    
396                for (int i = 0; i < newEntity.length; i++) {
397                    newEntity[i] = s.getSelected()[index[i]];
398                }
399                s.setSelected(newEntity);
400                updateEntity();
401            }
402        }
403    
404        public Selection[] getSelection() {
405            Selection[] returnVal = new Selection[selection.size()];
406            for (int i = 0; i < returnVal.length; i++) {
407                returnVal[i] = (Selection)(selection.get(i));
408            }
409    
410            return returnVal;
411        }
412    
413        public Selection getActiveSelection() {
414            int selectedIndex = listSelection.getSelectedIndex();
415    
416            if (selectedIndex == -1) return null;
417    
418            return (Selection)selection.get(selectedIndex);
419        }
420    
421        public void saveSelection() {
422            JFileChooser fc = new JFileChooser();
423            if (fc.showSaveDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
424                try {
425                    FileWriter file = new FileWriter(fc.getSelectedFile().getPath(),false);
426                    writeSelection(file,"Default");
427                } catch (IOException e) {}
428            }
429        }
430    
431        public void saveSelection(FileWriter file, String selectionName) {
432            try {
433                writeSelection(file,selectionName);
434            } catch (IOException e) {}
435        }
436    
437        public void selectAllFields() {
438            for (int i=0; i<modelSelection.getSize(); i++) {
439                listSelection.setSelectedIndex(i);
440                updateSelection();
441                int[] selIds= new int[modelField.getSize()];
442                for (int j=0; j<modelField.getSize(); j++) {
443                    selIds[j] = j;
444                }
445                listField.setSelectedIndices(selIds);
446                updateField();
447            }
448        }
449    
450        public void loadSelection(RandomAccessFile file) throws Exception{
451            Selection newSelection = null;
452            int start, end, entityType, selected[];
453            ArrayList IDs;
454            String currentName, line;
455            StringTokenizer token;
456            Color color;
457    
458            this.selection.clear();
459    
460            String version = file.readLine().trim();
461            if (!version.equals(Scene.VERSION)) throw (new Exception());
462    
463            file.readLine(); //skip one line
464            try {
465                line = file.readLine().trim();
466                while (line!=null) {
467                    currentName = line.trim(); //get selection name
468                    line = file.readLine().trim(); //get start position of x
469                    start = Integer.parseInt(line.substring(line.indexOf(':')+1));
470                    line = file.readLine().trim(); //get end position of x
471                    end = Integer.parseInt(line.substring(line.indexOf(':')+1));
472                    line = file.readLine().trim(); //get entity type
473                    entityType = Integer.parseInt(line.substring(line.indexOf(':')+1));
474                    line = file.readLine().trim(); //get color
475                    line = line.substring(line.indexOf(':')+1);
476                    color = null;
477                    if (line.charAt(0)!='n')
478                        color = new Color(Integer.parseInt(line));
479    
480                    file.readLine(); //skip tag
481                    line = file.readLine().trim(); // read entity ids
482                    token = new StringTokenizer(line,",");
483    
484                    IDs = new ArrayList();
485                    while (token.hasMoreTokens()) {
486                        IDs.add(token.nextToken());
487                    }
488                    selected = new int[IDs.size()];
489                    for (int k=0; k<selected.length; k++)
490                        selected[k] = Integer.parseInt((String)IDs.get(k));
491    
492                    newSelection = new Selection(entityType,selected,start,end);
493                    newSelection.setName(currentName);
494                    newSelection.setColor(color);
495                    line = file.readLine();
496                    this.selection.add(newSelection);
497                    update();
498    
499                    listSelection.setSelectedIndex(this.selection.size() - 1);
500                    updateSelection();
501                }
502    
503                file.close();
504            } catch (IOException e) {
505                Scene.showErrorMessage("Error occurred when trying to save selections!");
506            }
507    
508        }
509    
510        private void writeSelection(FileWriter file, String selectionName) throws IOException {
511            Selection currentSelection;
512            String currentSelectionName;
513            int start, end, entityType;
514            Entity[] entities;
515    
516            file.write(Scene.VERSION+"\n");
517            file.write(selectionName+"\n");
518            for (int i=0; i<selection.size(); i++) {
519                currentSelection = (Selection)selection.get(i);
520                start = currentSelection.getStart();
521                end = currentSelection.getEnd();
522                entityType = currentSelection.getEntityType();
523                currentSelectionName = currentSelection.getName();
524                entities = currentSelection.getSelected();
525    
526                file.write(currentSelectionName+"\n");
527                file.write("Start:"+start+"\n");
528                file.write("End:"+end+"\n");
529                file.write("Entity type:"+entityType+"\n");
530                if (currentSelection.getColor() != null)
531                    file.write("Color:"+currentSelection.getColor().getRGB()+"\n");
532                else
533                    file.write("Color:null"+"\n");
534                file.write("Selected ID list:\n");
535                for (int j=0; j<entities.length; j++) {
536                    file.write(entities[j].getId()+",");
537                }
538                file.write("\n");
539            }
540            file.flush();
541            file.close();
542    
543        }
544    }