JRangeSlider.java

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          * NOTE: This is a modified version of the original class distributed by Ben Bederson, Jesse Grosjean, and
00041          * Jon Meyer as part of an HCIL Tech Report. It is modified to allow both vertical and horitonal modes. It
00042          * also fixes a bug with offset on the buttons. Also fixed a bug with rendering using (x,y) instead of
00043          * (0,0) as origin. Also modified to render arrows as a series of lines rather than as a GeneralPath. Also
00044          * modified to fix rounding errors on toLocal and toScreen.
00045          * 
00046          * With inclusion in prefuse, this class has been further modified to use a bounded range model, support
00047          * keyboard commands and more extensize parameterization of rendering/appearance options. Furthermore, a
00048          * stub method has been introduced to allow subclasses to perform custom rendering within the slider
00049          * through.
00050          * 
00051          * With inclusion into r3, this class has been modified to provide more flexibility in rendering, such as
00052          * having the option of not using the 3D highlights.
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; // min extent, in pixels
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                 // does nothing in this class
00223                 // subclasses can override to perform custom painting
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         // Rendering
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         // Event Handling
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                         // do this for vertical also (ronyeh)
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                                 // leftmost
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                                 // middle
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                                 // right most
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                                 // middle
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                                 // left most
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                 // Paint the full slider if the slider is marked as empty
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                 // Draw arrow and thumb backgrounds
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                                 // Draw arrows
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                                 // Draw arrows
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 { // HORIZONTAL
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                                 // Draw arrows
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                                 // Draw arrows
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                 // If the direction is left/right_top/bottom then we subtract the min and multiply times
00885                 // scale
00886                 // Otherwise, we have to invert the number by subtracting the value from the height
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                 // If the direction is left/right_top/bottom then we subtract the min and multiply times
00912                 // scale
00913                 // Otherwise, we have to invert the number by subtracting the value from the height
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 } // end of class JRangeSlider

Generated on Sat Apr 14 18:21:36 2007 for R3 Paper Toolkit by  doxygen 1.4.7