00001 package edu.stanford.hci.r3.util.components;
00002
00003 import java.awt.BasicStroke;
00004 import java.awt.Color;
00005 import java.awt.Cursor;
00006 import java.awt.Dimension;
00007 import java.awt.Graphics;
00008 import java.awt.Graphics2D;
00009 import java.awt.Rectangle;
00010 import java.awt.event.KeyEvent;
00011 import java.awt.event.KeyListener;
00012 import java.awt.event.MouseEvent;
00013 import java.awt.event.MouseListener;
00014 import java.awt.event.MouseMotionListener;
00015 import java.util.ArrayList;
00016 import java.util.Iterator;
00017
00018 import javax.swing.BoundedRangeModel;
00019 import javax.swing.DefaultBoundedRangeModel;
00020 import javax.swing.JComponent;
00021 import javax.swing.event.ChangeEvent;
00022 import javax.swing.event.ChangeListener;
00023
00024 import edu.stanford.hci.r3.util.MathUtils;
00025
00038 public class JRangeSlider extends JComponent implements MouseListener, MouseMotionListener, KeyListener {
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00058 protected class RangeSliderChangeListener implements ChangeListener {
00059 public void stateChanged(ChangeEvent e) {
00060 fireChangeEvent();
00061 }
00062 }
00063
00064 protected final static int ARROW_HEIGHT = 4;
00065
00066 protected final static int ARROW_SZ = 16;
00067
00068 protected final static int ARROW_WIDTH = 8;
00069
00070 private static final BasicStroke arrowStroke = new BasicStroke(0);
00071
00072 public static final int HORIZONTAL = 1;
00073
00074 public static final int LEFTRIGHT_TOPBOTTOM = 0;
00075
00076 private static final int PICK_LEFT_OR_TOP = 1;
00077
00078 private static final int PICK_NONE = 0;
00079
00080 private static final int PICK_RIGHT_OR_BOTTOM = 3;
00081
00082 private static final int PICK_THUMB = 2;
00083
00084 public static final int PREFERRED_BREADTH = 16;
00085
00086 public static final int PREFERRED_LENGTH = 300;
00087
00088 public static final int RIGHTLEFT_BOTTOMTOP = 1;
00089
00090 public static final int VERTICAL = 0;
00091
00092 private Color arrowColor = new Color(77, 97, 133);
00093
00094 protected ChangeEvent changeEvent = null;
00095
00096 protected ChangeListener changeListener;
00097
00098 protected int direction;
00099
00100 protected boolean empty;
00101
00102 protected int increment = 1;
00103
00104 protected ArrayList listeners = new ArrayList();
00105
00106 protected int minExtent = 0;
00107
00108 protected BoundedRangeModel model;
00109
00110 int mouse;
00111
00112 protected int orientation;
00113
00114 int pick;
00115
00116 int pickOffsetHigh;
00117
00118 int pickOffsetLow;
00119
00120 protected Color thumbColor = new Color(150, 180, 220);
00121
00125 private boolean use3DHighlights = false;
00126
00137 public JRangeSlider(BoundedRangeModel model, int orientation, int direction) {
00138 super.setFocusable(true);
00139 this.model = model;
00140 this.orientation = orientation;
00141 this.direction = direction;
00142 setForeground(Color.LIGHT_GRAY);
00143
00144 this.changeListener = createListener();
00145 model.addChangeListener(changeListener);
00146
00147 addMouseListener(this);
00148 addMouseMotionListener(this);
00149 addKeyListener(this);
00150 }
00151
00166 public JRangeSlider(int minimum, int maximum, int lowValue, int highValue, int orientation) {
00167 this(new DefaultBoundedRangeModel(lowValue, highValue, minimum, maximum), orientation,
00168 LEFTRIGHT_TOPBOTTOM);
00169 }
00170
00187 public JRangeSlider(int minimum, int maximum, int lowValue, int highValue, int orientation, int direction) {
00188 this(new DefaultBoundedRangeModel(lowValue, highValue, minimum, maximum), orientation, direction);
00189 }
00190
00197 public void addChangeListener(ChangeListener cl) {
00198 if (!listeners.contains(cl))
00199 listeners.add(cl);
00200 }
00201
00207 protected ChangeListener createListener() {
00208 return new RangeSliderChangeListener();
00209 }
00210
00221 protected void customPaint(Graphics2D g, int width, int height) {
00222
00223
00224 }
00225
00229 protected void fireChangeEvent() {
00230 repaint();
00231 if (changeEvent == null) {
00232 changeEvent = new ChangeEvent(this);
00233 }
00234 Iterator iter = listeners.iterator();
00235 while (iter.hasNext()) {
00236 ((ChangeListener) iter.next()).stateChanged(changeEvent);
00237 }
00238 }
00239
00244 public int getHighValue() {
00245 return model.getValue() + model.getExtent();
00246 }
00247
00252 public int getLowValue() {
00253 return model.getValue();
00254 }
00255
00261 public int getMaximum() {
00262 return model.getMaximum();
00263 }
00264
00270 public int getMinimum() {
00271 return model.getMinimum();
00272 }
00273
00279 public BoundedRangeModel getModel() {
00280 return model;
00281 }
00282
00286 public Dimension getPreferredSize() {
00287 if (orientation == VERTICAL) {
00288 return new Dimension(PREFERRED_BREADTH, PREFERRED_LENGTH);
00289 } else {
00290 return new Dimension(PREFERRED_LENGTH, PREFERRED_BREADTH);
00291 }
00292 }
00293
00299 public Color getThumbColor() {
00300 return thumbColor;
00301 }
00302
00303 private void grow(int increment) {
00304 model.setRangeProperties(model.getValue() - increment, model.getExtent() + 2 * increment, model
00305 .getMinimum(), model.getMaximum(), false);
00306 }
00307
00308
00309
00310
00314 public void keyPressed(KeyEvent e) {
00315 int kc = e.getKeyCode();
00316 boolean v = (orientation == VERTICAL);
00317 boolean d = (kc == KeyEvent.VK_DOWN);
00318 boolean u = (kc == KeyEvent.VK_UP);
00319 boolean l = (kc == KeyEvent.VK_LEFT);
00320 boolean r = (kc == KeyEvent.VK_RIGHT);
00321
00322 int minimum = getMinimum();
00323 int maximum = getMaximum();
00324 int lowValue = getLowValue();
00325 int highValue = getHighValue();
00326
00327 if (v && r || !v && u) {
00328 if (lowValue - increment >= minimum && highValue + increment <= maximum) {
00329 grow(increment);
00330 }
00331 } else if (v && l || !v && d) {
00332 if (highValue - lowValue >= 2 * increment) {
00333 grow(-1 * increment);
00334 }
00335 } else if (v && d || !v && l) {
00336 if (lowValue - increment >= minimum) {
00337 offset(-increment);
00338 }
00339 } else if (v && u || !v && r) {
00340 if (highValue + increment <= maximum) {
00341 offset(increment);
00342 }
00343 }
00344 }
00345
00349 public void keyReleased(KeyEvent e) {
00350 }
00351
00355 public void keyTyped(KeyEvent e) {
00356 }
00357
00361 public void mouseClicked(MouseEvent e) {
00362 }
00363
00367 public void mouseDragged(MouseEvent e) {
00368 requestFocus();
00369 int value = (orientation == VERTICAL) ? e.getY() : e.getX();
00370
00371 int minimum = getMinimum();
00372 int maximum = getMaximum();
00373 int lowValue = getLowValue();
00374 int highValue = getHighValue();
00375
00376 switch (pick) {
00377 case PICK_LEFT_OR_TOP:
00378 int low = toLocal(value - pickOffsetLow);
00379
00380 if (low < minimum) {
00381 low = minimum;
00382 }
00383 if (low > maximum) {
00384 low = maximum;
00385 }
00386 if (low > highValue - minExtent) {
00387 low = highValue - minExtent;
00388 }
00389 setLowValue(low);
00390 break;
00391
00392 case PICK_RIGHT_OR_BOTTOM:
00393 int high = toLocal(value - pickOffsetHigh);
00394
00395 if (high < minimum) {
00396 high = minimum;
00397 }
00398 if (high > maximum) {
00399 high = maximum;
00400 }
00401 if (high < lowValue + minExtent) {
00402 high = lowValue + minExtent;
00403 }
00404 setHighValue(high);
00405 break;
00406
00407 case PICK_THUMB:
00408 int dxOrDy = toLocal(value - pickOffsetLow) - lowValue;
00409 if ((dxOrDy < 0) && ((lowValue + dxOrDy) < minimum)) {
00410 dxOrDy = minimum - lowValue;
00411 }
00412 if ((dxOrDy > 0) && ((highValue + dxOrDy) > maximum)) {
00413 dxOrDy = maximum - highValue;
00414 }
00415 if (dxOrDy != 0) {
00416 offset(dxOrDy);
00417 }
00418 break;
00419 }
00420 }
00421
00425 public void mouseEntered(MouseEvent e) {
00426 }
00427
00431 public void mouseExited(MouseEvent e) {
00432 }
00433
00434
00435
00436
00440 public void mouseMoved(MouseEvent e) {
00441 if (orientation == VERTICAL) {
00442 switch (pickHandle(e.getY())) {
00443 case PICK_LEFT_OR_TOP:
00444 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00445 break;
00446 case PICK_RIGHT_OR_BOTTOM:
00447 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00448 break;
00449 case PICK_THUMB:
00450 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00451 break;
00452 case PICK_NONE:
00453 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00454 break;
00455 }
00456 } else {
00457 switch (pickHandle(e.getX())) {
00458 case PICK_LEFT_OR_TOP:
00459 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00460 break;
00461 case PICK_RIGHT_OR_BOTTOM:
00462 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00463 break;
00464 case PICK_THUMB:
00465 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00466 break;
00467 case PICK_NONE:
00468 setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
00469 break;
00470 }
00471 }
00472 }
00473
00477 public void mousePressed(MouseEvent e) {
00478 if (orientation == VERTICAL) {
00479 pick = pickHandle(e.getY());
00480 pickOffsetLow = e.getY() - toScreen(getLowValue());
00481 pickOffsetHigh = e.getY() - toScreen(getHighValue());
00482 mouse = e.getY();
00483 } else {
00484 pick = pickHandle(e.getX());
00485 pickOffsetLow = e.getX() - toScreen(getLowValue());
00486 pickOffsetHigh = e.getX() - toScreen(getHighValue());
00487 mouse = e.getX();
00488 }
00489 repaint();
00490 }
00491
00495 public void mouseReleased(MouseEvent e) {
00496 pick = PICK_NONE;
00497 repaint();
00498 }
00499
00500 private void offset(int dxOrDy) {
00501 model.setValue(model.getValue() + dxOrDy);
00502 }
00503
00507 protected void paint3DRectLighting(Graphics2D g2, int x, int y, int width, int height) {
00508 if (use3DHighlights) {
00509 g2.setColor(Color.white);
00510 g2.drawLine(x + 1, y + 1, x + 1, y + height - 1);
00511 g2.drawLine(x + 1, y + 1, x + width - 1, y + 1);
00512 g2.setColor(Color.gray);
00513 g2.drawLine(x + 1, y + height - 1, x + width - 1, y + height - 1);
00514 g2.drawLine(x + width - 1, y + 1, x + width - 1, y + height - 1);
00515 g2.setColor(Color.darkGray);
00516 g2.drawLine(x, y + height, x + width, y + height);
00517 g2.drawLine(x + width, y, x + width, y + height);
00518 }
00519 }
00520
00525 protected void paintArrow(Graphics2D g2, double x, double y, int w, int h, boolean topDown) {
00526 int intX = (int) (x + 0.5);
00527 int intY = (int) (y + 0.5);
00528
00529 if (orientation == VERTICAL) {
00530 if (w % 2 == 0) {
00531 w = w - 1;
00532 }
00533
00534 if (topDown) {
00535 for (int i = 0; i < (w / 2 + 1); i++) {
00536 g2.drawLine(intX + i, intY + i, intX + w - i - 1, intY + i);
00537 }
00538 } else {
00539 for (int i = 0; i < (w / 2 + 1); i++) {
00540 g2.drawLine(intX + w / 2 - i, intY + i, intX + w - w / 2 + i - 1, intY + i);
00541 }
00542 }
00543 } else {
00544 if (h % 2 == 0) {
00545 h = h - 1;
00546 }
00547
00548
00549 final int x_1 = intX + 1;
00550 final int h_1 = h + 1;
00551 final int h_over_2_plus_1 = MathUtils.rint(h / 2.0) + 1;
00552 final int h_1_5_minus_1 = MathUtils.rint(1.5 * h) - 1;
00553 final int x_w_minus_1 = intX + w - 1;
00554 final int x_w_minus_2 = intX + w - 2;
00555
00556 if (topDown) {
00557
00558 g2.drawLine(intX, h_over_2_plus_1, x_w_minus_2, h);
00559 g2.drawLine(intX, h_1_5_minus_1, x_w_minus_2, h_1);
00560
00561
00562 g2.drawLine(x_1, h_over_2_plus_1, x_w_minus_1, h);
00563 g2.drawLine(x_1, h_1_5_minus_1, x_w_minus_1, h_1);
00564
00565
00566 g2.drawLine(x_1, h_over_2_plus_1 - 1, intX + w, h);
00567 g2.drawLine(x_1, h_1_5_minus_1 + 1, intX + w, h_1);
00568 } else {
00569 g2.drawLine(x_w_minus_1, h_over_2_plus_1, x_1, h);
00570 g2.drawLine(x_w_minus_1, h_1_5_minus_1, x_1, h_1);
00571
00572
00573 g2.drawLine(x_w_minus_2, h_over_2_plus_1, intX, h);
00574 g2.drawLine(x_w_minus_2, h_1_5_minus_1, intX, h_1);
00575
00576
00577 g2.drawLine(x_w_minus_2, h_over_2_plus_1 - 1, intX - 1, h);
00578 g2.drawLine(x_w_minus_2, h_1_5_minus_1 + 1, intX - 1, h_1);
00579 }
00580 }
00581 }
00582
00586 public void paintComponent(Graphics g) {
00587 Rectangle bounds = getBounds();
00588 int width = (int) bounds.getWidth() - 1;
00589 int height = (int) bounds.getHeight() - 1;
00590
00591 int min = toScreen(getLowValue());
00592 int max = toScreen(getHighValue());
00593
00594
00595 if (empty) {
00596 if (direction == LEFTRIGHT_TOPBOTTOM) {
00597 min = ARROW_SZ;
00598 max = (orientation == VERTICAL) ? height - ARROW_SZ : width - ARROW_SZ;
00599 } else {
00600 min = (orientation == VERTICAL) ? height - ARROW_SZ : width - ARROW_SZ;
00601 max = ARROW_SZ;
00602 }
00603 }
00604
00605 final Graphics2D g2 = (Graphics2D) g;
00606 g2.setColor(getBackground());
00607 g2.fillRect(0, 0, width, height);
00608
00609 g2.setColor(getForeground());
00610 g2.drawRect(0, 0, width, height);
00611
00612
00613 g2.setStroke(arrowStroke);
00614 final int thumbExtent = Math.abs(max - min) - 1;
00615
00616 if (orientation == VERTICAL) {
00617 if (direction == LEFTRIGHT_TOPBOTTOM) {
00618 g2.setColor(getForeground());
00619 g2.fillRect(0, min - ARROW_SZ, width, ARROW_SZ - 1);
00620 paint3DRectLighting(g2, 0, min - ARROW_SZ, width, ARROW_SZ - 1);
00621
00622 if (thumbColor != null) {
00623 g2.setColor(thumbColor);
00624 g2.fillRect(0, min, width, thumbExtent);
00625 paint3DRectLighting(g2, 0, min, width, thumbExtent);
00626 }
00627
00628 g2.setColor(getForeground());
00629 g2.fillRect(0, max, width, ARROW_SZ - 1);
00630 paint3DRectLighting(g2, 0, max, width, ARROW_SZ - 1);
00631
00632
00633 g2.setColor(arrowColor);
00634 paintArrow(g2, (width - ARROW_WIDTH) / 2.0, min - ARROW_SZ + (ARROW_SZ - ARROW_HEIGHT) / 2.0,
00635 ARROW_WIDTH, ARROW_HEIGHT, true);
00636 paintArrow(g2, (width - ARROW_WIDTH) / 2.0, max + (ARROW_SZ - ARROW_HEIGHT) / 2.0,
00637 ARROW_WIDTH, ARROW_HEIGHT, false);
00638 } else {
00639 g2.setColor(getForeground());
00640 g2.fillRect(0, min, width, ARROW_SZ - 1);
00641 paint3DRectLighting(g2, 0, min, width, ARROW_SZ - 1);
00642
00643 if (thumbColor != null) {
00644 g2.setColor(thumbColor);
00645 g2.fillRect(0, max, width, thumbExtent);
00646 paint3DRectLighting(g2, 0, max, width, thumbExtent);
00647 }
00648
00649 g2.setColor(getForeground());
00650 g2.fillRect(0, max - ARROW_SZ, width, ARROW_SZ - 1);
00651 paint3DRectLighting(g2, 0, max - ARROW_SZ, width, ARROW_SZ - 1);
00652
00653
00654 g2.setColor(arrowColor);
00655 paintArrow(g2, (width - ARROW_WIDTH) / 2.0, min + (ARROW_SZ - ARROW_HEIGHT) / 2.0,
00656 ARROW_WIDTH, ARROW_HEIGHT, false);
00657 paintArrow(g2, (width - ARROW_WIDTH) / 2.0, max - ARROW_SZ + (ARROW_SZ - ARROW_HEIGHT) / 2.0,
00658 ARROW_WIDTH, ARROW_HEIGHT, true);
00659 }
00660 } else {
00661 if (direction == LEFTRIGHT_TOPBOTTOM) {
00662 g2.setColor(getForeground());
00663 g2.fillRect(min - ARROW_SZ, 0, ARROW_SZ - 1, height);
00664 paint3DRectLighting(g2, min - ARROW_SZ, 0, ARROW_SZ - 1, height);
00665
00666 if (thumbColor != null) {
00667 g2.setColor(thumbColor);
00668 g2.fillRect(min, 0, thumbExtent, height);
00669 paint3DRectLighting(g2, min, 0, thumbExtent, height);
00670 }
00671
00672 g2.setColor(getForeground());
00673 g2.fillRect(max, 0, ARROW_SZ - 1, height);
00674 paint3DRectLighting(g2, max, 0, ARROW_SZ - 1, height);
00675
00676
00677 g2.setColor(arrowColor);
00678 paintArrow(g2, min - ARROW_SZ + (ARROW_SZ - ARROW_HEIGHT) / 2.0,
00679 (height - ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, true);
00680 paintArrow(g2, max + (ARROW_SZ - ARROW_HEIGHT) / 2.0, (height - ARROW_WIDTH) / 2.0,
00681 ARROW_HEIGHT, ARROW_WIDTH, false);
00682 } else {
00683 g2.setColor(getForeground());
00684 g2.fillRect(min, 0, ARROW_SZ - 1, height);
00685 paint3DRectLighting(g2, min, 0, ARROW_SZ - 1, height);
00686
00687 if (thumbColor != null) {
00688 g2.setColor(thumbColor);
00689 g2.fillRect(max, 0, thumbExtent, height);
00690 paint3DRectLighting(g2, max, 0, thumbExtent, height);
00691 }
00692
00693 g2.setColor(getForeground());
00694 g2.fillRect(max - ARROW_SZ, 0, ARROW_SZ - 1, height);
00695 paint3DRectLighting(g2, max - ARROW_SZ, 0, ARROW_SZ - 1, height);
00696
00697
00698 g2.setColor(arrowColor);
00699 paintArrow(g2, min + (ARROW_SZ - ARROW_HEIGHT) / 2.0, (height - ARROW_WIDTH) / 2.0,
00700 ARROW_HEIGHT, ARROW_WIDTH, true);
00701 paintArrow(g2, max - ARROW_SZ + (ARROW_SZ - ARROW_HEIGHT) / 2.0,
00702 (height - ARROW_WIDTH) / 2.0, ARROW_HEIGHT, ARROW_WIDTH, false);
00703 }
00704 }
00705 customPaint(g2, width, height);
00706
00707 }
00708
00709 private int pickHandle(int xOrY) {
00710 int min = toScreen(getLowValue());
00711 int max = toScreen(getHighValue());
00712 int pick = PICK_NONE;
00713
00714 if (direction == LEFTRIGHT_TOPBOTTOM) {
00715 if ((xOrY > (min - ARROW_SZ)) && (xOrY < min)) {
00716 pick = PICK_LEFT_OR_TOP;
00717 } else if ((xOrY >= min) && (xOrY <= max)) {
00718 pick = PICK_THUMB;
00719 } else if ((xOrY > max) && (xOrY < (max + ARROW_SZ))) {
00720 pick = PICK_RIGHT_OR_BOTTOM;
00721 }
00722 } else {
00723 if ((xOrY > min) && (xOrY < (min + ARROW_SZ))) {
00724 pick = PICK_LEFT_OR_TOP;
00725 } else if ((xOrY <= min) && (xOrY >= max)) {
00726 pick = PICK_THUMB;
00727 } else if ((xOrY > (max - ARROW_SZ) && (xOrY < max))) {
00728 pick = PICK_RIGHT_OR_BOTTOM;
00729 }
00730 }
00731
00732 return pick;
00733 }
00734
00741 public void removeChangeListener(ChangeListener cl) {
00742 listeners.remove(cl);
00743 }
00744
00751 public void setEmpty(boolean empty) {
00752 this.empty = empty;
00753 repaint();
00754 }
00755
00763 public void setHighValue(int highValue) {
00764 model.setExtent(highValue - model.getValue());
00765 }
00766
00774 public void setLowValue(int lowValue) {
00775 int e = (model.getValue() - lowValue) + model.getExtent();
00776 model.setRangeProperties(lowValue, e, model.getMinimum(), model.getMaximum(), false);
00777 model.setValue(lowValue);
00778 }
00779
00786 public void setMaximum(int maximum) {
00787 model.setMaximum(maximum);
00788 }
00789
00797 public void setMinExtent(int minExtent) {
00798 this.minExtent = minExtent;
00799 }
00800
00807 public void setMinimum(int minimum) {
00808 model.setMinimum(minimum);
00809 }
00810
00817 public void setModel(BoundedRangeModel brm) {
00818 model.removeChangeListener(changeListener);
00819 model = brm;
00820 model.addChangeListener(changeListener);
00821 repaint();
00822 }
00823
00832 public void setRange(int lowValue, int highValue) {
00833 model.setRangeProperties(lowValue, highValue - lowValue, model.getMinimum(), model.getMaximum(),
00834 false);
00835 }
00836
00843 public void setThumbColor(Color thumbColor) {
00844 this.thumbColor = thumbColor;
00845 }
00846
00850 protected int toLocal(int xOrY) {
00851 Dimension sz = getSize();
00852 int min = getMinimum();
00853 double scale;
00854 if (orientation == VERTICAL) {
00855 scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
00856 } else {
00857 scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
00858 }
00859
00860 if (direction == LEFTRIGHT_TOPBOTTOM) {
00861 return (int) (((xOrY - ARROW_SZ) / scale) + min + 0.5);
00862 } else {
00863 if (orientation == VERTICAL) {
00864 return (int) ((sz.height - xOrY - ARROW_SZ) / scale + min + 0.5);
00865 } else {
00866 return (int) ((sz.width - xOrY - ARROW_SZ) / scale + min + 0.5);
00867 }
00868 }
00869 }
00870
00874 protected int toScreen(int xOrY) {
00875 Dimension sz = getSize();
00876 int min = getMinimum();
00877 double scale;
00878 if (orientation == VERTICAL) {
00879 scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
00880 } else {
00881 scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() - min);
00882 }
00883
00884
00885
00886
00887 if (direction == LEFTRIGHT_TOPBOTTOM) {
00888 return (int) (ARROW_SZ + ((xOrY - min) * scale) + 0.5);
00889 } else {
00890 if (orientation == VERTICAL) {
00891 return (int) (sz.height - (xOrY - min) * scale - ARROW_SZ + 0.5);
00892 } else {
00893 return (int) (sz.width - (xOrY - min) * scale - ARROW_SZ + 0.5);
00894 }
00895 }
00896 }
00897
00901 protected double toScreenDouble(int xOrY) {
00902 Dimension sz = getSize();
00903 int min = getMinimum();
00904 double scale;
00905 if (orientation == VERTICAL) {
00906 scale = (sz.height - (2 * ARROW_SZ)) / (double) (getMaximum() + 1 - min);
00907 } else {
00908 scale = (sz.width - (2 * ARROW_SZ)) / (double) (getMaximum() + 1 - min);
00909 }
00910
00911
00912
00913
00914 if (direction == LEFTRIGHT_TOPBOTTOM) {
00915 return ARROW_SZ + ((xOrY - min) * scale);
00916 } else {
00917 if (orientation == VERTICAL) {
00918 return sz.height - (xOrY - min) * scale - ARROW_SZ;
00919 } else {
00920 return sz.width - (xOrY - min) * scale - ARROW_SZ;
00921 }
00922 }
00923 }
00924
00925 }