source: src/main/java/weka/gui/beans/ClassAssigner.java @ 11

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

Import di weka.

File size: 15.3 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 *    ClassAssigner.java
19 *    Copyright (C) 2002 University of Waikato, Hamilton, New Zealand
20 *
21 */
22
23package weka.gui.beans;
24
25import weka.core.Instances;
26
27import java.awt.BorderLayout;
28import java.beans.EventSetDescriptor;
29import java.io.Serializable;
30import java.util.Vector;
31
32import javax.swing.JPanel;
33
34/**
35 * Bean that assigns a class attribute to a data set.
36 *
37 * @author Mark Hall
38 * @version $Revision: 5667 $
39 */
40public class ClassAssigner
41  extends JPanel
42  implements Visible, DataSourceListener, TrainingSetListener, TestSetListener,
43             DataSource, TrainingSetProducer, TestSetProducer,
44             BeanCommon, EventConstraints, Serializable,
45             InstanceListener {
46
47  /** for serialization */
48  private static final long serialVersionUID = 4011131665025817924L;
49 
50  private String m_classColumn = "last";
51
52  /** format of instances for current incoming connection (if any) */
53  private Instances m_connectedFormat;
54
55  private Object m_trainingProvider;
56  private Object m_testProvider;
57  private Object m_dataProvider;
58  private Object m_instanceProvider;
59
60  private Vector m_trainingListeners = new Vector();
61  private Vector m_testListeners = new Vector();
62  private Vector m_dataListeners = new Vector();
63  private Vector m_instanceListeners = new Vector();
64
65  private Vector m_dataFormatListeners = new Vector();
66
67  protected transient weka.gui.Logger m_logger = null;
68
69  protected BeanVisual m_visual = 
70    new BeanVisual("ClassAssigner", 
71                   BeanVisual.ICON_PATH+"ClassAssigner.gif",
72                   BeanVisual.ICON_PATH+"ClassAssigner_animated.gif");
73
74  /**
75   * Global info for this bean
76   *
77   * @return a <code>String</code> value
78   */
79  public String globalInfo() {
80    return "Designate which column is to be considered the class column "
81      +"in incoming data.";
82  }
83
84  public ClassAssigner() {
85    setLayout(new BorderLayout());
86    add(m_visual, BorderLayout.CENTER);   
87  }
88
89  /**
90   * Set a custom (descriptive) name for this bean
91   *
92   * @param name the name to use
93   */
94  public void setCustomName(String name) {
95    m_visual.setText(name);
96  }
97
98  /**
99   * Get the custom (descriptive) name for this bean (if one has been set)
100   *
101   * @return the custom name (or the default name)
102   */
103  public String getCustomName() {
104    return m_visual.getText();
105  }
106
107  /**
108   * Tool tip text for this property
109   *
110   * @return a <code>String</code> value
111   */
112  public String classColumnTipText() {
113    return "Specify the number of the column that contains the class attribute";
114  }
115
116  /**
117   * Returns the structure of the incoming instances (if any)
118   *
119   * @return an <code>Instances</code> value
120   */
121  public Instances getConnectedFormat() {
122    return m_connectedFormat;
123  }
124
125  public void setClassColumn(String col) {
126    m_classColumn = col;
127    if (m_connectedFormat != null) {
128      assignClass(m_connectedFormat);
129    }
130  }
131
132  public String getClassColumn() {
133    return m_classColumn;
134  }
135
136  public void acceptDataSet(DataSetEvent e) {
137    Instances dataSet = e.getDataSet();
138    assignClass(dataSet);
139    notifyDataListeners(e);
140    if (e.isStructureOnly()) {
141      m_connectedFormat = e.getDataSet();
142      // tell any listening customizers (or other
143      notifyDataFormatListeners();
144    }
145  }
146
147  public void acceptTrainingSet(TrainingSetEvent e) {
148    Instances trainingSet = e.getTrainingSet();
149    assignClass(trainingSet);
150    notifyTrainingListeners(e);
151   
152    if (e.isStructureOnly()) {
153      m_connectedFormat = e.getTrainingSet();
154      // tell any listening customizers (or other
155      notifyDataFormatListeners();
156    }
157  }
158
159  public void acceptTestSet(TestSetEvent e) {
160    Instances testSet = e.getTestSet();
161    assignClass(testSet);
162    notifyTestListeners(e);
163    if (e.isStructureOnly()) {
164      m_connectedFormat = e.getTestSet();
165      // tell any listening customizers (or other
166      notifyDataFormatListeners();
167    }
168  }
169
170  public void acceptInstance(InstanceEvent e) {
171    if (e.getStatus() == InstanceEvent.FORMAT_AVAILABLE) {
172      //      Instances dataSet = e.getInstance().dataset();
173      m_connectedFormat = e.getStructure();
174     
175      //      System.err.println("Assigning class column...");
176      assignClass(m_connectedFormat);
177      notifyInstanceListeners(e);
178
179      // tell any listening customizers (or other interested parties)
180      System.err.println("Notifying customizer...");
181      notifyDataFormatListeners();
182    } else {
183      //      Instances dataSet = e.getInstance().dataset();
184      //      assignClass(dataSet);
185      notifyInstanceListeners(e);
186    }
187  }
188
189  private void assignClass(Instances dataSet) {
190    int classCol = -1;
191    if (m_classColumn.toLowerCase().compareTo("last") == 0) {
192      dataSet.setClassIndex(dataSet.numAttributes()-1);
193    } else if (m_classColumn.toLowerCase().compareTo("first") == 0) {
194      dataSet.setClassIndex(0);
195    } else {
196      classCol = Integer.parseInt(m_classColumn) - 1;
197      if (/*classCol < 0 ||*/ classCol > dataSet.numAttributes()-1) {
198        if (m_logger != null) {
199          m_logger.logMessage("Class column outside range of data "
200                              +"(ClassAssigner)");
201        }
202      } else {
203        dataSet.setClassIndex(classCol);
204      }
205    }
206  }
207
208  protected void notifyTestListeners(TestSetEvent tse) {
209    Vector l;
210    synchronized (this) {
211      l = (Vector)m_testListeners.clone();
212    }
213    if (l.size() > 0) {
214      for(int i = 0; i < l.size(); i++) {
215        System.err.println("Notifying test listeners "
216                           +"(ClassAssigner)");
217        ((TestSetListener)l.elementAt(i)).acceptTestSet(tse);
218      }
219    }
220  }
221
222  protected void notifyTrainingListeners(TrainingSetEvent tse) {
223    Vector l;
224    synchronized (this) {
225      l = (Vector)m_trainingListeners.clone();
226    }
227    if (l.size() > 0) {
228      for(int i = 0; i < l.size(); i++) {
229        System.err.println("Notifying training listeners "
230                           +"(ClassAssigner)");
231        ((TrainingSetListener)l.elementAt(i)).acceptTrainingSet(tse);
232      }
233    }
234  }
235
236  protected void notifyDataListeners(DataSetEvent tse) {
237    Vector l;
238    synchronized (this) {
239      l = (Vector)m_dataListeners.clone();
240    }
241    if (l.size() > 0) {
242      for(int i = 0; i < l.size(); i++) {
243        System.err.println("Notifying data listeners "
244                           +"(ClassAssigner)");
245        ((DataSourceListener)l.elementAt(i)).acceptDataSet(tse);
246      }
247    }
248  }
249
250  protected void notifyInstanceListeners(InstanceEvent tse) {
251    Vector l;
252    synchronized (this) {
253      l = (Vector)m_instanceListeners.clone();
254    }
255    if (l.size() > 0) {
256      for(int i = 0; i < l.size(); i++) {
257        //      System.err.println("Notifying instance listeners "
258        //                         +"(ClassAssigner)");
259       
260        ((InstanceListener)l.elementAt(i)).acceptInstance(tse);
261      }
262    }
263  }
264
265  protected void notifyDataFormatListeners() {
266    Vector l;
267    synchronized (this) {
268      l = (Vector)m_dataFormatListeners.clone();
269    }
270    if (l.size() > 0) {
271      DataSetEvent dse = new DataSetEvent(this, m_connectedFormat);
272      for(int i = 0; i < l.size(); i++) {
273        //      System.err.println("Notifying instance listeners "
274        //                         +"(ClassAssigner)");
275        ((DataFormatListener)l.elementAt(i)).newDataFormat(dse);
276      }
277    }
278  }
279
280  public synchronized void addInstanceListener(InstanceListener tsl) {
281    m_instanceListeners.addElement(tsl);
282    if (m_connectedFormat != null) {
283      InstanceEvent e = new InstanceEvent(this, m_connectedFormat);
284      tsl.acceptInstance(e);
285    }
286  }
287
288  public synchronized void removeInstanceListener(InstanceListener tsl) {
289    m_instanceListeners.removeElement(tsl);
290  }
291
292  public synchronized void addDataSourceListener(DataSourceListener tsl) {
293    m_dataListeners.addElement(tsl);
294    // pass on any format that we might know about
295    if (m_connectedFormat != null) {
296      DataSetEvent e = new DataSetEvent(this, m_connectedFormat);
297      tsl.acceptDataSet(e);
298    }
299  }
300
301  public synchronized void removeDataSourceListener(DataSourceListener tsl) {
302    m_dataListeners.removeElement(tsl);
303  }
304
305  public synchronized void addTrainingSetListener(TrainingSetListener tsl) {
306    m_trainingListeners.addElement(tsl);
307    // pass on any format that we might know about
308    if (m_connectedFormat != null) {
309      TrainingSetEvent e = new TrainingSetEvent(this, m_connectedFormat);
310      tsl.acceptTrainingSet(e);
311    }
312  }
313
314  public synchronized void removeTrainingSetListener(TrainingSetListener tsl) {
315    m_trainingListeners.removeElement(tsl);
316  }
317
318  public synchronized void addTestSetListener(TestSetListener tsl) {
319    m_testListeners.addElement(tsl);
320    // pass on any format that we might know about
321    if (m_connectedFormat != null) {
322      TestSetEvent e = new TestSetEvent(this, m_connectedFormat);
323      tsl.acceptTestSet(e);
324    }
325  }
326
327  public synchronized void removeTestSetListener(TestSetListener tsl) {
328    m_testListeners.removeElement(tsl);
329  }
330
331  public synchronized void addDataFormatListener(DataFormatListener dfl) {
332    m_dataFormatListeners.addElement(dfl);
333  }
334
335  public synchronized void removeDataFormatListener(DataFormatListener dfl) {
336    m_dataFormatListeners.removeElement(dfl);
337  }
338
339  public void setVisual(BeanVisual newVisual) {
340    m_visual = newVisual;
341  }
342
343  public BeanVisual getVisual() {
344    return m_visual;
345  }
346 
347  public void useDefaultVisual() {
348    m_visual.loadIcons(BeanVisual.ICON_PATH+"ClassAssigner.gif",
349                       BeanVisual.ICON_PATH+"ClassAssigner_animated.gif");
350  }
351
352  /**
353   * Returns true if, at this time,
354   * the object will accept a connection according to the supplied
355   * event name
356   *
357   * @param eventName the event
358   * @return true if the object will accept a connection
359   */
360  public boolean connectionAllowed(String eventName) {
361    if (eventName.compareTo("trainingSet") == 0 && 
362        (m_trainingProvider != null || m_dataProvider != null ||
363         m_instanceProvider != null)) { 
364      return false;
365    }
366   
367    if (eventName.compareTo("testSet") == 0 && 
368        m_testProvider != null) { 
369      return false;
370    }
371
372     if (eventName.compareTo("instance") == 0 &&
373        m_instanceProvider != null || m_trainingProvider != null ||
374         m_dataProvider != null) {
375       return false;
376     } 
377    return true;
378  }
379
380  /**
381   * Returns true if, at this time,
382   * the object will accept a connection according to the supplied
383   * EventSetDescriptor
384   *
385   * @param esd the EventSetDescriptor
386   * @return true if the object will accept a connection
387   */
388  public boolean connectionAllowed(EventSetDescriptor esd) {
389    return connectionAllowed(esd.getName());
390  }
391
392  /**
393   * Notify this object that it has been registered as a listener with
394   * a source with respect to the supplied event name
395   *
396   * @param eventName the event
397   * @param source the source with which this object has been registered as
398   * a listener
399   */
400  public synchronized void connectionNotification(String eventName,
401                                                  Object source) {
402    if (connectionAllowed(eventName)) {
403      if (eventName.compareTo("trainingSet") == 0) {
404        m_trainingProvider = source;
405      } else if (eventName.compareTo("testSet") == 0) {
406        m_testProvider = source;
407      } else if (eventName.compareTo("dataSet") == 0) {
408        m_dataProvider = source;
409      } else if (eventName.compareTo("instance") == 0) {
410        m_instanceProvider = source;
411      }
412    }
413  }
414
415  /**
416   * Notify this object that it has been deregistered as a listener with
417   * a source with respect to the supplied event name
418   *
419   * @param eventName the event
420   * @param source the source with which this object has been registered as
421   * a listener
422   */
423  public synchronized void disconnectionNotification(String eventName,
424                                                     Object source) {
425
426    if (eventName.compareTo("trainingSet") == 0) {
427      if (m_trainingProvider == source) {
428        m_trainingProvider = null;
429      }
430    }
431    if (eventName.compareTo("testSet") == 0) {
432      if (m_testProvider == source) {
433        m_testProvider = null;
434      }
435    }
436    if (eventName.compareTo("dataSet") == 0) {
437      if (m_dataProvider == source) {
438        m_dataProvider = null;
439      }
440    }
441
442    if (eventName.compareTo("instance") == 0) {
443      if (m_instanceProvider == source) {
444        m_instanceProvider = null;
445      }
446    }
447  }
448 
449  public void setLog(weka.gui.Logger logger) {
450    m_logger = logger;
451  }
452
453  public void stop() {
454    // Pass on to upstream beans
455    if (m_trainingProvider != null && m_trainingProvider instanceof BeanCommon) {
456      ((BeanCommon)m_trainingProvider).stop();
457    }
458   
459    if (m_testProvider != null && m_testProvider instanceof BeanCommon) {
460      ((BeanCommon)m_testProvider).stop();
461    }
462   
463    if (m_dataProvider != null && m_dataProvider instanceof BeanCommon) {
464      ((BeanCommon)m_dataProvider).stop();
465    }
466   
467    if (m_instanceProvider != null && m_instanceProvider instanceof BeanCommon) {
468      ((BeanCommon)m_instanceProvider).stop();
469    }
470  }
471 
472  /**
473   * Returns true if. at this time, the bean is busy with some
474   * (i.e. perhaps a worker thread is performing some calculation).
475   *
476   * @return true if the bean is busy.
477   */
478  public boolean isBusy() {
479    return false;
480  }
481 
482  /**
483   * Returns true, if at the current time, the named event could
484   * be generated. Assumes that the supplied event name is
485   * an event that could be generated by this bean
486   *
487   * @param eventName the name of the event in question
488   * @return true if the named event could be generated at this point in
489   * time
490   */
491  public boolean eventGeneratable(String eventName) {
492    if (eventName.compareTo("trainingSet") == 0) { 
493      if (m_trainingProvider == null) {
494        return false;
495      } else {
496        if (m_trainingProvider instanceof EventConstraints) {
497          if (!((EventConstraints)m_trainingProvider).
498              eventGeneratable("trainingSet")) {
499            return false;
500          }
501        }
502      }
503    }
504
505    if (eventName.compareTo("dataSet") == 0) { 
506      if (m_dataProvider == null) {
507        if (m_instanceProvider == null) {
508          m_connectedFormat = null;
509          notifyDataFormatListeners();
510        }
511        return false;
512      } else {
513        if (m_dataProvider instanceof EventConstraints) {
514          if (!((EventConstraints)m_dataProvider).
515              eventGeneratable("dataSet")) {
516            m_connectedFormat = null;
517            notifyDataFormatListeners();
518            return false;
519          }
520        }
521      }
522    }
523
524    if (eventName.compareTo("instance") == 0) { 
525      if (m_instanceProvider == null) {
526        if (m_dataProvider == null) {
527          m_connectedFormat = null;
528          notifyDataFormatListeners();
529        }
530        return false;
531      } else {
532        if (m_instanceProvider instanceof EventConstraints) {
533          if (!((EventConstraints)m_instanceProvider).
534              eventGeneratable("instance")) {
535            m_connectedFormat = null;
536            notifyDataFormatListeners();
537            return false;
538          }
539        }
540      }
541    }
542
543    if (eventName.compareTo("testSet") == 0) {
544      if (m_testProvider == null) {
545        return false;
546      } else {
547        if (m_testProvider instanceof EventConstraints) {
548          if (!((EventConstraints)m_testProvider).
549              eventGeneratable("testSet")) {
550            return false;
551          }
552        }
553      }
554    }
555    return true;
556  }
557}
Note: See TracBrowser for help on using the repository browser.