source: src/main/java/weka/gui/ensembleLibraryEditor/tree/NumberNodeEditor.java @ 4

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

Import di weka.

File size: 10.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 *    NumberNodeEditor.java
19 *    Copyright (C) 2006 Robert Jung
20 *
21 */
22
23package weka.gui.ensembleLibraryEditor.tree;
24
25import java.awt.Color;
26import java.awt.Font;
27import java.awt.event.ActionEvent;
28import java.awt.event.ActionListener;
29import java.awt.event.ItemEvent;
30import java.awt.event.ItemListener;
31import java.beans.PropertyChangeEvent;
32import java.beans.PropertyChangeListener;
33import java.text.NumberFormat;
34
35import javax.swing.JButton;
36import javax.swing.JCheckBox;
37import javax.swing.JFormattedTextField;
38import javax.swing.JLabel;
39import javax.swing.JPanel;
40import javax.swing.UIManager;
41
42/**
43 * This class is responsible for creating the number editor GUI to allow users
44 * to specify ranges of numerical values.
45 *
46 * @author  Robert Jung (mrbobjung@gmail.com)
47 * @version $Revision: 1.1 $
48 */
49public class NumberNodeEditor
50  extends JPanel
51  implements ActionListener, ItemListener, PropertyChangeListener {
52 
53  /** for serialization */
54  private static final long serialVersionUID = 3486848815982334460L;
55
56  /**
57   * the button that toggles the type of iterator that this node represents
58   */
59  private JButton m_IteratorButton;
60 
61  /** the textField that allows editing of the number value */
62  private JFormattedTextField m_NumberField;
63 
64  /** the checkBox that allows thi snode to be selected/unselected */
65  private JCheckBox m_SelectedCheckBox;
66 
67  /** the label that prints the name of this node */
68  private JLabel m_Label;
69 
70  /** the colors to use */
71  private Color textForeground, textBackground;
72 
73  /** a reference to the node this editor is rendering */
74  private NumberNode m_Node;
75 
76  /**
77   * The constructor builds a user interface based on the information queried
78   * from the node passed in. Specifically the iteratorType, whether the node
79   * is checkable, whether it is currently selected, it's current value, and
80   * the name to print on the label.
81   *
82   * @param node        the node the editor is for
83   */
84  public NumberNodeEditor(NumberNode node) {
85   
86    this.m_Node = node;
87    String name = node.getText();
88    Number value = node.getValue();
89    int iteratorType = node.getIteratorType();
90    boolean showCheckBox = node.getCheckable();
91    boolean selected = node.getSelected();
92   
93    textForeground = UIManager.getColor("Tree.textForeground");
94    textBackground = UIManager.getColor("Tree.textBackground");
95   
96    setForeground(textForeground);
97    setBackground(textBackground);
98   
99    Font fontValue;
100    fontValue = UIManager.getFont("Tree.font");
101   
102    if (showCheckBox) {
103      m_SelectedCheckBox = new JCheckBox();
104      m_SelectedCheckBox.setSelected(selected);
105      m_SelectedCheckBox.setForeground(textForeground);
106      m_SelectedCheckBox.setBackground(textBackground);
107      m_SelectedCheckBox.addItemListener(this);
108      add(m_SelectedCheckBox);
109    }
110   
111    m_Label = new JLabel(name);
112    if (fontValue != null) {
113      m_Label.setFont(fontValue);
114    }
115    m_Label.setForeground(textForeground);
116    m_Label.setBackground(textBackground);
117    add(m_Label);
118   
119    if (iteratorType != NumberNode.NOT_ITERATOR) {
120      updateIteratorButton();
121      m_IteratorButton.setForeground(textForeground);
122      m_IteratorButton.setBackground(textBackground);
123      add(m_IteratorButton);
124    }
125   
126    NumberFormat numberFormat = null;
127    try {
128      numberFormat = node.getNumberFormat();
129    } catch (NumberClassNotFoundException e) {
130      e.printStackTrace();
131    }
132   
133    m_NumberField = new JFormattedTextField(numberFormat);
134    m_NumberField.setValue(value);
135    m_NumberField.setColumns(10);
136    m_NumberField.setForeground(textForeground);
137    m_NumberField.setBackground(textBackground);
138   
139    m_NumberField.addPropertyChangeListener(this);
140   
141    add(m_NumberField);
142   
143    if (!selected && showCheckBox) {
144      m_Label.setEnabled(false);
145      if (m_IteratorButton != null)
146        m_IteratorButton.setEnabled(false);
147      m_NumberField.setEnabled(false);
148    }
149  }
150 
151  /**
152   * This method provides a way for the ModelTreeNodeEditor to register an
153   * actionListener with this editor. This way, after the user has done
154   * something, the tree can update its editing state as well as the tree node
155   * structure as necessary
156   *
157   * @param actionListener      the listener to use
158   */
159  public void setActionListener(ActionListener actionListener) {
160    if (m_IteratorButton != null)
161      m_IteratorButton.addActionListener(actionListener);
162  }
163 
164  /**
165   * This method provides a way for the ModelTreeNodeEditor to register an
166   * itemListener with this editor. This way, after the user has done
167   * something, the tree can update its editing state as well as the tree node
168   * structure as necessary
169   *
170   * @param itemListener        the listener to use
171   */
172  public void setItemListener(ItemListener itemListener) {
173    if (m_SelectedCheckBox != null)
174      m_SelectedCheckBox.addItemListener(itemListener);
175  }
176 
177  /**
178   * This method provides a way for the ModelTreeNodeEditor to register a
179   * PropertyListener with this editor. This way, after the user has done
180   * something, the tree can update its editing state as well as the tree node
181   * structure as necessary
182   *
183   * @param propertyChangeListener      the listener to use
184   */
185  public void setPropertyChangeListener(
186      PropertyChangeListener propertyChangeListener) {
187    if (m_NumberField != null)
188      m_NumberField.addPropertyChangeListener(propertyChangeListener);
189  }
190 
191  /**
192   * This is a helper function that repaints the iterator toggling button
193   * after an event.
194   *
195   */
196  private void updateIteratorButton() {
197   
198    if (m_Node.getIteratorType() == NumberNode.PLUS_EQUAL) {
199      m_IteratorButton = new JButton("+=");
200      m_IteratorButton.addActionListener(this);
201     
202    } else if (m_Node.getIteratorType() == NumberNode.TIMES_EQUAL) {
203      m_IteratorButton = new JButton("*=");
204      m_IteratorButton.addActionListener(this);
205     
206    }
207   
208    m_IteratorButton.repaint();
209    repaint();
210  }
211 
212  /**
213   * This is the actionListener that while handle events from the JButton that
214   * specifies the type of iterator. It simply updates both the label string
215   * for the button and the iteratorType of the NumberNode
216   *
217   * @param e           the event
218   */
219  public void actionPerformed(ActionEvent e) {
220   
221    if (m_Node.getIteratorType() == NumberNode.PLUS_EQUAL) {
222      m_Node.setIteratorType(NumberNode.TIMES_EQUAL);
223     
224      try {
225        if ((m_Node.getValue()).equals(m_Node.getOneValue())) {
226          m_Node.setValue(m_Node.getTwoValue());
227          updateIteratorButton();
228        }
229       
230      } catch (NumberClassNotFoundException e1) {
231        e1.printStackTrace();
232      }
233     
234    } else if (m_Node.getIteratorType() == NumberNode.TIMES_EQUAL) {
235      m_Node.setIteratorType(NumberNode.PLUS_EQUAL);
236      try {
237        if ((m_Node.getValue()).equals(m_Node.getTwoValue())) {
238          m_Node.setValue(m_Node.getOneValue());
239          updateIteratorButton();
240        }
241       
242      } catch (NumberClassNotFoundException e1) {
243        e1.printStackTrace();
244      }
245    }
246  }
247 
248  /**
249   * This is the Listener that while handle events from the checkBox ,if this
250   * node has one. Note that before we can select or deselect this node we
251   * have to ask permission from this node's parent. (wow, what fitting
252   * terminology). Anyway, the reason is that we cannot have an iterator node
253   * selected if there is no max node selected - conversely we cannot have a
254   * max node be deselected if the iterator node is selected.
255   *
256   * @param e           the event
257   */
258  public void itemStateChanged(ItemEvent e) {
259    if (e.getStateChange() == ItemEvent.SELECTED) {
260     
261      PropertyNode parent = (PropertyNode) m_Node.getParent();
262     
263      if (parent.canSelect(m_Node)) {
264       
265        m_Node.setSelected(true);
266       
267        m_Label.setEnabled(true);
268        if (m_IteratorButton != null)
269          m_IteratorButton.setEnabled(true);
270        m_NumberField.setEnabled(true);
271      } else {
272        m_SelectedCheckBox.setSelected(false);
273      }
274     
275    } else if (e.getStateChange() == ItemEvent.DESELECTED) {
276     
277      PropertyNode parent = (PropertyNode) m_Node.getParent();
278     
279      if (parent.canDeselect(m_Node)) {
280       
281        m_Node.setSelected(false);
282       
283        m_Label.setEnabled(false);
284        if (m_IteratorButton != null)
285          m_IteratorButton.setEnabled(false);
286        m_NumberField.setEnabled(false);
287       
288      } else {
289        m_SelectedCheckBox.setSelected(true);
290      }
291    }
292  }
293 
294  /**
295   * This is the Listener that while handle events from the text box for this
296   * node. It basically grabs the value from the text field and then casts it
297   * to the correct type and sets the value of the node.
298   *
299   * @param evt         the event
300   */
301  public void propertyChange(PropertyChangeEvent evt) {
302   
303    Object source = evt.getSource();
304   
305    if (source instanceof JFormattedTextField
306        && evt.getPropertyName().equals("value")
307        && (((JFormattedTextField) evt.getSource()).getValue() != null)) {
308     
309      Number newValue = null;
310     
311      Number value = m_Node.getValue();
312     
313      JFormattedTextField field = (JFormattedTextField) evt.getSource();
314     
315      Number fieldValue = (Number) field.getValue();
316     
317      if (value instanceof Double)
318        newValue = new Double(NumberNode.roundDouble((fieldValue.doubleValue())));
319      else if (value instanceof Integer)
320        newValue = new Integer((fieldValue).intValue());
321      else if (value instanceof Float)
322        newValue = new Float(NumberNode.roundFloat((fieldValue.floatValue())));
323      else if (value instanceof Long)
324        newValue = new Long((fieldValue).longValue());
325      else {
326        try {
327          throw new NumberClassNotFoundException(value.getClass()
328              + " not currently supported.");
329        } catch (NumberClassNotFoundException e) {
330          e.printStackTrace();
331        }
332      }
333     
334      field.setValue(newValue);
335     
336      m_Node.setValue(newValue);
337    }
338  }
339}
Note: See TracBrowser for help on using the repository browser.