source: src/main/java/weka/gui/EnsembleLibraryEditor.java @ 21

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

Import di weka.

File size: 10.5 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 *    EnsembleLibraryEditor.java
19 *    Copyright (C) 2006 Robert Jung
20 *
21 */
22
23package weka.gui;
24
25import weka.classifiers.EnsembleLibrary;
26import weka.gui.ensembleLibraryEditor.AddModelsPanel;
27import weka.gui.ensembleLibraryEditor.ListModelsPanel;
28
29import java.awt.BorderLayout;
30import java.awt.Component;
31import java.awt.Graphics;
32import java.awt.Rectangle;
33import java.beans.PropertyChangeListener;
34import java.beans.PropertyChangeSupport;
35import java.beans.PropertyEditor;
36
37import javax.swing.JFrame;
38import javax.swing.JPanel;
39import javax.swing.JTabbedPane;
40
41/**
42 * Class for editing Library objects. Brings up a custom editing panel for the
43 * user to edit the library model list, as well as save load libraries from
44 * files.
45 * <p/>
46 * A model list file is simply a flat file with a single classifier on each
47 * line. Each of these classifier is represented by the command line string that
48 * would be used to create that specific model with the specified set of
49 * paramters.
50 * <p/>
51 * This code in class is based on other custom editors in weka.gui such as the
52 * CostMatrixEditor to try and maintain some consistency throughout the package.
53 *
54 * @author  Robert Jung (mrbobjung@gmail.com)
55 * @version $Revision: 1.1 $
56 */
57public class EnsembleLibraryEditor
58  implements PropertyEditor {
59 
60  /** The library being edited */
61  protected EnsembleLibrary m_Library;
62 
63  /** A helper class for notifying listeners */
64  protected transient PropertyChangeSupport m_PropSupport = new PropertyChangeSupport(
65      this);
66 
67  /** An instance of the custom editor */
68  protected transient CustomEditor m_CustomEditor = new CustomEditor();
69 
70  /**
71   * the main panel of the editor that will let the user switch between the
72   * different editing panels.
73   */
74  protected transient JTabbedPane m_ModelOptionsPane = new JTabbedPane();
75 
76  /**
77   * the main panel that will display the current set of models in the library
78   */
79  protected transient ListModelsPanel m_ListModelsPanel = new ListModelsPanel(
80      m_Library);
81 
82  /**
83   * This class presents a GUI for editing the library, and saving and loading
84   * model list from files.
85   */
86  private class CustomEditor
87    extends JPanel {
88   
89    /** for serialization */
90    private static final long serialVersionUID = -1553490570313707008L;
91
92    /**
93     * Constructs a new editor.
94     */
95    public CustomEditor() {
96     
97      m_ModelOptionsPane = new JTabbedPane();
98     
99      m_ListModelsPanel = new ListModelsPanel(m_Library);
100     
101      m_ModelOptionsPane.addTab("Current Library", m_ListModelsPanel);
102     
103      m_ModelOptionsPane.addTab("Add Models", new AddModelsPanel(
104          m_ListModelsPanel));
105     
106      // All added panels needs a reference to the main one so that
107      // they can add models to it.
108      setLayout(new BorderLayout());
109      add(m_ModelOptionsPane, BorderLayout.CENTER);
110    }
111   
112  }
113 
114  /**
115   * Constructs a new LibraryEditor.
116   */
117  public EnsembleLibraryEditor() {
118    m_PropSupport = new PropertyChangeSupport(this);
119    m_CustomEditor = new CustomEditor();
120  }
121 
122  /**
123   * Sets the value of the Library to be edited.
124   *
125   * @param value
126   *            a Library object to be edited
127   */
128  public void setValue(Object value) {
129    m_Library = (EnsembleLibrary) value;
130    m_ListModelsPanel.setLibrary(m_Library);
131  }
132 
133  /**
134   * Gets the cost matrix that is being edited.
135   *
136   * @return the edited CostMatrix object
137   */
138  public Object getValue() {
139    return m_Library;
140  }
141 
142  /**
143   * Indicates whether the object can be represented graphically. In this case
144   * it can.
145   *
146   * @return true
147   */
148  public boolean isPaintable() {
149    return true;
150  }
151 
152  /**
153   * Paints a graphical representation of the Object. For the ensemble library
154   * it prints out the working directory as well as the number of models in
155   * the library
156   *
157   * @param gfx
158   *            the graphics context to draw the representation to
159   * @param box
160   *            the bounds within which the representation should fit.
161   */
162  public void paintValue(Graphics gfx, Rectangle box) {
163    gfx.drawString(m_Library.size() + " models selected", box.x, box.y
164        + box.height);
165  }
166 
167  /**
168   * Returns the Java code that generates an object the same as the one being
169   * edited. Unfortunately this can't be done in a single line of code, so the
170   * code returned will only build a default cost matrix of the same size.
171   *
172   * @return the initialization string
173   */
174  public String getJavaInitializationString() {
175    return ("new Library(" + m_Library.size() + ")");
176  }
177 
178  /**
179   * Some objects can be represented as text, but a library cannot.
180   *
181   * @return null
182   */
183  public String getAsText() {
184    return null;
185  }
186 
187  /**
188   * Some objects can be represented as text, but a library cannot.
189   *
190   * @param text
191   *            ignored
192   * @throws always throws an IllegalArgumentException
193   */
194  public void setAsText(String text) {
195    throw new IllegalArgumentException("LibraryEditor: "
196        + "Library properties cannot be " + "expressed as text");
197  }
198 
199  /**
200   * Some objects can return tags, but a cost matrix cannot.
201   *
202   * @return null
203   */
204  public String[] getTags() {
205    return null;
206  }
207 
208  /**
209   * Gets a GUI component with which the user can edit the cost matrix.
210   *
211   * @return an editor GUI component
212   */
213  public Component getCustomEditor() {
214    return m_CustomEditor;
215  }
216 
217  /**
218   * Indicates whether the library can be edited in a GUI, which it can.
219   *
220   * @return true
221   */
222  public boolean supportsCustomEditor() {
223    return true;
224  }
225 
226  /**
227   * Adds an object to the list of those that wish to be informed when the
228   * library changes.
229   *
230   * @param listener
231   *            a new listener to add to the list
232   */
233  public void addPropertyChangeListener(PropertyChangeListener listener) {
234    m_Library.addPropertyChangeListener(listener);
235  }
236 
237  /**
238   * Removes an object from the list of those that wish to be informed when
239   * the cost matrix changes.
240   *
241   * @param listener
242   *            the listener to remove from the list
243   */
244  public void removePropertyChangeListener(PropertyChangeListener listener) {
245    m_PropSupport.removePropertyChangeListener(listener);
246  }
247 
248  // ***************************************************************
249  // The following three methods seem sort of out of place here.
250  // Basically they are helper methods for the various classes that
251  // constitute the AddModelsPanel. These static methods needed to
252  // go here because the objects (PropertyText, PropertyPanel, etc)
253  // involved are not visible from the weka.gui.libraryEditor
254  // package where the AddModelsPanel classes reside.  If these
255  // objects ever became public then these three methods should be
256  // moved within the gui.LibraryEditor package
257  // ***************************************************************
258 
259  /**
260   * This method handles the different object editor types in weka to obtain
261   * their current values.
262   *
263   * @param source      an Editor
264   * @return            the value of the editor
265   */
266  public static Object getEditorValue(Object source) {
267   
268    Object value = null;
269   
270    if (source instanceof GenericArrayEditor) {
271      value = ((GenericArrayEditor) source).getValue();
272    } else if (source instanceof CostMatrixEditor) {
273      value = ((CostMatrixEditor) source).getValue();
274    } else if (source instanceof PropertyText) {
275      value = ((PropertyText) source).getText();
276    } else if (source instanceof PropertyEditor) {
277      value = ((PropertyEditor) source).getValue();
278    }
279   
280    return value;
281  }
282 
283  /**
284   * This is a helper function that creates a renderer for Default Objects.
285   * These are basically objects that are not numeric, nominal, or generic
286   * objects. These are objects that we don't want to do anything special with
287   * and just display their values as normal. We simply create the editor the
288   * same way that they would have been created in the PropertySheetPanel
289   * class.
290   *
291   * @param nodeEditor
292   *            the editor created for the defaultNode
293   * @return the Component to dispaly the defaultNode
294   */
295  public static Component getDefaultRenderer(PropertyEditor nodeEditor) {
296   
297    Component genericRenderer = null;
298   
299    if (nodeEditor.isPaintable() && nodeEditor.supportsCustomEditor()) {
300      genericRenderer = new PropertyPanel(nodeEditor);
301    } else if (nodeEditor.getTags() != null) {
302      genericRenderer = new PropertyValueSelector(nodeEditor);
303    } else if (nodeEditor.getAsText() != null) {
304      // String init = editor.getAsText();
305      genericRenderer = new PropertyText(nodeEditor);
306      ((PropertyText) genericRenderer).setColumns(20);
307    } else {
308      System.err.println("Warning: Property \""
309          + nodeEditor.getClass().toString()
310          + "\" has non-displayabale editor.  Skipping.");
311    }
312   
313    return genericRenderer;
314  }
315 
316  /**
317   * This is a helper function that creates a renderer for GenericObjects
318   *
319   * @param classifierEditor
320   *            the editor created for this
321   * @return object renderer
322   */
323  public static Component createGenericObjectRenderer(
324      GenericObjectEditor classifierEditor) {
325   
326    PropertyPanel propertyPanel = new PropertyPanel(classifierEditor);
327   
328    return propertyPanel;
329  }
330 
331 
332  /**
333   * This is a simple main method that lets you run a LibraryEditor
334   * on its own without having to deal with the Explorer, etc...
335   * This is useful only for building model lists.
336   *
337   * @param args        the commandline arguments
338   */
339  public static void main(String[] args) {
340   
341    EnsembleLibrary value = new EnsembleLibrary();
342    EnsembleLibraryEditor libraryEditor = new EnsembleLibraryEditor();
343    libraryEditor.setValue(value);
344   
345    JPanel editor = (JPanel) libraryEditor.getCustomEditor();
346   
347    JFrame frame = new JFrame();
348    frame.getContentPane().add(editor);
349   
350    frame.pack();
351    frame.setVisible(true);
352  }
353 
354}
Note: See TracBrowser for help on using the repository browser.