source: src/main/java/weka/gui/ensembleLibraryEditor/DefaultModelsPanel.java @ 24

Last change on this file since 24 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 19.2 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/*
18 *    DefaultModelsPanel.java
19 *    Copyright (C) 2006 Robert Jung
20 *
21 */
22
23package weka.gui.ensembleLibraryEditor;
24
25import weka.classifiers.Classifier;
26import weka.classifiers.AbstractClassifier;
27import weka.classifiers.EnsembleLibraryModel;
28import weka.classifiers.meta.ensembleSelection.EnsembleSelectionLibrary;
29import weka.core.Utils;
30
31import java.awt.BorderLayout;
32import java.awt.Dimension;
33import java.awt.GridBagConstraints;
34import java.awt.GridBagLayout;
35import java.awt.event.ActionEvent;
36import java.awt.event.ActionListener;
37import java.io.File;
38import java.io.InputStream;
39import java.util.Iterator;
40import java.util.Properties;
41import java.util.Vector;
42import java.util.regex.Pattern;
43
44import javax.swing.AbstractAction;
45import javax.swing.BorderFactory;
46import javax.swing.JButton;
47import javax.swing.JComboBox;
48import javax.swing.JLabel;
49import javax.swing.JList;
50import javax.swing.JOptionPane;
51import javax.swing.JPanel;
52import javax.swing.JScrollPane;
53import javax.swing.JTabbedPane;
54import javax.swing.KeyStroke;
55import javax.swing.ListSelectionModel;
56import javax.swing.ToolTipManager;
57import javax.swing.event.ChangeEvent;
58import javax.swing.event.ChangeListener;
59
60/**
61 * This class is intended to build a panel that contains as interface
62 * that will let users choose default lists of models to add to the
63 * library. There will be default a list of models provided by the
64 * EnsembleLibrary class.  In addition, the user will be able to prune
65 * the list of defaults to remove models that have either high training
66 * times, high testing times, or high file sizes on disk.  Finally, users
67 * will be able to also prune the size of the current working default set
68 * to a specific number of models with a slider bar.
69 *
70 * @author  Robert Jung (mrbobjung@gmail.com)
71 * @version $Revision: 5928 $
72 */
73public class DefaultModelsPanel 
74  extends JPanel
75  implements ActionListener, ChangeListener {
76 
77  /** for serialization */
78  private static final long serialVersionUID = -6123488873592563339L;
79
80  /** the name of the property file */
81  public static final String PROPERTY_FILE = "DefaultModels.props";
82 
83  /** Contains the editor properties */
84  protected static Properties DEFAULT_PROPERTIES;
85 
86  /** options to exclude */
87  public String EXCLUDE_OPTIONS[] = { "Train Time", "Test Time", "File Size" };
88 
89  /** an array of libray files to be used in populating
90   * the default list comboBox*/
91  private String[] m_DefaultFileNames;
92 
93  /** an array of model Strings that should be excluded
94   * if the file size option is selected*/
95  private String[] m_LargeFileSizeModels;
96 
97  /** an array of model Strings that should be excluded
98   * if the train time option is selected*/
99  private String[] m_LargeTrainTimeModels;
100 
101  /** an array of model Strings that should be excluded
102   * if the test time option is selected*/
103  private String[] m_LargeTestTimeModels;
104 
105  /** this is a combo box that will allow the user to select
106   * which set of models to remove from the list */
107  private JComboBox m_ExcludeModelsComboBox;
108 
109  /** this is a button that will allow the user to select
110   * which set of models to remove from the list */
111  private JButton m_ExcludeModelsButton;
112 
113  /** this is a combo box that will allow the user to select
114   * the default model file */
115  private JComboBox m_DefaultFilesComboBox;
116 
117  /** allows the user to reload the default set */
118  private JButton m_RefreshButton;
119 
120  /**
121   * This object will store all of the models that can be selected
122   * from the default list.  The ModelList class is
123   * a custom class in weka.gui that knows how to display library
124   * model objects in a JList
125   */
126  private ModelList m_ModelList;
127 
128  /** This button allows the user to remove all the models currently
129   * selected in the model List from those that will be added*/
130  private JButton m_RemoveSelectedButton;
131 
132  /** This button allows the user to add all the in the current
133   * working default set to the library */
134  private JButton m_AddAllButton;
135 
136  /** This button allows the user to add all the models currently
137   * selected to the current set of models in this library, after
138   * this is selected it should also send the user back to the
139   * main interface*/
140  private JButton m_AddSelectedButton;
141 
142  /**
143   * This is a reference to the main gui object that is responsible
144   * for displaying the model library.  This panel will add models
145   * to the main panel through methods in this object.
146   */
147  private ListModelsPanel m_ListModelsPanel;
148 
149  /** whether an update is pending */
150  private boolean m_ListUpdatePending = false;
151 
152  /**
153   * Loads the configuration property file
154   */
155  static {
156   
157    try {
158      System.out.println("package name: " + getPackageName());
159     
160      DEFAULT_PROPERTIES = Utils.readProperties(getPackageName()
161          + PROPERTY_FILE);
162      java.util.Enumeration keys = (java.util.Enumeration) DEFAULT_PROPERTIES
163      .propertyNames();
164      if (!keys.hasMoreElements()) {
165        throw new Exception("Failed to read a property file for the "
166            + "generic object editor");
167      }
168    } catch (Exception ex) {
169      JOptionPane.showMessageDialog(null,
170          "Could not read a configuration file for the default models\n"
171          + "panel.\n", "DefaultProperties",
172          JOptionPane.ERROR_MESSAGE);
173    }
174   
175  }
176 
177  /**
178   * Constructor to initialize the GUI
179   *
180   * @param listModelsPanel     the panel to use
181   */
182  public DefaultModelsPanel(ListModelsPanel listModelsPanel) {
183    m_ListModelsPanel = listModelsPanel;
184   
185    readProperties();
186   
187    createDefaultModelsPanel();
188  }
189 
190  /**
191   * This grabs the relevant properties from the Default model
192   * properties file.
193   *
194   */
195  private void readProperties() {
196   
197    m_DefaultFileNames = DEFAULT_PROPERTIES.getProperty("files").split(", ");
198   
199    m_LargeTrainTimeModels = DEFAULT_PROPERTIES.getProperty("train_time").split(", ");
200   
201    m_LargeTestTimeModels = DEFAULT_PROPERTIES.getProperty("test_time").split(", ");
202   
203    m_LargeFileSizeModels = DEFAULT_PROPERTIES.getProperty("file_size").split(", ");
204  }
205 
206  /**
207   * Initializes the GUI
208   *
209   */
210  private void createDefaultModelsPanel() {
211   
212    setLayout(new GridBagLayout());
213    GridBagConstraints gbc = new GridBagConstraints();
214   
215    JLabel defaultFileLabel = new JLabel("Select default set: ");
216    gbc.weightx = 1;
217    gbc.fill = GridBagConstraints.HORIZONTAL;
218    gbc.gridx = 0;
219    gbc.gridy = 0;
220    gbc.gridwidth = 1;
221    gbc.anchor = GridBagConstraints.WEST;
222    add(defaultFileLabel, gbc);
223   
224    m_DefaultFilesComboBox = new JComboBox(m_DefaultFileNames);
225    m_DefaultFilesComboBox.setSelectedItem(m_DefaultFileNames[0]);
226    m_DefaultFilesComboBox.addActionListener(this);
227    gbc.fill = GridBagConstraints.HORIZONTAL;
228    gbc.gridx = 1;
229    gbc.gridy = 0;
230    gbc.gridwidth = 1;
231    gbc.anchor = GridBagConstraints.WEST;
232    add(m_DefaultFilesComboBox, gbc);
233   
234    m_RefreshButton = new JButton("Reload set");
235    m_RefreshButton.addActionListener(this);
236    gbc.weightx = 1;
237    gbc.fill = GridBagConstraints.HORIZONTAL;
238    gbc.gridx = 2;
239    gbc.gridy = 0;
240    gbc.gridwidth = 1;
241    gbc.anchor = GridBagConstraints.WEST;
242    add(m_RefreshButton, gbc);
243   
244    JLabel excludeModelsLabel = new JLabel("Exclude models w/ large");
245    gbc.weightx = 1;
246    gbc.fill = GridBagConstraints.HORIZONTAL;
247    gbc.gridx = 0;
248    gbc.gridy = 1;
249    gbc.gridwidth = 1;
250    gbc.anchor = GridBagConstraints.WEST;
251    add(excludeModelsLabel, gbc);
252   
253    m_ExcludeModelsComboBox = new JComboBox(EXCLUDE_OPTIONS);
254    m_ExcludeModelsComboBox.setSelectedItem(EXCLUDE_OPTIONS[0]);
255    //m_ExcludeModelsComboBox.addActionListener(this);
256    gbc.fill = GridBagConstraints.HORIZONTAL;
257    gbc.gridx = 1;
258    gbc.gridy = 1;
259    gbc.gridwidth = 1;
260    gbc.anchor = GridBagConstraints.WEST;
261    add(m_ExcludeModelsComboBox, gbc);
262   
263    m_ExcludeModelsButton = new JButton("Exclude");
264    m_ExcludeModelsButton.setToolTipText(
265        "Exclude this type of models from the current working list");
266    m_ExcludeModelsButton.addActionListener(this);
267    gbc.weightx = 1;
268    gbc.fill = GridBagConstraints.HORIZONTAL;
269    gbc.gridx = 2;
270    gbc.gridy = 1;
271    gbc.gridwidth = 1;
272    gbc.anchor = GridBagConstraints.WEST;
273    add(m_ExcludeModelsButton, gbc);
274   
275    JPanel modelListPanel = new JPanel();
276    modelListPanel.setBorder(BorderFactory
277        .createTitledBorder("Working set of Default Library Models"));
278   
279    m_ModelList = new ModelList();
280   
281    m_ModelList.getInputMap().put(
282        KeyStroke.getKeyStroke("released DELETE"), "deleteSelected");
283    m_ModelList.getActionMap().put("deleteSelected",
284        new AbstractAction("deleteSelected") {
285     
286      private static final long serialVersionUID = 4601977182190493654L;
287     
288      public void actionPerformed(ActionEvent evt) {
289       
290        Object[] currentModels = m_ModelList.getSelectedValues();
291       
292        ModelList.SortedListModel dataModel = ((ModelList.SortedListModel) m_ModelList.getModel());
293       
294        for (int i = 0; i < currentModels.length; i++) {
295          dataModel.removeElement((EnsembleLibraryModel) currentModels[i]);
296        }
297       
298        //Shrink the selected range to the first index that was selected
299        int selected[] = new int[1];
300        selected[0] = m_ModelList.getSelectedIndices()[0];
301        m_ModelList.setSelectedIndices(selected);
302       
303      }
304    });
305   
306    m_ModelList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
307    m_ModelList.setLayoutOrientation(JList.VERTICAL);
308    //m_ModelList.setVisibleRowCount(12);
309   
310    ToolTipManager.sharedInstance().registerComponent(m_ModelList);
311   
312    JScrollPane listView = new JScrollPane(m_ModelList);
313    listView
314    .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
315    listView.setPreferredSize(new Dimension(150, 50));
316   
317    modelListPanel.setLayout(new BorderLayout());
318    modelListPanel.add(listView, BorderLayout.CENTER);
319   
320    gbc.weightx = 1;
321    gbc.weighty = 1;
322    gbc.fill = GridBagConstraints.BOTH;
323    gbc.gridx = 0;
324    gbc.gridy = 2;
325    gbc.gridwidth = 3;
326    gbc.anchor = GridBagConstraints.WEST;
327    add(modelListPanel, gbc);
328   
329    m_RemoveSelectedButton = new JButton("Remove Selected");
330    m_RemoveSelectedButton.addActionListener(this);
331    m_RemoveSelectedButton.setToolTipText(
332        "Remove the selected models from the current default set");
333    gbc.fill = GridBagConstraints.HORIZONTAL;
334    gbc.weighty = 0;
335    gbc.gridx = 0;
336    gbc.gridy = 3;
337    gbc.anchor = GridBagConstraints.WEST;
338    gbc.weightx = 1;
339    gbc.gridwidth = 1;
340    add(m_RemoveSelectedButton, gbc);
341   
342    m_AddSelectedButton = new JButton("Add Selected");
343    m_AddSelectedButton.addActionListener(this);
344    m_AddSelectedButton.setToolTipText("Add selected models in "
345        + "above list to the library");
346    gbc.fill = GridBagConstraints.HORIZONTAL;
347    gbc.gridx = 1;
348    gbc.gridy = 3;
349    gbc.anchor = GridBagConstraints.WEST;
350    gbc.gridwidth = 1;
351    gbc.weightx = 1;
352    add(m_AddSelectedButton, gbc);
353   
354    m_AddAllButton = new JButton("Add All");
355    m_AddAllButton.addActionListener(this);
356    m_AddAllButton.setToolTipText("Add all models in the above"
357        + "list to the Libray");
358    gbc.fill = GridBagConstraints.HORIZONTAL;
359    gbc.gridx = 2;
360    gbc.gridy = 3;
361    gbc.anchor = GridBagConstraints.WEST;
362    gbc.gridwidth = 1;
363    gbc.weightx = 1;
364    add(m_AddAllButton, gbc);
365   
366    m_ListUpdatePending = true;
367   
368  }
369 
370  /**
371   * This method is called in response to user actions prompting
372   * us to reload the model list: when they select a new list,
373   * or hit reload.
374   *
375   */
376  public void updateDefaultList() {
377   
378    ((ModelList.SortedListModel) m_ModelList.getModel()).clear();
379   
380    String ensemblePackageString = getPackageName();
381   
382    int index = m_DefaultFilesComboBox.getSelectedIndex();
383   
384    Vector classifiers = null;
385   
386    LibrarySerialization serialization;
387    try {
388     
389      serialization = new LibrarySerialization();
390     
391      String defaultFileString = ensemblePackageString
392      + m_DefaultFileNames[index].trim() + ".model.xml";
393     
394      //System.out.println(defaultFileString);
395     
396      InputStream is = ClassLoader.getSystemResourceAsStream(defaultFileString);
397     
398      if (is == null) {
399        File f = new File(defaultFileString);
400        if (f.exists()) {
401          System.out.println("file existed: " + f.getPath());
402        } else {
403          System.out.println("file didn't exist: " + f.getPath());
404        }
405       
406      }
407     
408      classifiers = (Vector) serialization.read(ClassLoader.getSystemResourceAsStream(defaultFileString));
409     
410      for (Iterator it = classifiers.iterator(); it.hasNext();) {
411        EnsembleLibraryModel model = m_ListModelsPanel.getLibrary().createModel((Classifier) it.next());
412        model.testOptions();
413        ((ModelList.SortedListModel) m_ModelList.getModel()).add(model);
414      }
415     
416    } catch (Exception e) {
417      // TODO Auto-generated catch block
418      e.printStackTrace();
419    }
420  }
421 
422  /**
423   * Deals with user input to the various buttons in this GUI
424   *
425   * @param e           the event
426   */
427  public void actionPerformed(ActionEvent e) {
428   
429    ModelList.SortedListModel dataModel = ((ModelList.SortedListModel) m_ModelList
430        .getModel());
431   
432    if (e.getSource() == m_RefreshButton) {
433      updateDefaultList();
434     
435    } else if (e.getSource() == m_DefaultFilesComboBox) {
436      updateDefaultList();
437     
438    } else if (e.getSource() == m_RemoveSelectedButton) {
439     
440      //here we simply get the list of models that are
441      //currently selected and ten remove them from the list
442     
443      Object[] currentModels = m_ModelList.getSelectedValues();
444     
445      for (int i = 0; i < currentModels.length; i++) {
446        dataModel.removeElement(currentModels[i]);
447      }
448     
449      //Shrink the selected range to the first index that was selected
450      if (m_ModelList.getSelectedIndices().length > 0) {
451        int selected[] = new int[1];
452        selected[0] = m_ModelList.getSelectedIndices()[0];
453        m_ModelList.setSelectedIndices(selected);
454      }
455     
456    } else if (e.getSource() == m_AddAllButton) {
457     
458      //here we just need to add all of the models to the
459      //ListModelsPanel object
460     
461      Iterator it = dataModel.iterator();
462     
463      while (it.hasNext()) {
464        EnsembleLibraryModel currentModel = (EnsembleLibraryModel) it.next();
465        m_ListModelsPanel.addModel(currentModel);
466      }
467     
468      dataModel.clear();
469     
470    } else if (e.getSource() == m_AddSelectedButton) {
471     
472      //here we simply get the list of models that are
473      //currently selected and ten remove them from the list
474     
475      Object[] currentModels = m_ModelList.getSelectedValues();
476     
477      for (int i = 0; i < currentModels.length; i++) {
478       
479        m_ListModelsPanel.addModel((EnsembleLibraryModel) currentModels[i]);
480        dataModel.removeElement(currentModels[i]);
481      }
482    } else if (e.getSource() == m_ExcludeModelsButton) {
483     
484      if (m_ExcludeModelsComboBox.getSelectedIndex() == 0) {
485        applyTrainTimeFilters();
486      } else if (m_ExcludeModelsComboBox.getSelectedIndex() == 1) {
487        applyTestTimeFilters();
488      } else if (m_ExcludeModelsComboBox.getSelectedIndex() == 2) {
489        applyFileSizeFilters();
490      }
491    }
492  }
493 
494  /**
495   * this listener event fires when the use switches back to this panel
496   * it checks to se if the working directory has changed since they were
497   * here last.  If so then it updates the model list.
498   *
499   * @param e           the event
500   */
501  public void stateChanged(ChangeEvent e) {
502    JTabbedPane pane = (JTabbedPane) e.getSource();
503   
504    if (pane.getSelectedComponent().equals(this) && m_ListUpdatePending) {
505     
506      updateDefaultList();
507      m_ListUpdatePending = false;
508    }
509  }
510 
511  /**
512   * Removes models from the list that fit the regular expressions
513   * defining models that have large train times
514   */
515  public void applyTrainTimeFilters() {
516   
517    //create an array of patterns and then pass them to the apply
518    //filters method
519    Pattern patterns[] = new Pattern[m_LargeTrainTimeModels.length];
520   
521    for (int i = 0; i < m_LargeTrainTimeModels.length; i++) {
522      patterns[i] = Pattern.compile(m_LargeTrainTimeModels[i]);
523    }
524   
525    applyFilters(patterns);
526  }
527 
528  /**
529   * Removes models from the list that fit the regular expressions
530   * defining models that have large test times
531   */
532  public void applyTestTimeFilters() {
533   
534    //create an array of patterns and then pass them to the apply
535    //filters method
536    Pattern patterns[] = new Pattern[m_LargeTestTimeModels.length];
537   
538    for (int i = 0; i < m_LargeTestTimeModels.length; i++) {
539      patterns[i] = Pattern.compile(m_LargeTestTimeModels[i]);
540    }
541   
542    applyFilters(patterns);
543  }
544 
545  /**
546   * Removes models from the list that fit the regular expressions
547   * defining models that have large file sizes
548   */
549  public void applyFileSizeFilters() {
550   
551    //create an array of patterns and then pass them to the apply
552    //filters method
553    Pattern patterns[] = new Pattern[m_LargeFileSizeModels.length];
554   
555    for (int i = 0; i < m_LargeFileSizeModels.length; i++) {
556      patterns[i] = Pattern.compile(m_LargeFileSizeModels[i]);
557    }
558   
559    applyFilters(patterns);
560  }
561 
562  /**
563   * This is the code common to the previous three methods.  It basically
564   * takes a Java regexp pattern and applies it to the currently selected
565   * list of models, removing those that match as it goes. 
566   *
567   * @param patterns    the regexp patterns
568   */
569  public void applyFilters(Pattern[] patterns) {
570   
571    ModelList.SortedListModel dataModel = ((ModelList.SortedListModel) m_ModelList
572        .getModel());
573   
574    //this will track all of the models that we need to remove
575    //from our list
576    Vector toRemove = new Vector();
577   
578    //here we simply get the list of models that are
579    //currently selected and ten remove them from the list
580    //if they match one of the patterns
581   
582    Iterator it = dataModel.iterator();
583   
584    while (it.hasNext()) {
585      EnsembleLibraryModel currentModel = (EnsembleLibraryModel) it.next();
586     
587      for (int i = 0; i < patterns.length; i++) {
588        if (patterns[i].matcher(currentModel.getStringRepresentation()).matches()) {
589          toRemove.add(currentModel);
590          break;
591        }
592      }
593    }
594   
595    it = toRemove.iterator();
596   
597    while (it.hasNext()) {
598      dataModel.removeElement(it.next());
599    }
600  }
601 
602  /**
603   * this bit of code grabs all of the .model.xml files located in
604   * the ensemble selection package directory.  I decided to detect this *
605   * directory in case we change the package name which I think we planned
606   * on doing. 
607   *
608   * @return            the package name
609   */
610  public static String getPackageName() {
611    return 
612       EnsembleSelectionLibrary.class.toString()
613      .replaceAll("class ", "")
614      .replaceAll("EnsembleSelectionLibrary", "")
615      .replaceAll("\\.", "/");
616  }
617 
618}
Note: See TracBrowser for help on using the repository browser.