~ubuntu-branches/ubuntu/precise/weka/precise

« back to all changes in this revision

Viewing changes to weka/gui/beans/ClassAssigner.java

  • Committer: Bazaar Package Importer
  • Author(s): Soeren Sonnenburg
  • Date: 2008-02-24 09:18:45 UTC
  • Revision ID: james.westby@ubuntu.com-20080224091845-1l8zy6fm6xipbzsr
Tags: upstream-3.5.7+tut1
ImportĀ upstreamĀ versionĀ 3.5.7+tut1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
23
package weka.gui.beans;
 
24
 
 
25
import weka.core.Instances;
 
26
 
 
27
import java.awt.BorderLayout;
 
28
import java.beans.EventSetDescriptor;
 
29
import java.io.Serializable;
 
30
import java.util.Vector;
 
31
 
 
32
import javax.swing.JPanel;
 
33
 
 
34
/**
 
35
 * Bean that assigns a class attribute to a data set.
 
36
 *
 
37
 * @author Mark Hall
 
38
 * @version $Revision: 1.13 $
 
39
 */
 
40
public 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
   * Tool tip text for this property
 
91
   *
 
92
   * @return a <code>String</code> value
 
93
   */
 
94
  public String classColumnTipText() {
 
95
    return "Specify the number of the column that contains the class attribute";
 
96
  }
 
97
 
 
98
  /**
 
99
   * Returns the structure of the incoming instances (if any)
 
100
   *
 
101
   * @return an <code>Instances</code> value
 
102
   */
 
103
  public Instances getConnectedFormat() {
 
104
    return m_connectedFormat;
 
105
  }
 
106
 
 
107
  public void setClassColumn(String col) {
 
108
    m_classColumn = col;
 
109
    if (m_connectedFormat != null) {
 
110
      assignClass(m_connectedFormat);
 
111
    }
 
112
  }
 
113
 
 
114
  public String getClassColumn() {
 
115
    return m_classColumn;
 
116
  }
 
117
 
 
118
  public void acceptDataSet(DataSetEvent e) {
 
119
    Instances dataSet = e.getDataSet();
 
120
    assignClass(dataSet);
 
121
    notifyDataListeners(e);
 
122
    if (e.isStructureOnly()) {
 
123
      m_connectedFormat = e.getDataSet();
 
124
      // tell any listening customizers (or other
 
125
      notifyDataFormatListeners();
 
126
    }
 
127
  }
 
128
 
 
129
  public void acceptTrainingSet(TrainingSetEvent e) {
 
130
    Instances trainingSet = e.getTrainingSet();
 
131
    assignClass(trainingSet);
 
132
    notifyTrainingListeners(e);
 
133
  }
 
134
 
 
135
  public void acceptTestSet(TestSetEvent e) {
 
136
    Instances testSet = e.getTestSet();
 
137
    assignClass(testSet);
 
138
    notifyTestListeners(e);
 
139
  }
 
140
 
 
141
  public void acceptInstance(InstanceEvent e) {
 
142
    if (e.getStatus() == InstanceEvent.FORMAT_AVAILABLE) {
 
143
      //      Instances dataSet = e.getInstance().dataset();
 
144
      m_connectedFormat = e.getStructure();
 
145
      
 
146
      //      System.err.println("Assigning class column...");
 
147
      assignClass(m_connectedFormat);
 
148
      notifyInstanceListeners(e);
 
149
 
 
150
      // tell any listening customizers (or other interested parties)
 
151
      System.err.println("Notifying customizer...");
 
152
      notifyDataFormatListeners();
 
153
    } else {
 
154
      //      Instances dataSet = e.getInstance().dataset();
 
155
      //      assignClass(dataSet);
 
156
      notifyInstanceListeners(e);
 
157
    }
 
158
  }
 
159
 
 
160
  private void assignClass(Instances dataSet) {
 
161
    int classCol = -1;
 
162
    if (m_classColumn.toLowerCase().compareTo("last") == 0) {
 
163
      dataSet.setClassIndex(dataSet.numAttributes()-1);
 
164
    } else if (m_classColumn.toLowerCase().compareTo("first") == 0) {
 
165
      dataSet.setClassIndex(0);
 
166
    } else {
 
167
      classCol = Integer.parseInt(m_classColumn) - 1;
 
168
      if (/*classCol < 0 ||*/ classCol > dataSet.numAttributes()-1) {
 
169
        if (m_logger != null) {
 
170
          m_logger.logMessage("Class column outside range of data "
 
171
                              +"(ClassAssigner)");
 
172
        }
 
173
      } else {
 
174
        dataSet.setClassIndex(classCol);
 
175
      }
 
176
    }
 
177
  }
 
