source: src/main/java/weka/gui/explorer/Explorer.java @ 20

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

Import di weka.

File size: 12.4 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 *    Explorer.java
19 *    Copyright (C) 1999 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui.explorer;
24
25import weka.core.Capabilities;
26import weka.core.Copyright;
27import weka.core.Instances;
28import weka.core.Memory;
29import weka.core.converters.AbstractFileLoader;
30import weka.core.converters.ConverterUtils;
31import weka.gui.LogPanel;
32import weka.gui.Logger;
33import weka.gui.LookAndFeel;
34import weka.gui.WekaTaskMonitor;
35
36import java.awt.BorderLayout;
37import java.awt.Image;
38import java.awt.Toolkit;
39import java.awt.event.WindowAdapter;
40import java.awt.event.WindowEvent;
41import java.beans.PropertyChangeEvent;
42import java.beans.PropertyChangeListener;
43import java.io.File;
44import java.text.SimpleDateFormat;
45import java.util.Date;
46import java.util.EventListener;
47import java.util.HashSet;
48import java.util.Hashtable;
49import java.util.Vector;
50
51import javax.swing.JFrame;
52import javax.swing.JPanel;
53import javax.swing.JTabbedPane;
54import javax.swing.event.ChangeEvent;
55
56/**
57 * The main class for the Weka explorer. Lets the user create,
58 * open, save, configure, datasets, and perform ML analysis.
59 *
60 * @author Len Trigg (trigg@cs.waikato.ac.nz)
61 * @version $Revision: 4722 $
62 */
63public class Explorer
64  extends JPanel {
65
66  /** for serialization */
67  private static final long serialVersionUID = -7674003708867909578L;
68
69  /**
70   * Interface for classes that listen for filter changes.
71   *
72   * @author FracPete (fracpete at waikato dot ac dot nz)
73   * @version $Revision: 4722 $
74   */
75  public static interface CapabilitiesFilterChangeListener 
76    extends EventListener {
77   
78    /**
79     * method gets called in case of a change event
80     *
81     * @param e         the associated change event
82     */
83    public void capabilitiesFilterChanged(CapabilitiesFilterChangeEvent e);
84  }
85
86  /**
87   * This event can be fired in case the capabilities filter got changed
88   *
89   * @author FracPete (fracpete at waikato dot ac dot nz)
90   * @version $Revision: 4722 $
91   */
92  public static class CapabilitiesFilterChangeEvent
93    extends ChangeEvent {
94
95    /** for serialization */
96    private static final long serialVersionUID = 1194260517270385559L;
97   
98    /** the capabilities filter */
99    protected Capabilities m_Filter;
100   
101    /**
102     * Constructs a GOECapabilitiesFilterChangeEvent object.
103     *
104     * @param source    the Object that is the source of the event
105     * @param filter    the responsible capabilities filter
106     */
107    public CapabilitiesFilterChangeEvent(Object source, Capabilities filter) {
108      super(source);
109      m_Filter = filter;
110    }
111   
112    /**
113     * returns the associated Capabilities filter
114     *
115     * @return          the filter
116     */
117    public Capabilities getFilter() {
118      return m_Filter;
119    }
120  }
121
122  /**
123   * A common interface for panels to be displayed in the Explorer
124   *
125   * @author FracPete (fracpete at waikato dot ac dot nz)
126   * @version $Revision: 4722 $
127   */
128  public static interface ExplorerPanel {
129
130    /**
131     * Sets the Explorer to use as parent frame (used for sending notifications
132     * about changes in the data)
133     *
134     * @param parent    the parent frame
135     */
136    public void setExplorer(Explorer parent);
137   
138    /**
139     * returns the parent Explorer frame
140     *
141     * @return          the parent
142     */
143    public Explorer getExplorer();
144   
145    /**
146     * Tells the panel to use a new set of instances.
147     *
148     * @param inst a set of Instances
149     */
150    public void setInstances(Instances inst);
151   
152    /**
153     * Returns the title for the tab in the Explorer
154     *
155     * @return the title of this tab
156     */
157    public String getTabTitle();
158   
159    /**
160     * Returns the tooltip for the tab in the Explorer
161     *
162     * @return the tooltip of this tab
163     */
164    public String getTabTitleToolTip();
165  }
166
167  /**
168   * A common interface for panels in the explorer that can handle logs
169   *
170   * @author FracPete (fracpete at waikato dot ac dot nz)
171   * @version $Revision: 4722 $
172   */
173  public static interface LogHandler {
174   
175    /**
176     * Sets the Logger to receive informational messages
177     *
178     * @param newLog the Logger that will now get info messages
179     */
180    public void setLog(Logger newLog);
181  }
182
183  /** The panel for preprocessing instances */
184  protected PreprocessPanel m_PreprocessPanel = new PreprocessPanel();
185 
186  /** Contains all the additional panels apart from the pre-processing panel */
187  protected Vector<ExplorerPanel> m_Panels = new Vector<ExplorerPanel>();
188 
189  /** The tabbed pane that controls which sub-pane we are working with */
190  protected JTabbedPane m_TabbedPane = new JTabbedPane();
191 
192  /** The panel for log and status messages */
193  protected LogPanel m_LogPanel = new LogPanel(new WekaTaskMonitor());
194 
195  /** the listeners that listen to filter changes */
196  protected HashSet<CapabilitiesFilterChangeListener> m_CapabilitiesFilterChangeListeners = new HashSet<CapabilitiesFilterChangeListener>();
197 
198  /**
199   * Creates the experiment environment gui with no initial experiment
200   */
201  public Explorer() {
202   
203    String date = (new SimpleDateFormat("EEEE, d MMMM yyyy")).format(new Date());
204    m_LogPanel.logMessage("Weka Explorer");
205    m_LogPanel.logMessage("(c) " + Copyright.getFromYear() + "-" + Copyright.getToYear() 
206        + " " + Copyright.getOwner() + ", " + Copyright.getAddress());
207    m_LogPanel.logMessage("web: " + Copyright.getURL());
208    m_LogPanel.logMessage("Started on " + date);
209    m_LogPanel.statusMessage("Welcome to the Weka Explorer");
210
211    // intialize pre-processpanel
212    m_PreprocessPanel.setLog(m_LogPanel);
213    m_TabbedPane.addTab(
214        m_PreprocessPanel.getTabTitle(),
215        null,
216        m_PreprocessPanel,
217        m_PreprocessPanel.getTabTitleToolTip());
218   
219    // initialize additional panels
220    String[] tabs = ExplorerDefaults.getTabs();
221    Hashtable<String, HashSet> tabOptions = new Hashtable<String, HashSet>();
222    for (int i = 0; i < tabs.length; i++) {
223      try {
224        // determine classname and additional options
225        String[] optionsStr = tabs[i].split(":");
226        String classname = optionsStr[0];
227        HashSet options = new HashSet();
228        tabOptions.put(classname, options);
229        for (int n = 1; n < optionsStr.length; n++)
230          options.add(optionsStr[n]);
231         
232        // setup panel
233        ExplorerPanel panel = (ExplorerPanel) Class.forName(classname).newInstance();
234        panel.setExplorer(this);
235        m_Panels.add(panel);
236        if (panel instanceof LogHandler)
237          ((LogHandler) panel).setLog(m_LogPanel);
238        m_TabbedPane.addTab(
239            panel.getTabTitle(), null, (JPanel) panel, panel.getTabTitleToolTip());
240      }
241      catch (Exception e) {
242        e.printStackTrace();
243      }
244    }
245
246    // setup tabbed pane
247    m_TabbedPane.setSelectedIndex(0);
248    for (int i = 0; i < m_Panels.size(); i++) {
249      HashSet options = tabOptions.get(m_Panels.get(i).getClass().getName());
250      m_TabbedPane.setEnabledAt(i + 1, options.contains("standalone"));
251    }
252
253    // setup notification for dataset changes
254    m_PreprocessPanel.addPropertyChangeListener(new PropertyChangeListener() {
255      public void propertyChange(PropertyChangeEvent e) {
256        for (int i = 0; i < m_Panels.size(); i++) {
257           m_Panels.get(i).setInstances(m_PreprocessPanel.getInstances());
258           m_TabbedPane.setEnabledAt(i + 1, true);
259        }
260      }
261    });
262
263    // add listeners for changes in the capabilities
264    m_PreprocessPanel.setExplorer(this);
265    addCapabilitiesFilterListener(m_PreprocessPanel);
266    for (int i = 0; i < m_Panels.size(); i++) {
267      if (m_Panels.get(i) instanceof CapabilitiesFilterChangeListener)
268        addCapabilitiesFilterListener((CapabilitiesFilterChangeListener) m_Panels.get(i));
269    }
270
271    // add components to layout
272    setLayout(new BorderLayout());
273    add(m_TabbedPane, BorderLayout.CENTER);
274    add(m_LogPanel, BorderLayout.SOUTH);
275  }
276 
277  /**
278   * returns all the panels, apart from the PreprocessPanel
279   *
280   * @return            the currently displayed panels w/o PreprocessPanel
281   */
282  public Vector<ExplorerPanel> getPanels() {
283    return m_Panels;
284  }
285 
286  /**
287   * returns the instance of the PreprocessPanel being used in this instance
288   * of the Explorer
289   *
290   * @return            the panel
291   */
292  public PreprocessPanel getPreprocessPanel() {
293    return m_PreprocessPanel;
294  }
295 
296  /**
297   * returns the tabbed pane of the Explorer
298   *
299   * @return            the tabbed pane
300   */
301  public JTabbedPane getTabbedPane() {
302    return m_TabbedPane;
303  }
304 
305  /**
306   * adds the listener to the list of objects that listen for changes of the
307   * CapabilitiesFilter
308   *
309   * @param l           the listener to add
310   * @see               #m_CapabilitiesFilterChangeListeners
311   */
312  public void addCapabilitiesFilterListener(CapabilitiesFilterChangeListener l) {
313    m_CapabilitiesFilterChangeListeners.add(l);
314  }
315
316  /**
317   * Removes the specified listener from the set of listeners if it is present.
318   *
319   * @param l           the listener to remove
320   * @return            true if the listener was registered
321   */
322  public boolean removeCapabilitiesFilterListener(CapabilitiesFilterChangeListener l) {
323    return m_CapabilitiesFilterChangeListeners.remove(l);
324  }
325 
326  /**
327   * notifies all the listeners of a change
328   *
329   * @param filter      the affected filter
330   */
331  public void notifyCapabilitiesFilterListener(Capabilities filter) {
332    for (CapabilitiesFilterChangeListener l: m_CapabilitiesFilterChangeListeners) {
333      if (l == this)
334        continue;
335      l.capabilitiesFilterChanged(new CapabilitiesFilterChangeEvent(this, filter));
336    }
337  }
338 
339  /** variable for the Explorer class which would be set to null by the memory
340      monitoring thread to free up some memory if we running out of memory
341   */
342  private static Explorer m_explorer;
343
344  /** for monitoring the Memory consumption */
345  private static Memory m_Memory = new Memory(true);
346
347  /**
348   * Tests out the explorer environment.
349   *
350   * @param args ignored.
351   */
352  public static void main(String [] args) {
353
354    weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, "Logging started");
355   
356    LookAndFeel.setLookAndFeel();
357   
358    try {
359      // uncomment to disable the memory management:
360      //m_Memory.setEnabled(false);
361
362      m_explorer = new Explorer();
363      final JFrame jf = new JFrame("Weka Explorer");
364      jf.getContentPane().setLayout(new BorderLayout());
365      jf.getContentPane().add(m_explorer, BorderLayout.CENTER);
366      jf.addWindowListener(new WindowAdapter() {
367        public void windowClosing(WindowEvent e) {
368          jf.dispose();
369          System.exit(0);
370        }
371      });
372      jf.pack();
373      jf.setSize(800, 600);
374      jf.setVisible(true);
375      Image icon = Toolkit.getDefaultToolkit().
376      getImage(ClassLoader.getSystemResource("weka/gui/weka_icon.gif"));
377      jf.setIconImage(icon);
378
379      if (args.length == 1) {
380        System.err.println("Loading instances from " + args[0]);
381        AbstractFileLoader loader = ConverterUtils.getLoaderForFile(args[0]);
382        loader.setFile(new File(args[0]));
383        m_explorer.m_PreprocessPanel.setInstancesFromFile(loader);
384      }
385
386      Thread memMonitor = new Thread() {
387        public void run() {
388          while(true) {
389            try {
390              //System.out.println("Before sleeping.");
391              this.sleep(4000);
392
393              System.gc();
394
395              if (m_Memory.isOutOfMemory()) {
396                // clean up
397                jf.dispose();
398                m_explorer = null;
399                System.gc();
400
401                // stop threads
402                m_Memory.stopThreads();
403
404                // display error
405                System.err.println("\ndisplayed message:");
406                m_Memory.showOutOfMemory();
407                System.err.println("\nexiting");
408                System.exit(-1);
409              }
410
411            } catch(InterruptedException ex) { ex.printStackTrace(); }
412          }
413        }
414      };
415
416      memMonitor.setPriority(Thread.MAX_PRIORITY);
417      memMonitor.start();
418    } catch (Exception ex) {
419      ex.printStackTrace();
420      System.err.println(ex.getMessage());
421    }
422  }
423}
Note: See TracBrowser for help on using the repository browser.