// // Slider.java // /* VisAD system for interactive analysis and visualization of numerical data. Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and Tommy Jasmin. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ package visad.browser; import java.awt.*; import java.awt.event.*; import java.util.Vector; /** * A simple slider widget. */ public class Slider extends Component implements MouseListener, MouseMotionListener { /** * Preferred slider height. */ public static final int SLIDER_PREF_HEIGHT = 14; /** * Preferred slider width. */ public static final int SLIDER_PREF_WIDTH = 300; /** * Width of grip. */ public static final int GRIP_WIDTH = 29; /** * Height of grip. */ public static final int GRIP_HEIGHT = 14; /** * Y-coordinate of top of grip. */ public static final int GRIP_TOP_Y = 0; /** * Y-coordinate of bottom of grip. */ public static final int GRIP_BOTTOM_Y = GRIP_TOP_Y + GRIP_HEIGHT; /** * Y-coordinate of slider line. */ public static final int LINE_LEVEL = GRIP_BOTTOM_Y - GRIP_HEIGHT / 2; /** * Current width of slider. */ protected int width = SLIDER_PREF_WIDTH; /** * Current value of slider. */ protected float value = 0; /** * Minimum value of slider. */ protected float minimum = 0; /** * Maximum value of slider. */ protected float maximum = 100; /** * Pixel location of grip. */ private int grip = 0; /** * Flag whether mouse is currently affecting grip. */ private boolean slide = false; /** * Flag whether grip has moved. */ private boolean moved = false; /** * Minimum widget size. */ protected Dimension minSize = null; /** * Preferred widget size. */ protected Dimension prefSize = null; /** * Maximum widget size. */ protected Dimension maxSize = null; /** * Constructs a slider with default value, minimum and maximum. */ public Slider() { } /** * Constructs a slider with the specified value, minimum and maximum. */ public Slider(float value, float min, float max) { setBounds(min, max); setValue(value); addMouseListener(this); addMouseMotionListener(this); } /** * Gets current slider value. */ public float getValue() { return value; } /** * Gets minimum slider value. */ public float getMinimum() { return minimum; } /** * Gets maximum slider value. */ public float getMaximum() { return maximum; } /** * Sets current slider value. */ public void setValue(float value) { this.value = value; grip = valueToGrip(value); repaint(); } /** * Sets minimum and maximum slider values. */ public void setBounds(float min, float max) { minimum = min; maximum = max; repaint(); } /** * Detects changes in slider width. */ public void setBounds(int x, int y, int w, int h) { super.setBounds(x, y, w, h); width = w; } /** * Horizontal position in grip where mouse was initially pressed. */ private int gripX; /** * Updates grip location of slider. */ private void updateGrip(int x) { grip = x - gripX; if (grip < 0) grip = 0; if (grip > width - GRIP_WIDTH) grip = width - GRIP_WIDTH; value = gripToValue(grip); notifyListeners(); repaint(); } /** * Vector of listeners for slider changes. */ private Vector listeners = new Vector(); /** * Command string for slider change notification. */ private String command = null; /** * Adds a listener to be notified of slider changes. */ public void addActionListener(ActionListener l) { synchronized (listeners) { listeners.addElement(l); } } /** * Removes a listener to be notified of slider changes. */ public void removeActionListener(ActionListener l) { synchronized (listeners) { listeners.removeElement(l); } } /** * Sets command string for slider change notification. */ public void setActionCommand(String cmd) { command = cmd; } /** * Notifies listeners of slider change. */ public void notifyListeners() { ActionEvent e = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command); synchronized (listeners) { for (int i=0; i<listeners.size(); i++) { ActionListener l = (ActionListener) listeners.elementAt(i); l.actionPerformed(e); } } } /** * MouseListener method for moving grip. */ public void mousePressed(MouseEvent e) { int x = e.getX(); int y = e.getY(); if (Widget.containedIn(x, y, grip, 0, GRIP_WIDTH, GRIP_HEIGHT)) { // mouse pressed in grip gripX = x - grip; slide = true; } else if (Widget.containedIn(x, y, 0, 0, grip - 1, GRIP_HEIGHT) || Widget.containedIn(x, y, grip + GRIP_WIDTH, 0, width - grip - GRIP_WIDTH, GRIP_HEIGHT)) { // mouse pressed in slider but outside of grip gripX = GRIP_WIDTH / 2; slide = true; updateGrip(x); } } /** * MouseListener method for moving grip. */ public void mouseReleased(MouseEvent e) { slide = false; } /** * Not used. */ public void mouseClicked(MouseEvent e) { } /** * Not used. */ public void mouseEntered(MouseEvent e) { } /** * Not used. */ public void mouseExited(MouseEvent e) { } /** * MouseMotionListener method for moving grip. */ public void mouseDragged(MouseEvent e) { int x = e.getX(); int y = e.getY(); // move grip if (slide) updateGrip(x); } /** * Not used. */ public void mouseMoved(MouseEvent e) { } /** * Returns minimum size of slider. */ public Dimension getMinimumSize() { if (minSize == null) minSize = new Dimension(0, SLIDER_PREF_HEIGHT); return minSize; } /** * Sets minimum size of slider. */ public void setMinimumSize(Dimension dim) { minSize = dim; } /** * Returns preferred size of slider. */ public Dimension getPreferredSize() { if (prefSize == null) { prefSize = new Dimension(SLIDER_PREF_WIDTH, SLIDER_PREF_HEIGHT); } return prefSize; } /** * Sets preferred size of slider. */ public void setPreferredSize(Dimension dim) { prefSize = dim; } /** * Returns maximum size oa slider. */ public Dimension getMaximumSize() { if (maxSize == null) { maxSize = new Dimension(Integer.MAX_VALUE, SLIDER_PREF_HEIGHT); } return maxSize; } /** * Sets preferred size of slider. */ public void setMaximumSize(Dimension dim) { maxSize = dim; } /** * Converts grip pixel value to slider value. */ private float gripToValue(int grip) { return (float) grip / (width - GRIP_WIDTH) * (maximum - minimum) + minimum; } /** * Converts slider value to grip pixel value. */ private int valueToGrip(float value) { return (int) ((value - minimum) / (maximum - minimum) * (width - GRIP_WIDTH)); } /** * Draws the slider. */ public void paint(Graphics g) { // draw slider background g.setColor(Widget.PALE_GRAY); g.fillRect(0, 0, grip, LINE_LEVEL); g.fillRect(grip + GRIP_WIDTH, 0, width - grip - GRIP_WIDTH, LINE_LEVEL); g.fillRect(0, LINE_LEVEL + 1, grip, GRIP_HEIGHT - LINE_LEVEL - 1); g.fillRect(grip + GRIP_WIDTH, LINE_LEVEL + 1, width - grip - GRIP_WIDTH, GRIP_HEIGHT - LINE_LEVEL - 1); // draw corner grip dots g.drawRect(grip, 0, 0, 0); g.drawRect(grip + GRIP_WIDTH - 1, 0, 0, 0); g.drawRect(grip, GRIP_HEIGHT - 1, 0, 0); g.drawRect(grip + GRIP_WIDTH - 1, GRIP_HEIGHT - 1, 0, 0); // draw central grip block g.fillRect(grip + 2, 2, GRIP_WIDTH - 3, GRIP_HEIGHT - 3); // draw outer grip outline g.setColor(Color.black); g.drawLine(grip + 1, 0, grip + GRIP_WIDTH - 2, 0); g.drawLine(grip + 1, GRIP_HEIGHT - 1, grip + GRIP_WIDTH - 2, GRIP_HEIGHT - 1); g.drawLine(grip, 1, grip, GRIP_HEIGHT - 2); g.drawLine(grip + GRIP_WIDTH - 1, 1, grip + GRIP_WIDTH - 1, GRIP_HEIGHT - 2); // draw inner grip outline g.setColor(Color.white); g.drawLine(grip + 1, 1, grip + GRIP_WIDTH - 2, 1); g.drawLine(grip + 1, 2, grip + 1, GRIP_HEIGHT - 2); // draw slider line if (grip > 0) g.drawLine(0, LINE_LEVEL, grip - 1, LINE_LEVEL); g.drawLine(grip + GRIP_WIDTH, LINE_LEVEL, width, LINE_LEVEL); } // CTR: ? public void repaint() { Graphics g = getGraphics(); if (g != null) { paint(g); g.dispose(); } } /** * Main method for testing purposes. */ public static void main(String[] argv) { Slider s = new Slider(26.3f, 0.0f, 100.0f); Frame f = new Frame("Slider test"); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.add(s); f.pack(); f.setVisible(true); } }