1 16 17 package org.mc4j.console.swing; 18 19 import java.awt.Color ; 20 import java.awt.Graphics ; 21 import java.awt.Rectangle ; 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.util.Enumeration ; 25 import java.util.Hashtable ; 26 27 import javax.swing.BoundedRangeModel ; 28 import javax.swing.BoxLayout ; 29 import javax.swing.JFrame ; 30 import javax.swing.JLabel ; 31 import javax.swing.JSlider ; 32 import javax.swing.event.ChangeEvent ; 33 import javax.swing.event.ChangeListener ; 34 import javax.swing.plaf.SliderUI ; 35 import javax.swing.plaf.UIResource ; 36 import javax.swing.plaf.basic.BasicSliderUI ; 37 38 46 public class LogarithmicJSlider extends JSlider { 47 48 49 public LogarithmicJSlider(int orientation) { 50 super(orientation); 51 SliderUI ui = new LogSliderUI(this); 52 this.setUI(ui); 53 } 54 55 public LogarithmicJSlider(int min, int max) { 56 super(min, max); 57 SliderUI ui = new LogSliderUI(this); 58 this.setUI(ui); 59 } 60 61 public LogarithmicJSlider(int min, int max, int value) { 62 super(min, max, value); 63 SliderUI ui = new LogSliderUI(this); 64 this.setUI(ui); 65 } 66 67 public LogarithmicJSlider(int orientation, int min, int max, int value) { 68 super(orientation, min, max, value); 69 SliderUI ui = new LogSliderUI(this); 70 this.setUI(ui); 71 } 72 73 public LogarithmicJSlider(BoundedRangeModel brm) { 74 super(brm); 75 SliderUI ui = new LogSliderUI(this); 76 this.setUI(ui); 77 } 78 79 public LogarithmicJSlider() { 80 SliderUI ui = new LogSliderUI(this); 81 this.setUI(ui); 82 } 83 84 85 public static class LogSliderUI extends BasicSliderUI { 86 87 public LogSliderUI(JSlider b) { 88 super(b); 89 } 90 91 92 public int xPositionForValue(int value) { 93 int min = slider.getMinimum(); 94 int max = slider.getMaximum(); 95 int trackLength = trackRect.width; 96 double valueRange = (double) Math.log(max) - (double) Math.log(min); 97 double pixelsPerValue = (double) trackLength / valueRange; 98 int trackLeft = trackRect.x; 99 int trackRight = trackRect.x + (trackRect.width - 1); 100 int xPosition; 101 102 if (!drawInverted()) { 103 xPosition = trackLeft; 104 xPosition += Math.round(pixelsPerValue * ((double) Math.log(value) - Math.log(min))); 105 } else { 106 xPosition = trackRight; 107 xPosition -= Math.round(pixelsPerValue * ((double) Math.log(value) - Math.log(min))); 108 } 109 110 xPosition = Math.max(trackLeft, xPosition); 111 xPosition = Math.min(trackRight, xPosition); 112 113 return xPosition; 114 115 116 } 117 118 public int yPositionForValue(int value) { 119 return super.yPositionForValue(value); 121 } 122 123 public int valueForYPosition(int yPos) { 124 return super.valueForYPosition(yPos); 126 } 127 128 public int valueForXPosition(int xPos) { 129 int value; 130 final int minValue = slider.getMinimum(); 131 final int maxValue = slider.getMaximum(); 132 final int trackLength = trackRect.width; 133 final int trackLeft = trackRect.x; 134 final int trackRight = trackRect.x + (trackRect.width - 1); 135 136 if (xPos <= trackLeft) { 137 value = drawInverted() ? maxValue : minValue; 138 } else if (xPos >= trackRight) { 139 value = drawInverted() ? minValue : maxValue; 140 } else { 141 int distanceFromTrackLeft = xPos - trackLeft; 142 double valueRange = (double) Math.log(maxValue) - (double) Math.log(minValue); 143 147 int valueFromTrackLeft = 148 (int) 149 Math.round(Math.pow(Math.E, Math.log(minValue) + ((((double) distanceFromTrackLeft) * valueRange) / (double) trackLength))); 150 151 value = drawInverted() ? maxValue - valueFromTrackLeft : 152 (int) Math.log(minValue) + valueFromTrackLeft; 153 } 154 155 return value; 156 157 } 158 159 public void paintTicks(Graphics g) { 160 Rectangle tickBounds = tickRect; 161 int i; 162 int maj, min, max; 163 int w = tickBounds.width; 164 int h = tickBounds.height; 165 int centerEffect, tickHeight; 166 167 g.setColor(Color.black); 168 169 maj = slider.getMajorTickSpacing(); 170 min = slider.getMinorTickSpacing(); 171 172 if (slider.getOrientation() == JSlider.HORIZONTAL) { 173 g.translate(0, tickBounds.y); 174 175 int value = slider.getMinimum(); 176 int xPos = 0; 177 178 if (slider.getMinorTickSpacing() > 0) { 179 int majorValue = slider.getMinimum(); 180 181 while (value <= slider.getMaximum()) { 182 if (value >= majorValue) { 183 value = majorValue; 184 majorValue *= maj; 185 } 186 value += (majorValue / 10.0); 187 188 xPos = xPositionForValue(value); 189 paintMinorTickForHorizSlider(g, tickBounds, xPos); 190 191 } 192 } 193 194 if (slider.getMajorTickSpacing() > 0) { 195 value = slider.getMinimum(); 196 197 while (value <= slider.getMaximum()) { 198 xPos = xPositionForValue(value); 199 paintMajorTickForHorizSlider(g, tickBounds, xPos); 200 value *= slider.getMajorTickSpacing(); 201 } 202 } 203 204 g.translate(0, -tickBounds.y); 205 } else { 206 207 g.translate(tickBounds.x, 0); 208 209 int value = slider.getMinimum(); 210 int yPos = 0; 211 212 if (slider.getMinorTickSpacing() > 0) { 213 int majorValue = slider.getMinimum(); 214 int offset = 0; 215 if (!slider.getComponentOrientation().isLeftToRight()) { 216 offset = tickBounds.width - tickBounds.width / 2; 217 g.translate(offset, 0); 218 } 219 220 while (value <= slider.getMaximum()) { 221 if (value >= majorValue) { 222 value = majorValue; 223 majorValue *= maj; 224 } 225 226 yPos = yPositionForValue(value); 227 paintMinorTickForVertSlider(g, tickBounds, yPos); 228 value += (majorValue / 10.0); 229 } 230 231 if (!slider.getComponentOrientation().isLeftToRight()) { 232 g.translate(-offset, 0); 233 } 234 } 235 236 if (slider.getMajorTickSpacing() > 0) { 237 value = slider.getMinimum(); 238 if (!slider.getComponentOrientation().isLeftToRight()) { 239 g.translate(2, 0); 240 } 241 242 while (value <= slider.getMaximum()) { 243 yPos = yPositionForValue(value); 244 paintMajorTickForVertSlider(g, tickBounds, yPos); 245 value *= slider.getMajorTickSpacing(); 246 } 247 248 if (!slider.getComponentOrientation().isLeftToRight()) { 249 g.translate(-2, 0); 250 } 251 } 252 g.translate(-tickBounds.x, 0); 253 } 254 } 255 256 } 257 258 259 public static void main(String [] args) { 260 JFrame frame = new JFrame (); 261 frame.setSize(408, 408); 262 263 final JSlider slider = new LogarithmicJSlider(100, 10000000, 1000); 264 final JLabel label = new JLabel (); 265 266 slider.setPaintTicks(true); 267 slider.setPaintLabels(true); 268 slider.setMajorTickSpacing(10); 269 slider.setMinorTickSpacing(10); 270 271 slider.addChangeListener(new ChangeListener () { 272 public void stateChanged(ChangeEvent e) { 273 System.out.println("Value is now: " + slider.getValue()); 274 275 276 label.setText("Current value is: " + slider.getValue()); 277 278 } 279 }); 280 281 frame.getContentPane().setLayout(new BoxLayout (frame.getContentPane(), BoxLayout.Y_AXIS)); 282 frame.getContentPane().add(slider); 283 frame.getContentPane().add(label); 284 frame.setVisible(true); 285 286 LogSliderUI ui = (LogSliderUI) slider.getUI(); 287 for (int i = 10; i <= 100000; i *= 10) { 288 System.out.println("I: " + i + " xPos: " + ui.xPositionForValue(i) + " valueFor: " + ui.valueForXPosition(ui.xPositionForValue(i))); 289 } 290 291 } 292 293 294 299 public Hashtable createStandardLabels(int increment, int start) { 300 if (start > getMaximum() || start < getMinimum()) { 301 throw new IllegalArgumentException ("Slider label start point out of range."); 302 } 303 304 if (increment <= 0) { 305 throw new IllegalArgumentException ("Label incremement must be > 0"); 306 } 307 308 class LabelHashtable extends Hashtable implements PropertyChangeListener { 309 int increment = 0; 310 int start = 0; 311 boolean startAtMin = false; 312 313 314 public LabelHashtable(int increment, int start) { 315 super(); 316 this.increment = increment; 317 this.start = start; 318 startAtMin = start == getMinimum(); 319 createLabels(this, increment, start); 320 } 321 322 public void propertyChange(PropertyChangeEvent e) { 323 if (e.getPropertyName().equals("minimum") && startAtMin) { 324 start = getMinimum(); 325 } 326 327 if (e.getPropertyName().equals("minimum") || 328 e.getPropertyName().equals("maximum")) { 329 330 Enumeration keys = getLabelTable().keys(); 331 Object key = null; 332 Hashtable hashtable = new Hashtable (); 333 334 while (keys.hasMoreElements()) { 336 key = keys.nextElement(); 337 Object value = getLabelTable().get(key); 338 if (!(value instanceof LabelUIResource)) { 339 hashtable.put(key, value); 340 } 341 } 342 343 clear(); 344 createLabels(this, increment, start); 345 346 keys = hashtable.keys(); 348 while (keys.hasMoreElements()) { 349 key = keys.nextElement(); 350 put(key, hashtable.get(key)); 351 } 352 ((JSlider ) e.getSource()).setLabelTable(this); 353 } 354 } 355 } 356 357 LabelHashtable table = new LabelHashtable(increment, start); 358 359 if (getLabelTable() != null && (getLabelTable() instanceof PropertyChangeListener )) { 360 removePropertyChangeListener((PropertyChangeListener ) getLabelTable()); 361 } 362 363 addPropertyChangeListener(table); 364 365 return table; 366 } 367 368 375 protected void createLabels(Hashtable table, int increment, int start) { 376 for (int labelIndex = start; labelIndex <= getMaximum(); labelIndex *= increment) { 377 378 table.put(new Integer (labelIndex), new LabelUIResource("" + labelIndex, JLabel.CENTER)); 379 } 380 } 381 382 protected class LabelUIResource extends JLabel implements UIResource { 383 public LabelUIResource(String text, int alignment) { 384 super(text, alignment); 385 setName("Slider.label"); 386 } 387 } 388 389 } 390 | Popular Tags |