source: branches/MetisMQI/src/main/java/weka/gui/boundaryvisualizer/BoundaryVisualizer.java

Last change on this file was 29, checked in by gnappo, 14 years ago

Taggata versione per la demo e aggiunto branch.

File size: 40.8 KB
RevLine 
[29]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 *   BoundaryVisualizer.java
19 *   Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui.boundaryvisualizer;
24
25import weka.classifiers.Classifier;
26import weka.classifiers.AbstractClassifier;
27import weka.core.Attribute;
28import weka.core.FastVector;
29import weka.core.Instances;
30import weka.core.DenseInstance;
31import weka.core.TechnicalInformation;
32import weka.core.TechnicalInformationHandler;
33import weka.core.Utils;
34import weka.core.TechnicalInformation.Field;
35import weka.core.TechnicalInformation.Type;
36import weka.gui.ExtensionFileFilter;
37import weka.gui.GenericObjectEditor;
38import weka.gui.PropertyPanel;
39import weka.gui.visualize.ClassPanel;
40
41import java.awt.BorderLayout;
42import java.awt.Color;
43import java.awt.Dimension;
44import java.awt.Font;
45import java.awt.FontMetrics;
46import java.awt.Graphics;
47import java.awt.GridBagConstraints;
48import java.awt.GridBagLayout;
49import java.awt.GridLayout;
50import java.awt.event.ActionEvent;
51import java.awt.event.ActionListener;
52import java.awt.event.ItemEvent;
53import java.awt.event.ItemListener;
54import java.awt.event.MouseAdapter;
55import java.awt.event.MouseEvent;
56import java.beans.PropertyChangeEvent;
57import java.beans.PropertyChangeListener;
58import java.io.File;
59import java.io.FileOutputStream;
60import java.io.ObjectOutputStream;
61import java.util.Vector;
62
63import javax.swing.BorderFactory;
64import javax.swing.BoxLayout;
65import javax.swing.ButtonGroup;
66import javax.swing.DefaultComboBoxModel;
67import javax.swing.JButton;
68import javax.swing.JCheckBox;
69import javax.swing.JComboBox;
70import javax.swing.JFileChooser;
71import javax.swing.JLabel;
72import javax.swing.JOptionPane;
73import javax.swing.JPanel;
74import javax.swing.JRadioButton;
75import javax.swing.JTextField;
76
77/**
78 * BoundaryVisualizer. Allows the visualization of classifier decision
79 * boundaries in two dimensions. A supplied classifier is first
80 * trained on supplied training data, then a data generator (currently
81 * using kernels) is used to generate new instances at points fixed in
82 * the two visualization dimensions but random in the other
83 * dimensions. These instances are classified by the classifier and
84 * plotted as points with colour corresponding to the probability
85 * distribution predicted by the classifier. At present, 2 * 2^(#
86 * non-fixed dimensions) points are generated from each kernel per
87 * pixel in the display. In practice, fewer points than this are
88 * actually classified because kernels are weighted (on a per-pixel
89 * basis) according to the fixexd dimensions and kernels corresponding
90 * to the lowest 1% of the weight mass are discarded. Predicted
91 * probability distributions are weighted (acording to the fixed
92 * visualization dimensions) and averaged to produce an RGB value for
93 * the pixel. For more information, see<p>
94 *
95 * Eibe Frank and Mark Hall (2003). Visualizing Class Probability
96 * Estimators. Working Paper 02/03, Department of Computer Science,
97 * University of Waikato.
98 *
99 * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
100 * @version $Revision: 5987 $
101 * @since 1.0
102 * @see JPanel
103 */
104public class BoundaryVisualizer
105  extends JPanel implements TechnicalInformationHandler {
106
107  /** for serialization */
108  private static final long serialVersionUID = 3933877580074013208L;
109
110  /**
111   * Inner class to handle rendering the axis
112   *
113   * @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
114   * @version $Revision: 5987 $
115   * @since 1.0
116   * @see JPanel
117   */
118  private class AxisPanel
119    extends JPanel {
120
121    /** for serialization */
122    private static final long serialVersionUID = -7421022416674492712L;
123   
124    private static final int MAX_PRECISION = 10;
125    private boolean m_vertical = false;
126    private final int PAD = 5;
127    private FontMetrics m_fontMetrics;
128    private int m_fontHeight;
129   
130    public AxisPanel(boolean vertical) {
131      m_vertical = vertical;
132      this.setBackground(Color.black);
133      //      Graphics g = this.getGraphics();
134      String fontFamily = this.getFont().getFamily();
135      Font newFont = new Font(fontFamily, Font.PLAIN, 10);
136      this.setFont(newFont);
137    }
138
139    public Dimension getPreferredSize() {
140      if (m_fontMetrics == null) {
141        Graphics g = this.getGraphics();
142        m_fontMetrics = g.getFontMetrics();
143        m_fontHeight = m_fontMetrics.getHeight();
144      }
145      if (!m_vertical) {
146        return new Dimension(this.getSize().width, PAD+2+m_fontHeight);
147      }
148      return new Dimension(50, this.getSize().height);
149    }
150
151    public void paintComponent(Graphics g) {
152      super.paintComponent(g);
153      this.setBackground(Color.black);
154      if (m_fontMetrics == null) {
155        m_fontMetrics = g.getFontMetrics();
156        m_fontHeight = m_fontMetrics.getHeight();
157      }
158
159      Dimension d = this.getSize();
160      Dimension d2 = m_boundaryPanel.getSize();
161      g.setColor(Color.gray);
162      int hf = m_fontMetrics.getAscent();
163      if (!m_vertical) {
164        g.drawLine(d.width, PAD, d.width-d2.width, PAD);
165        // try and draw some scale values
166        if (getInstances() != null) {
167          int precisionXmax = 1;
168          int precisionXmin = 1;
169          int whole = (int)Math.abs(m_maxX);
170          double decimal = Math.abs(m_maxX) - whole;
171          int nondecimal;
172          nondecimal = (whole > 0) 
173            ? (int)(Math.log(whole) / Math.log(10))
174            : 1;
175         
176          precisionXmax = (decimal > 0) 
177            ? (int)Math.abs(((Math.log(Math.abs(m_maxX)) / 
178                              Math.log(10))))+2
179            : 1;
180          if (precisionXmax > MAX_PRECISION) {
181            precisionXmax = 1;
182          }
183          String maxStringX = Utils.doubleToString(m_maxX,
184                                                   nondecimal+1+precisionXmax
185                                                   ,precisionXmax);
186         
187          whole = (int)Math.abs(m_minX);
188          decimal = Math.abs(m_minX) - whole;
189          nondecimal = (whole > 0) 
190            ? (int)(Math.log(whole) / Math.log(10))
191            : 1;
192          precisionXmin = (decimal > 0) 
193            ? (int)Math.abs(((Math.log(Math.abs(m_minX)) / 
194                              Math.log(10))))+2
195            : 1;
196          if (precisionXmin > MAX_PRECISION) {
197            precisionXmin = 1;
198          }
199         
200          String minStringX = Utils.doubleToString(m_minX,
201                                                   nondecimal+1+precisionXmin,
202                                                   precisionXmin);
203          g.drawString(minStringX,  d.width-d2.width, PAD+hf+2);
204          int maxWidth = m_fontMetrics.stringWidth(maxStringX);
205          g.drawString(maxStringX, d.width-maxWidth, PAD+hf+2);
206        }
207      } else {
208        g.drawLine(d.width-PAD, 0, d.width-PAD, d2.height);
209        // try and draw some scale values
210        if (getInstances() != null) {
211          int precisionYmax = 1;
212          int precisionYmin = 1;
213          int whole = (int)Math.abs(m_maxY);
214          double decimal = Math.abs(m_maxY) - whole;
215          int nondecimal;
216          nondecimal = (whole > 0) 
217            ? (int)(Math.log(whole) / Math.log(10))
218            : 1;
219         
220          precisionYmax = (decimal > 0) 
221            ? (int)Math.abs(((Math.log(Math.abs(m_maxY)) / 
222                              Math.log(10))))+2
223            : 1;
224          if (precisionYmax > MAX_PRECISION) {
225            precisionYmax = 1;
226          }
227          String maxStringY = Utils.doubleToString(m_maxY,
228                                                   nondecimal+1+precisionYmax
229                                                   ,precisionYmax);
230         
231          whole = (int)Math.abs(m_minY);
232          decimal = Math.abs(m_minY) - whole;
233          nondecimal = (whole > 0) 
234            ? (int)(Math.log(whole) / Math.log(10))
235            : 1;
236          precisionYmin = (decimal > 0) 
237            ? (int)Math.abs(((Math.log(Math.abs(m_minY)) / 
238                              Math.log(10))))+2
239            : 1;
240          if (precisionYmin > MAX_PRECISION) {
241            precisionYmin = 1;
242          }
243         
244          String minStringY = Utils.doubleToString(m_minY,
245                                                   nondecimal+1+precisionYmin,
246                                                   precisionYmin);
247          int maxWidth = m_fontMetrics.stringWidth(minStringY);
248          g.drawString(minStringY,  d.width-PAD-maxWidth-2, d2.height);
249          maxWidth = m_fontMetrics.stringWidth(maxStringY);
250          g.drawString(maxStringY, d.width-PAD-maxWidth-2, hf);
251        }
252      }
253    }
254  }
255 
256  /** the number of visualizer windows we have open. */
257  protected static int m_WindowCount = 0; 
258 
259  /** whether the exit if there are no more windows open */
260  protected static boolean m_ExitIfNoWindowsOpen = true;
261
262  /** the training instances */
263  private Instances m_trainingInstances;
264
265  /** the classifier to use */
266  private Classifier m_classifier;
267
268  // plot area dimensions
269  protected int m_plotAreaWidth = 384;
270  //protected int m_plotAreaHeight = 384;
271  protected int m_plotAreaHeight = 384;
272
273  /** the plotting panel */
274  protected BoundaryPanel m_boundaryPanel;
275
276  // combo boxes for selecting the class attribute, class values (for
277  // colouring pixels), and visualization attributes
278  protected JComboBox m_classAttBox = new JComboBox();
279  protected JComboBox m_xAttBox = new JComboBox();
280  protected JComboBox m_yAttBox = new JComboBox();
281
282  protected Dimension COMBO_SIZE = 
283    new Dimension((int)(m_plotAreaWidth * 0.75),
284                  m_classAttBox.getPreferredSize().height);
285
286  protected JButton m_startBut = new JButton("Start");
287
288  protected JCheckBox m_plotTrainingData = new JCheckBox("Plot training data");
289
290  protected JPanel m_controlPanel;
291
292  protected ClassPanel m_classPanel = new ClassPanel();
293
294  // separate panels for rendering axis information
295  private AxisPanel m_xAxisPanel;
296  private AxisPanel m_yAxisPanel;
297
298  // min and max values for visualization dimensions
299  private double m_maxX;
300  private double m_maxY;
301  private double m_minX;
302  private double m_minY;
303
304  private int m_xIndex;
305  private int m_yIndex;
306
307  /* Kernel density estimator/generator */
308  private KDDataGenerator m_dataGenerator;
309
310  /* number of samples per pixel (fixed dimensions only) */
311  private int m_numberOfSamplesFromEachRegion;
312
313  /** base for sampling in the non-fixed dimensions */
314  private int m_generatorSamplesBase;
315
316  /** Set the kernel bandwidth to cover this many nearest neighbours */
317  private int m_kernelBandwidth;
318 
319  private JTextField m_regionSamplesText = 
320    new JTextField(""+0);
321
322  private JTextField m_generatorSamplesText = 
323    new JTextField(""+0);
324
325  private JTextField m_kernelBandwidthText = 
326    new JTextField(""+3+"  ");
327
328  //jimmy
329  protected GenericObjectEditor m_classifierEditor = new GenericObjectEditor(); //the widget to select the classifier
330  protected PropertyPanel m_ClassifierPanel = new PropertyPanel(m_classifierEditor);
331  /** The file chooser for selecting arff files */
332  protected JFileChooser m_FileChooser
333    = new JFileChooser(new File(System.getProperty("user.dir")));
334  protected ExtensionFileFilter m_arffFileFilter = 
335    new ExtensionFileFilter(Instances.FILE_EXTENSION,
336                            "Arff data files");
337  protected JLabel dataFileLabel = new JLabel(); //stores the name of the data file (currently stores relation name rather than filename)
338  protected JPanel m_addRemovePointsPanel = new JPanel(); //a panel which contains the controls to add and remove points
339  protected JComboBox m_classValueSelector = new JComboBox(); //a widget to select the class attribute.
340  protected JRadioButton m_addPointsButton = new JRadioButton(); //when this is selected, clicking on the BoundaryPanel will add points.
341  protected JRadioButton m_removePointsButton = new JRadioButton(); //when this is selected, clicking on the BoundaryPanel will remove points.
342  protected ButtonGroup m_addRemovePointsButtonGroup = new ButtonGroup();
343  protected JButton removeAllButton = new JButton ("Remove all"); //button to remove all points
344  protected JButton chooseButton = new JButton("Open File"); //button to choose a data file
345 
346  /* Register the property editors we need */
347  static {
348    GenericObjectEditor.registerEditors();
349  }
350 
351  /**
352   * Returns a string describing this tool
353   * @return a description of the tool suitable for
354   * displaying in various Weka GUIs
355   */
356  public String globalInfo() {
357    return "Class for visualizing class probability estimates.\n\n"
358    + "For more information, see\n\n"
359    + getTechnicalInformation().toString();
360  }
361 
362  /**
363   * Returns an instance of a TechnicalInformation object, containing
364   * detailed information about the technical background of this class,
365   * e.g., paper reference or book this class is based on.
366   *
367   * @return the technical information about this class
368   */
369  public TechnicalInformation getTechnicalInformation() {
370    TechnicalInformation        result;
371
372    result = new TechnicalInformation(Type.INPROCEEDINGS);
373    result.setValue(Field.AUTHOR, "Eibe Frank and Mark Hall");
374    result.setValue(Field.TITLE, "Visualizing class probability estimators");
375    result.setValue(Field.BOOKTITLE, "European Conference on Principles and Practice of " +
376                "Knowledge Discovery in Databases");
377    result.setValue(Field.YEAR, "2003");
378    result.setValue(Field.PAGES, "168-169");
379    result.setValue(Field.PUBLISHER, "Springer-Verlag");
380    result.setValue(Field.ADDRESS, "Cavtat-Dubrovnik");
381
382    return result;
383  }
384
385
386  /**
387   * Creates a new <code>BoundaryVisualizer</code> instance.
388   */
389  public BoundaryVisualizer() {
390   
391    setLayout(new BorderLayout());
392    m_classAttBox.setMinimumSize(COMBO_SIZE);
393    m_classAttBox.setPreferredSize(COMBO_SIZE);
394    m_classAttBox.setMaximumSize(COMBO_SIZE);
395    m_classAttBox.addActionListener(new ActionListener() {
396      public void actionPerformed(ActionEvent e) {
397        if (m_classAttBox.getItemCount() != 0)
398        {
399                try { 
400                        m_classPanel.setCindex(m_classAttBox.getSelectedIndex());
401                        plotTrainingData();
402                        System.err.println("Here in class att box listener");
403                } catch (Exception ex) {ex.printStackTrace();}
404               
405                //set up the add points selector combo box. -jimmy
406                setUpClassValueSelectorCB();
407        }
408      }
409      });
410           
411
412    m_xAttBox.setMinimumSize(COMBO_SIZE);
413    m_xAttBox.setPreferredSize(COMBO_SIZE);
414    m_xAttBox.setMaximumSize(COMBO_SIZE);
415
416    m_yAttBox.setMinimumSize(COMBO_SIZE);
417    m_yAttBox.setPreferredSize(COMBO_SIZE);
418    m_yAttBox.setMaximumSize(COMBO_SIZE);
419
420    m_classPanel.setMinimumSize(new 
421      Dimension((int)COMBO_SIZE.getWidth()*2, 
422                (int)COMBO_SIZE.getHeight()*2));
423    m_classPanel.setPreferredSize(new 
424      Dimension((int)COMBO_SIZE.getWidth()*2, 
425                (int)COMBO_SIZE.getHeight()*2));
426
427
428    m_controlPanel = new JPanel();
429    m_controlPanel.setLayout(new BorderLayout());
430   
431    //jimmy
432    JPanel dataChooseHolder = new JPanel(new BorderLayout());
433    dataChooseHolder.setBorder(BorderFactory.createTitledBorder("Dataset"));
434    dataChooseHolder.add(dataFileLabel, BorderLayout.WEST);
435   
436    m_FileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
437    m_FileChooser.addChoosableFileFilter(m_arffFileFilter);
438    chooseButton.addActionListener(new ActionListener() {
439      public void actionPerformed(ActionEvent e) {
440        try {
441                setInstancesFromFileQ();
442                int classIndex = m_classAttBox.getSelectedIndex();
443                if (m_trainingInstances != null && m_classifier != null && (m_trainingInstances.attribute(classIndex).isNominal())) {
444                        m_startBut.setEnabled(true);
445//                      plotTrainingData();
446                }
447               
448               
449        } catch (Exception ex) {
450                ex.printStackTrace(System.out);
451                System.err.println("exception");
452        }
453       
454      }
455    });
456    dataChooseHolder.add(chooseButton, BorderLayout.EAST);
457   
458    JPanel classifierHolder = new JPanel();
459    classifierHolder.setBorder(BorderFactory.createTitledBorder("Classifier"));
460    classifierHolder.setLayout(new BorderLayout());
461    m_classifierEditor.setClassType(weka.classifiers.Classifier.class);
462   
463    m_classifierEditor.addPropertyChangeListener(new PropertyChangeListener() {
464        public void propertyChange(PropertyChangeEvent evt) {
465                m_classifier = (Classifier)m_classifierEditor.getValue();
466                try {
467                        int classIndex = m_classAttBox.getSelectedIndex();
468                        if (m_trainingInstances != null && m_classifier != null && (m_trainingInstances.attribute(classIndex).isNominal())) {
469                                m_startBut.setEnabled(true);
470                        }
471                } catch (Exception ex) {};
472        }
473    });
474    classifierHolder.add(m_ClassifierPanel, BorderLayout.CENTER);
475   
476       
477
478    JPanel cHolder = new JPanel();
479    cHolder.setBorder(BorderFactory.createTitledBorder("Class Attribute"));
480    cHolder.add(m_classAttBox);
481
482    JPanel vAttHolder = new JPanel();
483    vAttHolder.setLayout(new GridLayout(2,1));
484    vAttHolder.setBorder(BorderFactory.
485                         createTitledBorder("Visualization Attributes"));
486    vAttHolder.add(m_xAttBox);
487    vAttHolder.add(m_yAttBox);
488
489    JPanel colOne = new JPanel();
490    colOne.setLayout(new BorderLayout());
491    colOne.add(dataChooseHolder, BorderLayout.NORTH); //jimmy
492    colOne.add(cHolder, BorderLayout.CENTER);
493    //colOne.add(vAttHolder, BorderLayout.SOUTH);
494
495    JPanel tempPanel = new JPanel();
496    tempPanel.setBorder(BorderFactory.
497                        createTitledBorder("Sampling control"));
498    tempPanel.setLayout(new GridLayout(3,1));
499
500    JPanel colTwo = new JPanel();
501    colTwo.setLayout(new BorderLayout());
502    JPanel gsP = new JPanel(); gsP.setLayout(new BorderLayout());
503    gsP.add(new JLabel(" Base for sampling (r)"), BorderLayout.CENTER);
504    gsP.add(m_generatorSamplesText, BorderLayout.WEST);
505    tempPanel.add(gsP);
506
507    JPanel rsP = new JPanel(); rsP.setLayout(new BorderLayout());
508    rsP.add(new JLabel(" Num. locations per pixel"), BorderLayout.CENTER);
509    rsP.add(m_regionSamplesText, BorderLayout.WEST);
510    tempPanel.add(rsP);
511
512    JPanel ksP = new JPanel(); ksP.setLayout(new BorderLayout());
513    ksP.add(new JLabel(" Kernel bandwidth (k)"), BorderLayout.CENTER);
514    ksP.add(m_kernelBandwidthText, BorderLayout.WEST);
515    tempPanel.add(ksP);
516   
517    colTwo.add(classifierHolder,BorderLayout.NORTH);//jimmy
518    //colTwo.add(tempPanel, BorderLayout.CENTER);
519    colTwo.add(vAttHolder, BorderLayout.CENTER);
520
521    JPanel startPanel = new JPanel();
522    startPanel.setBorder(BorderFactory.
523                         createTitledBorder("Plotting"));
524    startPanel.setLayout(new BorderLayout());
525    startPanel.add(m_startBut, BorderLayout.CENTER);
526    startPanel.add(m_plotTrainingData, BorderLayout.WEST);
527
528    //colTwo.add(startPanel, BorderLayout.SOUTH);
529
530    m_controlPanel.add(colOne, BorderLayout.WEST);
531    m_controlPanel.add(colTwo, BorderLayout.CENTER);
532    JPanel classHolder = new JPanel();
533    classHolder.setLayout(new BorderLayout()); //jimmy
534    classHolder.setBorder(BorderFactory.createTitledBorder("Class color"));
535    classHolder.add(m_classPanel, BorderLayout.CENTER);
536    m_controlPanel.add(classHolder, BorderLayout.SOUTH);
537   
538    JPanel aboutAndControlP = new JPanel();
539    aboutAndControlP.setLayout(new BorderLayout());
540    aboutAndControlP.add(m_controlPanel, BorderLayout.SOUTH);
541   
542    weka.gui.PropertySheetPanel psp = new weka.gui.PropertySheetPanel();
543    psp.setTarget(BoundaryVisualizer.this);
544    JPanel aboutPanel = psp.getAboutPanel();
545   
546    aboutAndControlP.add(aboutPanel, BorderLayout.NORTH);
547
548    add(aboutAndControlP, BorderLayout.NORTH);
549   
550    //classHolder.add(newWindowButton, BorderLayout.EAST);
551   
552    // set up the add-remove points widgets
553    m_addRemovePointsPanel.setBorder(BorderFactory.createTitledBorder("Add / remove data points"));
554    m_addRemovePointsPanel.setLayout(new GridBagLayout());
555    GridBagConstraints constraints = new GridBagConstraints();
556    constraints.weightx = 1.0;
557    constraints.weighty = 1.0;
558    constraints.gridx = 0;
559    constraints.gridy = 0;
560    constraints.fill = GridBagConstraints.BOTH;
561    m_addRemovePointsPanel.add(m_addPointsButton);
562    constraints.gridx = 1;
563    m_addRemovePointsPanel.add(new JLabel("Add points"), constraints);
564    constraints.gridx = 2;
565    m_addRemovePointsPanel.add(m_classValueSelector);
566    constraints.gridx = 0;
567    constraints.gridy = 1;
568    m_addRemovePointsPanel.add(m_removePointsButton, constraints);
569    constraints.gridx = 1;
570    m_addRemovePointsPanel.add(new JLabel("Remove points"),constraints);
571   
572   
573        removeAllButton.addActionListener(new ActionListener() {
574                public void actionPerformed(ActionEvent e) {
575                        if (m_trainingInstances != null)
576                        {
577                                if (m_startBut.getText().equals("Stop")) //we are plotting
578                                        return;
579                                m_boundaryPanel.removeAllInstances();
580                                computeBounds();
581                                m_xAxisPanel.repaint(0,0,0,m_xAxisPanel.getWidth(), m_xAxisPanel.getHeight());
582                                m_yAxisPanel.repaint(0,0,0,m_yAxisPanel.getWidth(), m_yAxisPanel.getHeight());
583       
584                                try {m_boundaryPanel.plotTrainingData(); } catch (Exception ex) {}
585                        }
586                }       
587        });
588    constraints.gridx = 2;
589    m_addRemovePointsPanel.add(removeAllButton, constraints);
590   
591//     m_addRemovePointsPanel.add(addPointsFrame, BorderLayout.NORTH);
592//     m_addRemovePointsPanel.add(removePointsFrame, BorderLayout.CENTER);
593    //m_addRemovePointsPanel.add(removeAllButton, BorderLayout.SOUTH);
594   
595   
596    m_addRemovePointsButtonGroup.add(m_addPointsButton);
597    m_addRemovePointsButtonGroup.add(m_removePointsButton);
598    m_addPointsButton.setSelected(true);
599       
600    //classHolder.add(m_addRemovePointsPanel, BorderLayout.SOUTH);
601   
602
603    m_boundaryPanel = new BoundaryPanel(m_plotAreaWidth, m_plotAreaHeight);
604    m_numberOfSamplesFromEachRegion = m_boundaryPanel.getNumSamplesPerRegion();
605    m_regionSamplesText.setText(""+m_numberOfSamplesFromEachRegion+"  ");
606    m_generatorSamplesBase = (int)m_boundaryPanel.getGeneratorSamplesBase();
607    m_generatorSamplesText.setText(""+m_generatorSamplesBase+"  ");
608
609    m_dataGenerator = new KDDataGenerator();
610    m_kernelBandwidth = m_dataGenerator.getKernelBandwidth();
611    m_kernelBandwidthText.setText(""+m_kernelBandwidth+"  ");
612    m_boundaryPanel.setDataGenerator(m_dataGenerator);
613   
614     
615    JPanel gfxPanel = new JPanel();
616    gfxPanel.setLayout(new BorderLayout());
617    gfxPanel.setBorder(BorderFactory.createEtchedBorder());
618    //add(gfxPanel, BorderLayout.CENTER);
619       
620   // gfxPanel.add(m_addRemovePointsPanel, BorderLayout.NORTH);
621    gfxPanel.add(m_boundaryPanel, BorderLayout.CENTER);
622    m_xAxisPanel = new AxisPanel(false);
623    gfxPanel.add(m_xAxisPanel, BorderLayout.SOUTH);
624    m_yAxisPanel = new AxisPanel(true);
625    gfxPanel.add(m_yAxisPanel, BorderLayout.WEST);
626   
627    JPanel containerPanel = new JPanel();
628    containerPanel.setLayout(new BorderLayout());
629    containerPanel.add(gfxPanel, BorderLayout.CENTER);
630    add(containerPanel, BorderLayout.WEST);
631   
632    JPanel rightHandToolsPanel = new JPanel(); //this panel contains the widgets to the right of the BoundaryPanel.
633    rightHandToolsPanel.setLayout(new BoxLayout(rightHandToolsPanel, BoxLayout.PAGE_AXIS));
634
635    rightHandToolsPanel.add(m_addRemovePointsPanel);
636   
637    JButton newWindowButton = new JButton("Open a new window"); //the button for spawning a new window for the program.
638    //newWindowButton.setMaximumSize(new Dimension(100, 100));
639    //newWindowButton.setPreferredSize(new Dimension(120, m_addRemovePointsPanel.getHeight()));
640    newWindowButton.addActionListener(new ActionListener() {
641        public void actionPerformed(ActionEvent e) {
642                try {
643                        Instances newTrainingData = null;
644                        Classifier newClassifier = null;
645                        if (m_trainingInstances != null)
646                                newTrainingData = new Instances(m_trainingInstances);
647                        if (m_classifier != null)
648                                newClassifier = AbstractClassifier.makeCopy(m_classifier);
649                        createNewVisualizerWindow(newClassifier, newTrainingData);
650                } catch (Exception ex) {  ex.printStackTrace();}
651        }
652    });
653    JPanel newWindowHolder = new JPanel();
654    newWindowHolder.add(newWindowButton);
655    rightHandToolsPanel.add(newWindowHolder);
656    rightHandToolsPanel.add(tempPanel);
657    rightHandToolsPanel.add(startPanel);
658   
659    containerPanel.add(rightHandToolsPanel, BorderLayout.EAST);
660       
661    /*add(m_boundaryPanel, BorderLayout.CENTER);
662
663    m_xAxisPanel = new AxisPanel(false);
664    add(m_xAxisPanel, BorderLayout.SOUTH);
665    m_yAxisPanel = new AxisPanel(true);
666    add(m_yAxisPanel, BorderLayout.WEST);*/
667
668    m_startBut.setEnabled(false);
669    m_startBut.addActionListener(new ActionListener() {
670        public void actionPerformed(ActionEvent e) {
671          if (m_startBut.getText().equals("Start")) {
672            if (m_trainingInstances != null && m_classifier != null) {
673                try {
674                       
675                        int BPSuccessCode = setUpBoundaryPanel(); //set up the boundary panel, find out if it was successful or not.
676                       
677                        if (BPSuccessCode == 1)
678                                JOptionPane.showMessageDialog(null,"Error: Kernel Bandwidth can't be less than zero!");
679                        else if (BPSuccessCode == 2) {
680                                JOptionPane.showMessageDialog(null,"Error: Kernel Bandwidth must be less than the number of training instances!");
681                        } else {
682                                m_boundaryPanel.start();
683                                m_startBut.setText("Stop");
684                                setControlEnabledStatus(false);
685                        }
686                } catch (Exception ex) {
687                        ex.printStackTrace();
688                }
689            }
690          } else {
691            m_boundaryPanel.stopPlotting();
692            m_startBut.setText("Start");
693            setControlEnabledStatus(true);
694          }
695        }
696      });
697
698    m_boundaryPanel.addActionListener(new ActionListener() {
699        public void actionPerformed(ActionEvent e) {
700          m_startBut.setText("Start");
701          setControlEnabledStatus(true);
702        }
703      });
704
705    m_classPanel.addActionListener(new ActionListener() {
706        public void actionPerformed(ActionEvent e) {
707
708          try {
709            // save color vector to a file
710            FastVector colors = m_boundaryPanel.getColors();
711            FileOutputStream fos = new FileOutputStream("colors.ser");
712            ObjectOutputStream oos = new ObjectOutputStream(fos);
713            oos.writeObject(colors);
714            oos.flush();
715            oos.close();
716          } catch (Exception ex) {}
717
718          m_boundaryPanel.replot();
719         
720        }
721      });
722     
723    //set up a mouse listener for the boundary panel.
724    m_boundaryPanel.addMouseListener(new MouseAdapter() {
725        public void mouseClicked(MouseEvent e) {
726//              System.err.println("boundary panel mouseClick " + e.getX() + " " + e.getY());
727                if (m_trainingInstances != null) {
728                        if (m_startBut.getText().equals("Stop")) //we are plotting
729                                return;
730               
731                        if (m_addPointsButton.isSelected()) {//we are in add mode
732                                double classVal = 0;
733                                boolean validInput = true;
734                                if (m_trainingInstances.attribute(m_classAttBox.getSelectedIndex()).isNominal()) //class is nominal
735                                        classVal = (double)m_classValueSelector.getSelectedIndex();
736                                else {
737                                        String indexStr = "";
738                                        try {                                   
739                                                indexStr = (String)m_classValueSelector.getSelectedItem();
740                                                classVal = Double.parseDouble(indexStr);
741                                        } catch (Exception ex) {
742                                                if (indexStr == null) indexStr = "";
743                                                JOptionPane.showMessageDialog(null,"Error adding a point: \"" + indexStr + "\""
744                                                        + " is not a valid class value.");
745                                                validInput = false;
746                                        }
747                                }
748                                //System.err.println("classVal is " + classVal);
749                                if (validInput)
750                                        m_boundaryPanel.addTrainingInstanceFromMouseLocation(e.getX(), e.getY(), m_classAttBox.getSelectedIndex(), classVal);
751                        }
752                        else { //remove mode
753                                m_boundaryPanel.removeTrainingInstanceFromMouseLocation(e.getX(), e.getY());
754                        }
755                        try{ plotTrainingData(); } catch (Exception ex) {} //jimmy
756                        m_xAxisPanel.repaint(0,0,0,m_xAxisPanel.getWidth(), m_xAxisPanel.getHeight());
757                        m_yAxisPanel.repaint(0,0,0,m_yAxisPanel.getWidth(), m_yAxisPanel.getHeight());
758                }
759        }
760    });
761  }
762   
763  /**
764   * Set the enabled status of the controls
765   *
766   * @param status a <code>boolean</code> value
767   */
768  private void setControlEnabledStatus(boolean status) {
769    m_classAttBox.setEnabled(status);
770    m_xAttBox.setEnabled(status);
771    m_yAttBox.setEnabled(status);
772    m_regionSamplesText.setEnabled(status);
773    m_generatorSamplesText.setEnabled(status);
774    m_kernelBandwidthText.setEnabled(status);
775    m_plotTrainingData.setEnabled(status);
776    removeAllButton.setEnabled(status);
777    m_classValueSelector.setEnabled(status);
778    m_addPointsButton.setEnabled(status);
779    m_removePointsButton.setEnabled(status);
780    m_FileChooser.setEnabled(status);
781    chooseButton.setEnabled(status);
782  }
783
784  /**
785   * Set a classifier to use
786   *
787   * @param newClassifier the classifier to use
788   * @exception Exception if an error occurs
789   */
790  public void setClassifier(Classifier newClassifier) throws Exception {
791
792    m_classifier = newClassifier;
793   
794    try {
795        int classIndex = m_classAttBox.getSelectedIndex();
796       
797        if ((m_classifier != null) && (m_trainingInstances != null) &&
798                (m_trainingInstances.attribute(classIndex).isNominal())) {
799                m_startBut.setEnabled(true);
800        }
801        else
802                m_startBut.setEnabled(false);
803    } catch (Exception e) {}
804   
805  }
806 
807  /** Sets up the bounds on our x and y axes to fit the dataset.
808      Also repaints the x and y axes.
809  */
810  private void computeBounds() {
811 
812    m_boundaryPanel.computeMinMaxAtts(); //delegate to the BoundaryPanel
813 
814    String xName = (String)m_xAttBox.getSelectedItem();
815    if (xName == null) {
816      return;
817    }
818    xName = Utils.removeSubstring(xName, "X: ");
819    xName = Utils.removeSubstring(xName, " (Num)");
820    String yName = (String)m_yAttBox.getSelectedItem();
821    yName = Utils.removeSubstring(yName, "Y: ");
822    yName = Utils.removeSubstring(yName, " (Num)");
823
824    m_xIndex = -1;
825    m_yIndex = -1;
826    for (int i = 0; i < m_trainingInstances.numAttributes(); i++) {
827      if (m_trainingInstances.attribute(i).name().equals(xName)) {
828        m_xIndex = i;
829      } 
830      if (m_trainingInstances.attribute(i).name().equals(yName)) {
831        m_yIndex = i;
832      }
833    }
834   
835    m_minX = m_boundaryPanel.getMinXBound();
836    m_minY = m_boundaryPanel.getMinYBound();
837    m_maxX = m_boundaryPanel.getMaxXBound();
838    m_maxY = m_boundaryPanel.getMaxYBound();
839    //System.err.println("setting bounds to " + m_minX + " " + m_minY + " " + m_maxX + " " + m_maxY);
840    m_xAxisPanel.repaint(0,0,0,m_xAxisPanel.getWidth(), m_xAxisPanel.getHeight());
841    m_yAxisPanel.repaint(0,0,0,m_yAxisPanel.getWidth(), m_yAxisPanel.getHeight());
842  }
843
844  /**
845   * Get the training instances
846   *
847   * @return the training instances
848   */
849  public Instances getInstances() {
850    return m_trainingInstances;
851  }
852
853  /**
854   * Set the training instances
855   *
856   * @param inst the instances to use
857   */
858  public void setInstances(Instances inst) throws Exception {
859    if (inst == null) {
860        m_trainingInstances = inst;
861        m_classPanel.setInstances(m_trainingInstances);
862        return;
863    }
864   
865    // count the number of numeric attributes
866    int numCount = 0;
867    for (int i = 0; i < inst.numAttributes(); i++) {
868      if (inst.attribute(i).isNumeric()) {
869        numCount++;
870      }
871    }
872   
873    if (numCount < 2) {
874      JOptionPane.showMessageDialog(null,"We need at least two numeric " +
875                "attributes in order to visualize!");
876      return;
877    }
878       
879    m_trainingInstances = inst;
880    m_classPanel.setInstances(m_trainingInstances);
881    // setup combo boxes
882    String [] classAttNames = new String [m_trainingInstances.numAttributes()];
883    final Vector xAttNames = new Vector();
884    Vector yAttNames = new Vector();
885
886    for (int i = 0; i < m_trainingInstances.numAttributes(); i++) {
887      classAttNames[i] = m_trainingInstances.attribute(i).name();
888      String type = "";
889      switch (m_trainingInstances.attribute(i).type()) {
890        case Attribute.NOMINAL:
891          type = " (Nom)";
892          break;
893        case Attribute.NUMERIC:
894          type = " (Num)";
895          break;
896        case Attribute.STRING:
897          type = " (Str)";
898          break;
899        case Attribute.DATE:
900          type = " (Dat)";
901          break;
902        case Attribute.RELATIONAL:
903          type = " (Rel)";
904          break;
905        default:
906          type = " (???)";
907      }
908      classAttNames[i] += type;
909      if (m_trainingInstances.attribute(i).isNumeric()) {
910        xAttNames.addElement("X: "+classAttNames[i]);
911        yAttNames.addElement("Y: "+classAttNames[i]);
912      }
913    }
914
915    m_classAttBox.setModel(new DefaultComboBoxModel(classAttNames));
916    m_xAttBox.setModel(new DefaultComboBoxModel(xAttNames));
917    m_yAttBox.setModel(new DefaultComboBoxModel(yAttNames));
918    if (xAttNames.size() > 1) {
919      m_yAttBox.setSelectedIndex(1);
920    }
921   
922    m_classAttBox.addActionListener(new ActionListener() {
923        public void actionPerformed(ActionEvent e) {
924          configureForClassAttribute();
925        }
926      });
927
928    m_xAttBox.addItemListener(new ItemListener() {
929        public void itemStateChanged(ItemEvent e) {
930          if (e.getStateChange() == ItemEvent.SELECTED) {
931/*          if (xAttNames.size() > 1) {
932              if (m_xAttBox.getSelectedIndex() ==
933                  m_yAttBox.getSelectedIndex()) {
934                m_xAttBox.setSelectedIndex((m_xAttBox.getSelectedIndex() + 1) %
935                                           xAttNames.size());
936              }
937            } */
938            computeBounds();
939            repaint();
940            try{ plotTrainingData(); } catch (Exception ex) {ex.printStackTrace();} //jimmy         
941          }
942        }
943      });
944
945    m_yAttBox.addItemListener(new ItemListener() {
946        public void itemStateChanged(ItemEvent e) {
947          if (e.getStateChange() == ItemEvent.SELECTED) {
948/*          if (xAttNames.size() > 1) {
949              if (m_yAttBox.getSelectedIndex() ==
950                  m_xAttBox.getSelectedIndex()) {
951                m_yAttBox.setSelectedIndex((m_yAttBox.getSelectedIndex() + 1) %
952                                           xAttNames.size());
953              }
954            } */
955            computeBounds();
956            repaint();
957            try{ plotTrainingData(); } catch (Exception ex) {ex.printStackTrace();}
958          }
959        }
960      });
961   
962    if (classAttNames.length > 0)
963      m_classAttBox.setSelectedIndex(classAttNames.length - 1); //select last attribute as class by default.  -jimmy
964     
965    //set up the add points selector combo box
966    setUpClassValueSelectorCB();
967   
968    configureForClassAttribute();
969   
970    m_classPanel.setCindex(m_classAttBox.getSelectedIndex());
971    plotTrainingData();     
972    computeBounds();
973    revalidate();
974    repaint();
975   
976    if (getTopLevelAncestor() instanceof java.awt.Window) {
977      ((java.awt.Window)getTopLevelAncestor()).pack();
978    }
979  }
980 
981  /** Set up the combo box that chooses which class values to use when adding data points.
982  */
983  private void setUpClassValueSelectorCB() {
984    m_classValueSelector.removeAllItems();
985    int classAttribute = m_classAttBox.getSelectedIndex();
986    //System.err.println(m_trainingInstances.numClasses() + " classes");
987    m_trainingInstances.setClassIndex(classAttribute);
988    if (m_trainingInstances.attribute(classAttribute).isNominal()) {
989        m_classValueSelector.setEditable(false);
990        for (int i = 0; i < /*m_trainingInstances.numDistinctValues(classAttribute)*/m_trainingInstances.numClasses(); i++)
991                m_classValueSelector.insertItemAt(m_trainingInstances.attribute(classAttribute).value(i) , i);
992        m_classValueSelector.setSelectedIndex(0);
993    }
994    else {
995        m_classValueSelector.setEditable(true);
996    }
997  }
998 
999  /**
1000   * Set up the class values combo boxes
1001   */
1002  private void configureForClassAttribute() {
1003    int classIndex = m_classAttBox.getSelectedIndex();
1004    if (classIndex >= 0) {
1005      // see if this is a nominal attribute
1006      if (!m_trainingInstances.attribute(classIndex).isNominal() || m_classifier == null) {
1007        m_startBut.setEnabled(false);
1008      } else {
1009        m_startBut.setEnabled(true);
1010      }
1011      // set up class colours
1012        FastVector colors = new FastVector();
1013        if (!m_trainingInstances.attribute(m_classAttBox.getSelectedIndex()).isNominal()) //this if by jimmy
1014        {
1015                for (int i = 0; i < BoundaryPanel.DEFAULT_COLORS.length; i++)
1016                        colors.addElement(BoundaryPanel.DEFAULT_COLORS[i]);
1017        }
1018        else {
1019                for (int i = 0; i < 
1020                m_trainingInstances.attribute(classIndex).numValues(); i++) {
1021                        colors.addElement(BoundaryPanel.
1022                                DEFAULT_COLORS[i % BoundaryPanel.DEFAULT_COLORS.length]);
1023//                      m_classPanel.setColours(colors);         
1024//                      m_boundaryPanel.setColors(colors);
1025                }
1026        }
1027        m_classPanel.setColours(colors); //jimmy
1028        m_boundaryPanel.setColors(colors);
1029   }
1030  }
1031 
1032   
1033  /**
1034   * Queries the user for a file to load instances from, then loads the
1035   * instances in a background process. This is done in the IO
1036   * thread, and an error message is popped up if the IO thread is busy.
1037   */
1038  public void setInstancesFromFileQ() {
1039   
1040//     if (m_IOThread == null) {
1041      int returnVal = m_FileChooser.showOpenDialog(this);
1042      if (returnVal == JFileChooser.APPROVE_OPTION) {
1043        File selected = m_FileChooser.getSelectedFile();
1044       
1045        try
1046        {
1047        java.io.Reader r = new java.io.BufferedReader(
1048                                new java.io.FileReader(selected));
1049        Instances i = new Instances(r);
1050        setInstances(i);
1051       
1052        //dataFileLabel.setText(selected.getName());
1053        dataFileLabel.setText(i.relationName());
1054        } catch (Exception e)
1055        {
1056                JOptionPane.showMessageDialog(this,"Can't load at this time,\n"
1057                                    + "currently busy with other IO",
1058                                    "Load Instances",
1059                                    JOptionPane.WARNING_MESSAGE);
1060                    e.printStackTrace();
1061       
1062        }
1063      }
1064  }
1065 
1066  /** Sets up the BoundaryPanel object so that it is ready for plotting.
1067   * @return an error code:<br/>
1068   *            0 - SUCCESS<br/>
1069   *            1 - ERROR - Kernel bandwidth < 0<br/>
1070   *            2 - ERROR - Kernel bandwidth >= number of training instances.
1071   */
1072  public int setUpBoundaryPanel() throws Exception {
1073        int returner = 0; //OK code.
1074        int tempSamples = m_numberOfSamplesFromEachRegion;
1075                try {
1076                  tempSamples = 
1077                    Integer.parseInt(m_regionSamplesText.getText().trim());
1078                } catch (Exception ex) {
1079                  m_regionSamplesText.setText(""+tempSamples);
1080                }
1081                m_numberOfSamplesFromEachRegion = tempSamples;
1082                m_boundaryPanel.
1083                  setNumSamplesPerRegion(tempSamples);
1084
1085                tempSamples = m_generatorSamplesBase;
1086                try {
1087                  tempSamples = 
1088                    Integer.parseInt(m_generatorSamplesText.getText().trim());
1089                } catch (Exception ex) {
1090                  m_generatorSamplesText.setText(""+tempSamples);
1091                }
1092                m_generatorSamplesBase = tempSamples;
1093                m_boundaryPanel.setGeneratorSamplesBase((double)tempSamples);
1094
1095                tempSamples = m_kernelBandwidth;
1096                try {
1097                  tempSamples = 
1098                    Integer.parseInt(m_kernelBandwidthText.getText().trim());
1099                } catch (Exception ex) {
1100                  m_kernelBandwidthText.setText(""+tempSamples);
1101                }
1102                m_kernelBandwidth = tempSamples;
1103                m_dataGenerator.setKernelBandwidth(tempSamples);
1104               
1105                if (m_kernelBandwidth < 0)      returner = 1;
1106                if (m_kernelBandwidth >= m_trainingInstances.numInstances())    returner = 2;
1107
1108                m_trainingInstances.
1109                  setClassIndex(m_classAttBox.getSelectedIndex());
1110                m_boundaryPanel.setClassifier(m_classifier);
1111                m_boundaryPanel.setTrainingData(m_trainingInstances);
1112                m_boundaryPanel.setXAttribute(m_xIndex);
1113                m_boundaryPanel.setYAttribute(m_yIndex);
1114                m_boundaryPanel.
1115                  setPlotTrainingData(m_plotTrainingData.isSelected());
1116
1117        return returner;
1118  }
1119 
1120  /** Plots the training data on-screen.  Also does all of the setup required
1121   *  for this to work.
1122  */
1123  public void plotTrainingData() throws Exception {
1124        m_boundaryPanel.initialize();
1125        setUpBoundaryPanel();
1126        computeBounds();
1127        m_boundaryPanel.plotTrainingData();
1128  }
1129 
1130  /** Stops the plotting thread.
1131  */
1132  public void stopPlotting() {
1133        m_boundaryPanel.stopPlotting();
1134  }
1135 
1136  /**
1137   * Sets whether System.exit gets called when no more windows are open.
1138   *
1139   * @param value       if TRUE then a System.exit call is ossued after the
1140   *                    last window gets closed.
1141   */
1142  public static void setExitIfNoWindowsOpen(boolean value) {
1143    m_ExitIfNoWindowsOpen = value;
1144  }
1145 
1146  /**
1147   * Gets whether System.exit gets called after the last window gets closed
1148   *
1149   * @return            TRUE if System.exit gets called after last window
1150   *                    got closed.
1151   */
1152  public static boolean getExitIfNoWindowsOpen() {
1153    return m_ExitIfNoWindowsOpen;
1154  }
1155 
1156  /** Creates a new GUI window with all of the BoundaryVisualizer trappings,
1157   *  @param classifier The classifier to use in the new window.  May be null.
1158   *  @param instances  The dataset to visualize on in the new window.  May be null.
1159   */
1160  public static void createNewVisualizerWindow(Classifier classifier, Instances instances) throws Exception {
1161      m_WindowCount++;
1162 
1163      final javax.swing.JFrame jf = 
1164        new javax.swing.JFrame("Weka classification boundary visualizer");
1165      jf.getContentPane().setLayout(new BorderLayout());
1166      final BoundaryVisualizer bv = new BoundaryVisualizer();
1167      jf.getContentPane().add(bv, BorderLayout.CENTER);
1168      jf.setSize(bv.getMinimumSize());
1169      jf.addWindowListener(new java.awt.event.WindowAdapter() {
1170          public void windowClosing(java.awt.event.WindowEvent e) {
1171            m_WindowCount--;
1172            bv.stopPlotting();
1173            jf.dispose();
1174            if ((m_WindowCount == 0) && m_ExitIfNoWindowsOpen) {
1175                System.exit(0);
1176            }
1177          }
1178        });
1179
1180      jf.pack();
1181      jf.setVisible(true);
1182      jf.setResizable(false);
1183     
1184      if (classifier == null)
1185        bv.setClassifier(null);
1186      else {
1187        bv.setClassifier(classifier);
1188        bv.m_classifierEditor.setValue(classifier);
1189      }
1190     
1191      if (instances == null)
1192        bv.setInstances(null);
1193      else
1194      {
1195        bv.setInstances(instances);
1196       
1197        try{
1198                bv.dataFileLabel.setText(instances.relationName());
1199                bv.plotTrainingData();
1200                bv.m_classPanel.setCindex(bv.m_classAttBox.getSelectedIndex());
1201                bv.repaint(0,0,0,bv.getWidth(), bv.getHeight());
1202        } catch (Exception ex) {}
1203      }
1204 
1205  }
1206
1207  /**
1208   * Main method for testing this class
1209   *
1210   * @param args a <code>String[]</code> value
1211   */
1212  public static void main(String [] args) {
1213    weka.core.logging.Logger.log(weka.core.logging.Logger.Level.INFO, "Logging started");
1214    try {
1215        if (args.length < 2) {
1216                createNewVisualizerWindow(null, null);
1217        }
1218        else {
1219                String [] argsR = null;
1220                if (args.length > 2) {
1221                        argsR = new String [args.length-2];
1222                        for (int j = 2; j < args.length; j++) {
1223                        argsR[j-2] = args[j];
1224                        }
1225                }
1226                Classifier c = AbstractClassifier.forName(args[1], argsR);
1227               
1228                System.err.println("Loading instances from : "+args[0]);
1229                java.io.Reader r = new java.io.BufferedReader(
1230                                        new java.io.FileReader(args[0]));
1231                Instances i = new Instances(r);
1232       
1233                createNewVisualizerWindow(c, i);
1234        }
1235     
1236    } catch (Exception ex) {
1237      ex.printStackTrace();
1238    }
1239  }
1240}
1241
1242
Note: See TracBrowser for help on using the repository browser.