View Javadoc

1   // Copyright 2005, FreeHEP.
2   package hep.wired.util;
3   
4   import java.awt.*;
5   import java.awt.event.*;
6   import java.beans.*;
7   import java.util.*;
8   import java.text.*;
9   
10  import javax.swing.*;
11  import javax.swing.event.*;
12  import javax.swing.plaf.*;
13  
14  import org.freehep.swing.layout.TableLayout;
15  import org.freehep.util.ScientificFormat;
16  
17  /***
18   * FIXME WIRED-440 Should move to freehep-swing ?
19   *
20   * @author Mark Donszelmann
21   * @version $Id: NumberSlider.java 2026 2005-07-08 23:31:30Z duns $
22   */
23  public class NumberSlider extends JSlider {
24      
25  /* FIXME WIRED-441, should be NumberFormat */
26      private Format format;
27      
28      private BoundedDoubleRangeModel model;
29      
30      // For testing purposes
31      public NumberSlider() {
32          this(NumberSlider.VERTICAL, -40, 360, 0);
33      }
34      
35      public NumberSlider(int orientation, double min, double max, double def) {
36          this(orientation, min, max, def, false);
37      }
38      
39      public NumberSlider(int orientation, double min, double max, double def, boolean log) {
40          super(orientation);
41          
42          setModel(new DefaultBoundedDoubleRangeModel(def, 0, min, max, log));
43                 
44          setFormat(new ScientificFormat(2, 8, false));
45          
46          int ticks = model.isLogarithmic() ? (int)Math.round(DefaultBoundedDoubleRangeModel.log10(max)) - (int)Math.round(DefaultBoundedDoubleRangeModel.log10(min)) 
47                                            : 10;
48          int increment = model.getMaximum() / ticks;
49  
50          setMajorTickSpacing(increment);
51          if (!log) setMinorTickSpacing(getMajorTickSpacingDouble()/2);
52          setPaintTicks(true);  
53          setLabelTable(createStandardLabels(increment, 100.0));
54          setPaintLabels(true);
55              
56          setPaintTrack(true);
57  
58          addChangeListener(new ChangeListener() {
59              public void stateChanged(ChangeEvent event) {
60                  setToolTipText(String.valueOf(getValueDouble()));
61              }
62          });
63  
64          reset();
65      }
66  
67      public void setModel(BoundedDoubleRangeModel model) {
68          super.setModel(model);
69          this.model = model;
70      }
71  
72      public void reset() {
73          setValue(model.getDefaultValueDouble());
74      }
75  
76  /* FIXME WIRED-441 Should be NumberFormat */
77      public Format getFormat() {
78          return format;
79      }
80      
81  /* FIXME WIRED-441 Should be NumberFormat */
82      public void setFormat(Format format) {
83          if (!(format instanceof ScientificFormat) && !(format instanceof NumberFormat)) throw new RuntimeException("Format needs to be ScientificFormat or NumberFOrmat"); 
84          this.format = format;
85      }
86      
87      public boolean isLogarithmic() {
88          return model.isLogarithmic();
89      }
90      
91      public void setLogarithmic(boolean log) {
92          model.setLogarithmic(log);
93          
94          if (log) {
95              setMinorTickSpacing(0.0);
96          }
97      }
98      
99      public void setMajorTickSpacing(double d) {
100         super.setMajorTickSpacing((int)(d / model.getFactor()));
101     }
102     
103     public double getMajorTickSpacingDouble() {
104         return super.getMajorTickSpacing() * model.getFactor();
105     }
106         
107     public void setMinorTickSpacing(double d) {
108         super.setMinorTickSpacing((int)(d / model.getFactor()));
109     }
110     
111     public double getMinorTickSpacingDouble() {
112         return super.getMinorTickSpacing() * model.getFactor();
113     }
114       
115     public void setExtent(double d) {
116         model.setExtent(d);
117     }
118     
119     public double getExtentDouble() {
120         return model.getExtentDouble();
121     }
122              
123     public double getValueDouble() {
124         return model.getValueDouble();
125     }
126             
127     public void setValue(double value) {
128         model.setValue(value);
129     }
130     
131     public double getMinimumDouble() {
132         return model.getMinimumDouble();
133     }
134     
135     public void setMinimum(double min) {
136         model.setMinimum(min);
137     }
138     
139     public double getMaximumDouble() {
140         return model.getMaximumDouble();
141     }
142     
143     public void setMaximum(double max) {
144         model.setMaximum(max);
145     }       
146 
147     private String format(double value) {
148         if (format instanceof NumberFormat) {
149             return ((NumberFormat)format).format(value);
150         } else if (format instanceof ScientificFormat) {
151             return ((ScientificFormat)format).format(value);
152         }
153         return ""+value;
154     }
155 
156     public Hashtable createStandardLabels(double increment) {
157         return createStandardLabels(increment, getMinimumDouble());
158     }
159 
160     public Hashtable createStandardLabels(double increment, double value) {
161         return createStandardLabels((int)(increment / model.getFactor()), value);
162     }
163 
164     public Hashtable createStandardLabels(int increment, int value) {
165         return createStandardLabels(increment, (double)value);
166     }
167 
168     public Hashtable createStandardLabels(int increment) {
169         return createStandardLabels(increment, getMinimumDouble());
170     }
171 
172     public Hashtable createStandardLabels(int increment, double value) {
173         if ( value > getMaximumDouble() || value < getMinimumDouble() ) {
174             throw new IllegalArgumentException( "Slider label value point out of range." );
175         }
176 
177         if ( increment <= 0 ) {
178             throw new IllegalArgumentException( "Label incremement must be > 0" );
179         }
180 
181         class SmartHashtable extends Hashtable implements PropertyChangeListener {
182             int increment = 0;
183             double value = 0;
184 
185             class LabelUIResource extends JLabel implements UIResource {
186                 public LabelUIResource( String text, int alignment ) {
187                     super( text, alignment );
188                     setName("Slider.label");
189                 }
190             }
191 
192             public SmartHashtable( int increment, double value ) {
193                 super();
194                 this.increment = increment;
195                 this.value = value;
196                 createLabels();
197             }
198 
199             public void propertyChange( PropertyChangeEvent e ) {
200                 if ( e.getPropertyName().equals( "minimum" ) ||
201                      e.getPropertyName().equals( "maximum" ) ) {
202 
203                     Enumeration keys = getLabelTable().keys();
204                     Object key = null;
205                     Hashtable hashtable = new Hashtable();
206 
207                     // Save the labels that were added by the developer
208                     while ( keys.hasMoreElements() ) {
209                         key = keys.nextElement();
210                         Object value = getLabelTable().get( key );
211                         if ( !(value instanceof LabelUIResource) ) {
212                             hashtable.put( key, value );
213                         }
214                     }
215 
216                     clear();
217                     createLabels();
218 
219                     // Add the saved labels
220                     keys = hashtable.keys();
221                     while ( keys.hasMoreElements() ) {
222                         key = keys.nextElement();
223                         put( key, hashtable.get( key ) );
224                     }
225 
226                     ((JSlider)e.getSource()).setLabelTable( this );
227                 }
228             }
229 
230             void createLabels() {
231                 int labelStart = getMinimum();
232                 int labelMaximum = getMaximum();
233                 for ( int labelIndex = labelStart; labelIndex <= labelMaximum; labelIndex += increment ) {
234                     put( new Integer( labelIndex ), new LabelUIResource( format(model.getValueAt(labelIndex)), JLabel.CENTER ) );
235                 }
236             }
237         }
238 
239         SmartHashtable table = new SmartHashtable( increment, value );
240 
241         if ( getLabelTable() != null && (getLabelTable() instanceof PropertyChangeListener) ) {
242             removePropertyChangeListener( (PropertyChangeListener)getLabelTable() );
243         }
244 
245         addPropertyChangeListener( table );
246 
247         return table;
248     }
249 
250     private static void add(JPanel p, final NumberSlider s) {
251         s.addChangeListener(new ChangeListener() {
252             public void stateChanged(ChangeEvent e) {
253                 System.err.println(e.getSource().hashCode()+" "+s.getValueDouble());  
254             }
255         });
256         p.add(s);
257     }
258 
259 /*
260     public static void main(String[] args) {
261         JPanel p = new JPanel();
262         p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
263         
264         add(p, new NumberSlider(NumberSlider.VERTICAL, -40, 360, 0));
265         add(p, new NumberSlider(NumberSlider.VERTICAL, 0, 2000, 100));
266         add(p, new NumberSlider(NumberSlider.VERTICAL, -100, 0, -30));
267         add(p, new NumberSlider(NumberSlider.VERTICAL, -0.01, 0.03, 0));
268         add(p, new NumberSlider(NumberSlider.VERTICAL, 0, 0.00001, 0));
269         add(p, new NumberSlider(NumberSlider.VERTICAL, 0.01, 1000, 200));
270         NumberSlider n = new NumberSlider(NumberSlider.VERTICAL, 0.01, 1000, 200, true);
271         n.setLogarithmic(true);
272         add(p, n);
273         
274         JFrame f = new JFrame();
275         f.getContentPane().add(p);
276         f.setSize(800, 600);
277         f.show();
278     }    
279 */
280 }