source: src/main/java/weka/gui/CheckBoxList.java @ 18

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

Import di weka.

File size: 17.9 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 * CheckBoxList.java
19 * Copyright (C) 2006 University of Waikato, Hamilton, New Zealand
20 */
21
22package weka.gui;
23
24import java.awt.Component;
25import java.awt.event.KeyAdapter;
26import java.awt.event.KeyEvent;
27import java.awt.event.MouseAdapter;
28import java.awt.event.MouseEvent;
29import java.util.Vector;
30
31import javax.swing.DefaultListModel;
32import javax.swing.JCheckBox;
33import javax.swing.JList;
34import javax.swing.ListCellRenderer;
35import javax.swing.ListModel;
36
37/**
38 * An extended JList that contains CheckBoxes. If necessary a CheckBoxListItem
39 * wrapper is added around the displayed object in any of the Model methods,
40 * e.g., addElement. For methods returning objects the opposite takes place,
41 * the wrapper is removed and only the payload object is returned.
42 *
43 * @author  fracpete (fracpete at waikato dot ac dot nz)
44 * @version $Revision: 1.3 $
45 */
46public class CheckBoxList
47  extends JList {
48
49  /** for serialization */
50  private static final long serialVersionUID = -4359573373359270258L;
51 
52  /**
53   * represents an item in the CheckBoxListModel
54   *
55   * @author  fracpete (fracpete at waikato dot ac dot nz)
56   * @version $Revision: 1.3 $
57   */
58  protected class CheckBoxListItem {
59   
60    /** whether item is checked or not */
61    private boolean m_Checked = false;
62   
63    /** the actual object */
64    private Object m_Content = null;
65   
66    /**
67     * initializes the item with the given object and initially unchecked
68     *
69     * @param o         the content object
70     */
71    public CheckBoxListItem(Object o) {
72      this(o, false);
73    }
74   
75    /**
76     * initializes the item with the given object and whether it's checked
77     * initially
78     *
79     * @param o         the content object
80     * @param checked   whether the item should be checked initially
81     */
82    public CheckBoxListItem(Object o, boolean checked) {
83      m_Checked = checked;
84      m_Content = o;
85    }
86   
87    /**
88     * returns the content object
89     */
90    public Object getContent() {
91      return m_Content;
92    }
93   
94    /**
95     * sets the checked state of the item
96     */
97    public void setChecked(boolean value) {
98      m_Checked = value;
99    }
100   
101    /**
102     * returns the checked state of the item
103     */
104    public boolean getChecked() {
105      return m_Checked;
106    }
107   
108    /**
109     * returns the string representation of the content object
110     */
111    public String toString() {
112      return m_Content.toString();
113    }
114   
115    /**
116     * returns true if the "payload" objects of the current and the given
117     * CheckBoxListItem are the same.
118     *
119     * @param o         the CheckBoxListItem to check
120     * @throws IllegalArgumentException if the provided object is not a CheckBoxListItem
121     */
122    public boolean equals(Object o) {
123      if (!(o instanceof CheckBoxListItem))
124        throw new IllegalArgumentException("Must be a CheckBoxListItem!");
125     
126      return getContent().equals(((CheckBoxListItem) o).getContent());
127    }
128  }
129 
130  /**
131   * A specialized model.
132   *
133   * @author  fracpete (fracpete at waikato dot ac dot nz)
134   * @version $Revision: 1.3 $
135   */
136  public class CheckBoxListModel
137    extends DefaultListModel {
138
139    /** for serialization */
140    private static final long serialVersionUID = 7772455499540273507L;
141   
142    /**
143     * initializes the model with no data.
144     */
145    public CheckBoxListModel() {
146      super();
147    }
148   
149    /**
150     * Constructs a CheckBoxListModel from an array of objects and then applies
151     * setModel to it.
152     *
153     * @param listData  the data to use
154     */
155    public CheckBoxListModel(Object[] listData) {
156      for (int i = 0; i < listData.length; i++)
157        addElement(listData[i]);
158    }
159   
160    /**
161     * Constructs a CheckBoxListModel from a Vector and then applies setModel
162     * to it.
163     */
164    public CheckBoxListModel(Vector listData) {
165      for (int i = 0; i < listData.size(); i++)
166        addElement(listData.get(i));
167    }
168   
169    /**
170     * Inserts the specified element at the specified position in this list.
171     *
172     * @param index     index at which the specified element is to be inserted
173     * @param element   element to be inserted
174     */
175    public void add(int index, Object element) {
176      if (!(element instanceof CheckBoxListItem))
177        super.add(index, new CheckBoxListItem(element));
178      else
179        super.add(index, element);
180    }
181   
182    /**
183     * Adds the specified component to the end of this list.
184     *
185     * @param obj       the component to be added
186     */
187    public void addElement(Object obj) {
188      if (!(obj instanceof CheckBoxListItem))
189        super.addElement(new CheckBoxListItem(obj));
190      else
191        super.addElement(obj);
192    }
193   
194    /**
195     * Tests whether the specified object is a component in this list.
196     *
197     * @param elem      the element to check
198     * @return          true if the element is in the list
199     */
200    public boolean contains(Object elem) {
201      if (!(elem instanceof CheckBoxListItem))
202        return super.contains(new CheckBoxListItem(elem));
203      else
204        return super.contains(elem);
205    }
206   
207    /**
208     * Copies the components of this list into the specified array.
209     *
210     * @param anArray   the array into which the components get copied
211     * @throws IndexOutOfBoundsException if the array is not big enough
212     */
213    public void copyInto(Object[] anArray) {
214      if (anArray.length < getSize())
215        throw new IndexOutOfBoundsException("Array not big enough!");
216     
217      for (int i = 0; i < getSize(); i++)
218        anArray[i] = ((CheckBoxListItem) getElementAt(i)).getContent();
219    }
220   
221    /**
222     * Returns the component at the specified index. Throws an
223     * ArrayIndexOutOfBoundsException if the index is negative or not less
224     * than the size of the list.
225     *
226     * @param index     an index into this list
227     * @return          the component at the specified index
228     * @throws ArrayIndexOutOfBoundsException
229     */
230    public Object elementAt(int index) {
231      return ((CheckBoxListItem) super.elementAt(index)).getContent();
232    }
233   
234    /**
235     * Returns the first component of this list. Throws a
236     * NoSuchElementException if this vector has no components.
237     *
238     * @return          the first component of this list
239     * @throws NoSuchElementException
240     */
241    public Object firstElement() {
242      return ((CheckBoxListItem) super.firstElement()).getContent();
243    }
244   
245    /**
246     * Returns the element at the specified position in this list.
247     *
248     * @param index of element to return
249     * @throws ArrayIndexOutOfBoundsException
250     */
251    public Object get(int index) {
252      return ((CheckBoxListItem) super.get(index)).getContent();
253    }
254   
255    /**
256     * Returns the component at the specified index.
257     *
258     * @param index     an index into this list
259     * @return          the component at the specified index
260     * @throws ArrayIndexOutOfBoundsException
261     */
262    public Object getElementAt(int index) {
263      return ((CheckBoxListItem) super.getElementAt(index)).getContent();
264    }
265   
266    /**
267     * Searches for the first occurrence of elem.
268     *
269     * @param elem      an object
270     * @return          the index of the first occurrence of the argument in this list;
271     *                  returns -1 if the object is not found
272     */
273    public int indexOf(Object elem) {
274      if (!(elem instanceof CheckBoxListItem))
275        return super.indexOf(new CheckBoxListItem(elem));
276      else
277        return super.indexOf(elem);
278    }
279   
280    /**
281     * Searches for the first occurrence of elem, beginning the search at index.
282     *
283     * @param elem      the desired component
284     * @param index     the index from which to begin searching
285     * @return          the index where the first occurrence of elem  is found after index;
286     *                  returns -1  if the elem is not found in the list
287     */
288    public int indexOf(Object elem, int index) {
289      if (!(elem instanceof CheckBoxListItem))
290        return super.indexOf(new CheckBoxListItem(elem), index);
291      else
292        return super.indexOf(elem, index);
293    }
294   
295    /**
296     * Inserts the specified object as a component in this list at the
297     * specified index.
298     *
299     * @param obj       the component to insert
300     * @param index     where to insert the new component
301     * @throws ArrayIndexOutOfBoundsException
302     */
303    public void insertElementAt(Object obj, int index) {
304      if (!(obj instanceof CheckBoxListItem))
305        super.insertElementAt(new CheckBoxListItem(obj), index);
306      else
307        super.insertElementAt(obj, index);
308    }
309   
310    /**
311     * Returns the last component of the list. Throws a NoSuchElementException
312     * if this vector has no components.
313     *
314     * @return          the last component of the list
315     * @throws NoSuchElementException
316     */
317    public Object lastElement() {
318      return ((CheckBoxListItem) super.lastElement()).getContent();
319    }
320   
321    /**
322     * Returns the index of the last occurrence of elem.
323     *
324     * @param elem      the desired component
325     * @return          the index of the last occurrence of elem  in the list;
326     *                  returns -1 if the object is not found
327     */
328    public int lastIndexOf(Object elem) {
329      if (!(elem instanceof CheckBoxListItem))
330        return super.lastIndexOf(new CheckBoxListItem(elem));
331      else
332        return super.lastIndexOf(elem);
333    }
334   
335    /**
336     * Searches backwards for elem, starting from the specified index,
337     * and returns an index to it.
338     *
339     * @param elem      the desired component
340     * @param index     the index to start searching from
341     * @return          the index of the last occurrence of the elem in this
342     *                  list at position less than index; returns -1 if the
343     *                  object is not found
344     */
345    public int lastIndexOf(Object elem, int index) {
346      if (!(elem instanceof CheckBoxListItem))
347        return super.lastIndexOf(new CheckBoxListItem(elem), index);
348      else
349        return super.lastIndexOf(elem, index);
350    }
351   
352    /**
353     * Removes the element at the specified position in this list. Returns the
354     * element that was removed from the list.
355     *
356     * @param index     the index of the element to removed
357     * @throws ArrayIndexOutOfBoundsException
358     */
359    public Object remove(int index) {
360      return ((CheckBoxListItem) super.remove(index)).getContent();
361    }
362   
363    /**
364     * Removes the first (lowest-indexed) occurrence of the argument from this
365     * list.
366     *
367     * @param obj       the component to be removed
368     * @return          true if the argument was a component of this list;
369     *                  false otherwise
370     */
371    public boolean removeElement(Object obj) {
372      if (!(obj instanceof CheckBoxListItem))
373        return super.removeElement(new CheckBoxListItem(obj));
374      else
375        return super.removeElement(obj);
376    }
377   
378    /**
379     * Replaces the element at the specified position in this list with the
380     * specified element.
381     *
382     * @param index     index of element to replace
383     * @param element   element to be stored at the specified position
384     * @throws ArrayIndexOutOfBoundsException
385     */
386    public Object set(int index, Object element) {
387      if (!(element instanceof CheckBoxListItem))
388        return ((CheckBoxListItem) super.set(index, new CheckBoxListItem(element))).getContent();
389      else
390        return ((CheckBoxListItem) super.set(index, element)).getContent();
391    }
392   
393    /**
394     * Sets the component at the specified index of this list to be the
395     * specified object. The previous component at that position is discarded.
396     *
397     * @param obj       what the component is to be set to
398     * @param index     the specified index
399     * @throws ArrayIndexOutOfBoundsException
400     */
401    public void setElementAt(Object obj, int index) {
402      if (!(obj instanceof CheckBoxListItem))
403        super.setElementAt(new CheckBoxListItem(obj), index);
404      else
405        super.setElementAt(obj, index);
406    }
407   
408    /**
409     * Returns an array containing all of the elements in this list in the
410     * correct order.
411     *
412     * @return          an array containing the elements of the list
413     */
414    public Object[] toArray() {
415      Object[]          result;
416      Object[]          internal;
417      int               i;
418     
419      internal = super.toArray();
420      result   = new Object[internal.length];
421     
422      for (i = 0; i < internal.length; i++)
423        result[i] = ((CheckBoxListItem) internal[i]).getContent();
424     
425      return result;
426    }
427   
428    /**
429     * returns the checked state of the element at the given index
430     *
431     * @param index     the index of the element to return the checked state for
432     * @return          the checked state of the specifed element
433     */
434    public boolean getChecked(int index) {
435      return ((CheckBoxListItem) super.getElementAt(index)).getChecked();
436    }
437   
438    /**
439     * sets the checked state of the element at the given index
440     *
441     * @param index     the index of the element to set the checked state for
442     * @param checked   the new checked state
443     */
444    public void setChecked(int index, boolean checked) {
445      ((CheckBoxListItem) super.getElementAt(index)).setChecked(checked);
446    }
447  }
448 
449  /**
450   * A specialized CellRenderer for the CheckBoxList
451   *
452   * @author  fracpete (fracpete at waikato dot ac dot nz)
453   * @version $Revision: 1.3 $
454   * @see CheckBoxList
455   */
456  public class CheckBoxListRenderer 
457    extends JCheckBox
458    implements ListCellRenderer {
459
460    /** for serialization */
461    private static final long serialVersionUID = 1059591605858524586L;
462 
463    /**
464     * Return a component that has been configured to display the specified
465     * value.
466     *
467     * @param list      The JList we're painting.
468     * @param value     The value returned by list.getModel().getElementAt(index).
469     * @param index     The cells index.
470     * @param isSelected        True if the specified cell was selected.
471     * @param cellHasFocus      True if the specified cell has the focus.
472     * @return          A component whose paint() method will render the
473     *                  specified value.
474     */
475    public Component getListCellRendererComponent(
476        JList list,
477        Object value,
478        int index,
479        boolean isSelected,
480        boolean cellHasFocus) {
481     
482      setText(value.toString());
483      setSelected(((CheckBoxList) list).getChecked(index));
484      setBackground(isSelected ? list.getSelectionBackground() : list.getBackground());
485      setForeground(isSelected ? list.getSelectionForeground() : list.getForeground());
486      setFocusPainted(false);
487     
488      return this;
489    }
490  }
491 
492  /**
493   * initializes the list with an empty CheckBoxListModel
494   */
495  public CheckBoxList() {
496    this(null);
497  }
498 
499  /**
500   * initializes the list with the given CheckBoxListModel
501   *
502   * @param model       the model to initialize with
503   */
504  public CheckBoxList(CheckBoxListModel model) {
505    super();
506   
507    if (model == null)
508      model = this.new CheckBoxListModel();
509   
510    setModel(model);
511    setCellRenderer(new CheckBoxListRenderer());
512   
513    addMouseListener(new MouseAdapter() {
514      public void mousePressed(MouseEvent e) {
515        int index = locationToIndex(e.getPoint());
516       
517        if (index != -1) {
518          setChecked(index, !getChecked(index));
519          repaint();
520        }
521      }
522    });
523   
524    addKeyListener(new KeyAdapter() {
525      public void keyTyped(KeyEvent e) {
526        if ( (e.getKeyChar() == ' ') && (e.getModifiers() == 0) ) {
527          int index = getSelectedIndex();
528          setChecked(index, !getChecked(index));
529          e.consume();
530          repaint();
531        }
532      }
533    });
534  }
535 
536  /**
537   * sets the model - must be an instance of CheckBoxListModel
538   *
539   * @param model                       the model to use
540   * @throws IllegalArgumentException   if the model is not an instance of
541   *                                    CheckBoxListModel
542   * @see CheckBoxListModel
543   */
544  public void setModel(ListModel model) {
545    if (!(model instanceof CheckBoxListModel))
546      throw new IllegalArgumentException("Model must be an instance of CheckBoxListModel!");
547   
548    super.setModel(model);
549  }
550 
551  /**
552   * Constructs a CheckBoxListModel from an array of objects and then applies
553   * setModel to it.
554   *
555   * @param listData    the data to use
556   */
557  public void setListData(Object[] listData) {
558    setModel(new CheckBoxListModel(listData));
559  }
560 
561  /**
562   * Constructs a CheckBoxListModel from a Vector and then applies setModel
563   * to it.
564   */
565  public void setListData(Vector listData) {
566    setModel(new CheckBoxListModel(listData));
567  }
568 
569  /**
570   * returns the checked state of the element at the given index
571   *
572   * @param index       the index of the element to return the checked state for
573   * @return            the checked state of the specifed element
574   */
575  public boolean getChecked(int index) {
576    return ((CheckBoxListModel) getModel()).getChecked(index);
577  }
578 
579  /**
580   * sets the checked state of the element at the given index
581   *
582   * @param index       the index of the element to set the checked state for
583   * @param checked     the new checked state
584   */
585  public void setChecked(int index, boolean checked) {
586    ((CheckBoxListModel) getModel()).setChecked(index, checked);
587  }
588 
589  /**
590   * returns an array with the indices of all checked items
591   *
592   * @return            the indices of all items that are currently checked
593   */
594  public int[] getCheckedIndices() {
595    Vector      list;
596    int[]       result;
597    int         i;
598   
599    // traverse over model
600    list = new Vector();
601    for (i = 0; i < getModel().getSize(); i++) {
602      if (getChecked(i))
603        list.add(new Integer(i));
604    }
605   
606    // generate result array
607    result = new int[list.size()];
608    for (i = 0; i < list.size(); i++) {
609      result[i] = ((Integer) list.get(i)).intValue();
610    }
611   
612    return result;
613  }
614}
Note: See TracBrowser for help on using the repository browser.