178
 
 
179
  protected void notifyTestListeners(TestSetEvent tse) {
 
180
    Vector l;
 
181
    synchronized (this) {
 
182
      l = (Vector)m_testListeners.clone();
 
183
    }
 
184
    if (l.size() > 0) {
 
185
      for(int i = 0; i < l.size(); i++) {
 
186
        System.err.println("Notifying test listeners "
 
187
                           +"(ClassAssigner)");
 
188
        ((TestSetListener)l.elementAt(i)).acceptTestSet(tse);
 
189
      }
 
190
    }
 
191
  }
 
192
 
 
193
  protected void notifyTrainingListeners(TrainingSetEvent tse) {
 
194
    Vector l;
 
195
    synchronized (this) {
 
196
      l = (Vector)m_trainingListeners.clone();
 
197
    }
 
198
    if (l.size() > 0) {
 
199
      for(int i = 0; i < l.size(); i++) {
 
200
        System.err.println("Notifying training listeners "
 
201
                           +"(ClassAssigner)");
 
202
        ((TrainingSetListener)l.elementAt(i)).acceptTrainingSet(tse);
 
203
      }
 
204
    }
 
205
  }
 
206
 
 
207
  protected void notifyDataListeners(DataSetEvent tse) {
 
208
    Vector l;
 
209
    synchronized (this) {
 
210
      l = (Vector)m_dataListeners.clone();
 
211
    }
 
212
    if (l.size() > 0) {
 
213
      for(int i = 0; i < l.size(); i++) {
 
214
        System.err.println("Notifying data listeners "
 
215
                           +"(ClassAssigner)");
 
216
        ((DataSourceListener)l.elementAt(i)).acceptDataSet(tse);
 
217
      }
 
218
    }
 
219
  }
 
220
 
 
221
  protected void notifyInstanceListeners(InstanceEvent tse) {
 
222
    Vector l;
 
223
    synchronized (this) {
 
224
      l = (Vector)m_instanceListeners.clone();
 
225
    }
 
226
    if (l.size() > 0) {
 
227
      for(int i = 0; i < l.size(); i++) {
 
228
        //      System.err.println("Notifying instance listeners "
 
229
        //                         +"(ClassAssigner)");
 
230
        
 
231
        ((InstanceListener)l.elementAt(i)).acceptInstance(tse);
 
232
      }
 
233
    }
 
234
  }
 
235
 
 
236
  protected void notifyDataFormatListeners() {
 
237
    Vector l;
 
238
    synchronized (this) {
 
239
      l = (Vector)m_dataFormatListeners.clone();
 
240
    }
 
241
    if (l.size() > 0) {
 
242
      DataSetEvent dse = new DataSetEvent(this, m_connectedFormat);
 
243
      for(int i = 0; i < l.size(); i++) {
 
244
        //      System.err.println("Notifying instance listeners "
 
245
        //                         +"(ClassAssigner)");
 
246
        ((DataFormatListener)l.elementAt(i)).newDataFormat(dse);
 
247
      }
 
248
    }
 
249
  }
 
250
 
 
251
  public synchronized void addInstanceListener(InstanceListener tsl) {
 
252
    m_instanceListeners.addElement(tsl);
 
253
    if (m_connectedFormat != null) {
 
254
      InstanceEvent e = new InstanceEvent(this, m_connectedFormat);
 
255
      tsl.acceptInstance(e);
 
256
    }
 
257
  }
 
258
 
 
259
  public synchronized void removeInstanceListener(InstanceListener tsl) {
 
260
    m_instanceListeners.removeElement(tsl);
 
261
  }
 
262
 
 
263
  public synchronized void addDataSourceListener(DataSourceListener tsl) {
 
264
    m_dataListeners.addElement(tsl);
 
265
    // pass on any format that we might know about
 
266
    if (m_connectedFormat != null) {
 
267
      DataSetEvent e = new DataSetEvent(this, m_connectedFormat);
 
268
      tsl.acceptDataSet(e);
 
269
    }
 
270
  }
 
271
 
 
272
  public synchronized void removeDataSourceListener(DataSourceListener tsl) {
 
273
    m_dataListeners.removeElement(tsl);
 
274
  }
 
275
 
 
276
  public synchronized void addTrainingSetListener(TrainingSetListener tsl) {
 
277
    m_trainingListeners.addElement(tsl);
 
278
    // pass on any format that we might know about
 
279
    if (m_connectedFormat != null) {
 
280
      TrainingSetEvent e = new TrainingSetEvent(this, m_connectedFormat);
 
281
      tsl.acceptTrainingSet(e);
 
282
    }
 
283
  }
 
284
 
 
285
  public synchronized void removeTrainingSetListener(TrainingSetListener tsl) {
 
286
    m_trainingListeners.removeElement(tsl);
 
287
  }
 
288
 
 
289
  public synchronized void addTestSetListener(TestSetListener tsl) {
 
290
    m_testListeners.addElement(tsl);
 
291
    // pass on any format that we might know about
 
292
    if (m_connectedFormat != null) {
 
293
      TestSetEvent e = new TestSetEvent(this, m_connectedFormat);
 
294
      tsl.acceptTestSet(e);
 
295
    }
 
296
  }
 
297
 
 
298
  public synchronized void removeTestSetListener(TestSetListener tsl) {
 
299
    m_testListeners.removeElement(tsl);
 
300
  }
 
301
 
 
302
  public synchronized void addDataFormatListener(DataFormatListener dfl) {
 
303
    m_dataFormatListeners.addElement(dfl);
 
304
  }
 
305
 
 
306
  public synchronized void removeDataFormatListener(DataFormatListener dfl) {
 
307
    m_dataFormatListeners.removeElement(dfl);
 
308
  }
 
309
 
 
310
  public void setVisual(BeanVisual newVisual) {
 
311
    m_visual = newVisual;
 
312
  }
 
313
 
 
314
  public BeanVisual getVisual() {
 
315
    return m_visual;
 
316
  }
 
317
  
 
318
  public void useDefaultVisual() {
 
319
    m_visual.loadIcons(BeanVisual.ICON_PATH+"ClassAssigner.gif",
 
320
                       BeanVisual.ICON_PATH+"ClassAssigner_animated.gif");
 
321
  }
 
322
 
 
323
  /**
 
324
   * Returns true if, at this time, 
 
325
   * the object will accept a connection according to the supplied
 
326
   * event name
 
327
   *
 
328
   * @param eventName the event
 
329
   * @return true if the object will accept a connection
 
330
   */
 
331
  public boolean connectionAllowed(String eventName) {
 
332
    if (eventName.compareTo("trainingSet") == 0 && 
 
333
        (m_trainingProvider != null || m_dataProvider != null ||
 
334
         m_instanceProvider != null)) { 
 
335
      return false;
 
336
    }
 
337
    
 
338
    if (eventName.compareTo("testSet") == 0 && 
 
339
        m_testProvider != null) { 
 
340
      return false;
 
341
    }
 
342
 
 
343
     if (eventName.compareTo("instance") == 0 &&
 
344
        m_instanceProvider != null || m_trainingProvider != null ||
 
345
         m_dataProvider != null) {
 
346
       return false;
 
347
     } 
 
348
    return true;
 
349
  }
 
350
 
 
351
  /**
 
352
   * Returns true if, at this time, 
 
353
   * the object will accept a connection according to the supplied
 
354
   * EventSetDescriptor
 
355
   *
 
356
   * @param esd the EventSetDescriptor
 
357
   * @return true if the object will accept a connection
 
358
   */
 
359
  public boolean connectionAllowed(EventSetDescriptor esd) {
 
360
    return connectionAllowed(esd.getName());
 
361
  }
 
362
 
 
363
  /**
 
364
   * Notify this object that it has been registered as a listener with
 
365
   * a source with respect to the supplied event name
 
366
   *
 
367
   * @param eventName the event
 
368
   * @param source the source with which this object has been registered as
 
369
   * a listener
 
370
   */
 
371
  public synchronized void connectionNotification(String eventName,
 
372
                                                  Object source) {
 
373
    if (connectionAllowed(eventName)) {
 
374
      if (eventName.compareTo("trainingSet") == 0) {
 
375
        m_trainingProvider = source;
 
376
      } else if (eventName.compareTo("testSet") == 0) {
 
377
        m_testProvider = source;
 
378
      } else if (eventName.compareTo("dataSet") == 0) {
 
379
        m_dataProvider = source;
 
380
      } else if (eventName.compareTo("instance") == 0) {
 
381
        m_instanceProvider = source;
 
382
      }
 
383
    }
 
384
  }
 
385
 
 
386
  /**
 
387
   * Notify this object that it has been deregistered as a listener with
 
388
   * a source with respect to the supplied event name
 
389
   *
 
390
   * @param eventName the event
 
391
   * @param source the source with which this object has been registered as
 
392
   * a listener
 
393
   */
 
394
  public synchronized void disconnectionNotification(String eventName,
 
395
                                                     Object source) {
 
396
 
 
397
    if (eventName.compareTo("trainingSet") == 0) {
 
398
      if (m_trainingProvider == source) {
 
399
        m_trainingProvider = null;
 
400
      }
 
401
    }
 
402
    if (eventName.compareTo("testSet") == 0) {
 
403
      if (m_testProvider == source) {
 
404
        m_testProvider = null;
 
405
      }
 
406
    }
 
407
    if (eventName.compareTo("dataSet") == 0) {
 
408
      if (m_dataProvider == source) {
 
409
        m_dataProvider = null;
 
410
      }
 
411
    }
 
412
 
 
413
    if (eventName.compareTo("instance") == 0) {
 
414
      if (m_instanceProvider == source) {
 
415
        m_instanceProvider = null;
 
416
      }
 
417
    }
 
418
  }
 
419
  
 
420
  public void setLog(weka.gui.Logger logger) {
 
421
    m_logger = logger;
 
422
  }
 
423
 
 
424
  public void stop() {
 
425
    // nothing to do
 
426
  }
 
427
  
 
428
  /**
 
429
   * Returns true, if at the current time, the named event could
 
430
   * be generated. Assumes that the supplied event name is
 
431
   * an event that could be generated by this bean
 
432
   *
 
433
   * @param eventName the name of the event in question
 
434
   * @return true if the named event could be generated at this point in
 
435
   * time
 
436
   */
 
437
  public boolean eventGeneratable(String eventName) {
 
438
    if (eventName.compareTo("trainingSet") == 0) { 
 
439
      if (m_trainingProvider == null) {
 
440
        return false;
 
441
      } else {
 
442
        if (m_trainingProvider instanceof EventConstraints) {
 
443
          if (!((EventConstraints)m_trainingProvider).
 
444
              eventGeneratable("trainingSet")) {
 
445
            return false;
 
446
          }
 
447
        }
 
448
      }
 
449
    }
 
450
 
 
451
    if (eventName.compareTo("dataSet") == 0) { 
 
452
      if (m_dataProvider == null) {
 
453
        if (m_instanceProvider == null) {
 
454
          m_connectedFormat = null;
 
455
          notifyDataFormatListeners();
 
456
        }
 
457
        return false;
 
458
      } else {
 
459
        if (m_dataProvider instanceof EventConstraints) {
 
460
          if (!((EventConstraints)m_dataProvider).
 
461
              eventGeneratable("dataSet")) {
 
462
            m_connectedFormat = null;
 
463
            notifyDataFormatListeners();
 
464
            return false;
 
465
          }
 
466
        }
 
467
      }
 
468
    }
 
469
 
 
470
    if (eventName.compareTo("instance") == 0) { 
 
471
      if (m_instanceProvider == null) {
 
472
        if (m_dataProvider == null) {
 
473
          m_connectedFormat = null;
 
474
          notifyDataFormatListeners();
 
475
        }
 
476
        return false;
 
477
      } else {
 
478
        if (m_instanceProvider instanceof EventConstraints) {
 
479
          if (!((EventConstraints)m_instanceProvider).
 
480
              eventGeneratable("instance")) {
 
481
            m_connectedFormat = null;
 
482
            notifyDataFormatListeners();
 
483
            return false;
 
484
          }
 
485
        }
 
486
      }
 
487
    }
 
488
 
 
489
    if (eventName.compareTo("testSet") == 0) {
 
490
      if (m_testProvider == null) {
 
491
        return false;
 
492
      } else {
 
493
        if (m_testProvider instanceof EventConstraints) {
 
494
          if (!((EventConstraints)m_testProvider).
 
495
              eventGeneratable("testSet")) {
 
496
            return false;
 
497
          }
 
498
        }
 
499
      }
 
500
    }
 
501
    return true;
 
502
  }
 
503
}