/*
@(#) $Id: ArrowSlider.java,v 1.17 2000-10-09 19:12:11 donm Exp $
VisAD Utility Library: Widgets for use in building applications with
the VisAD interactive analysis and visualization library
Copyright (C) 2017 Nick Rasmussen
VisAD is Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink and Dave Glowacki.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program 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 General Public License in file NOTICE for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package visad.util;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* A pointer slider for visad .
*
* @author Nick Rasmussen nick@cae.wisc.edu
* @version $Revision: 1.17 $, $Date: 2000-10-09 19:12:11 $
* @since Visad Utility Library v0.7.1
*/
public class ArrowSlider extends Slider implements MouseListener, MouseMotionListener {
/** The upper bound */
private float upper;
/** The lower bound */
private float lower;
/** The current value */
private float val;
/** widget sizes */
Dimension minSize = null;
Dimension prefSize = null;
Dimension maxSize = null;
private Object lock = new Object();
/** Construct a new arrow slider with the default values */
public ArrowSlider() {
this(-1, 1, 0);
}
/**
* Construct a new arrow slider with the givden lower, upper and initial values
* @throws IllegalArgumenentException if lower is not less than initial or initial
* is not less than upper
*/
public ArrowSlider(float lower, float upper, float initial) {
this(lower, upper, initial, "value");
}
/**
* Construct a new arrow slider with the given lower, upper and initial values
* @throws IllegalArgumenentException if lower is not less than initial or initial
* is not less than upper
*/
public ArrowSlider(float lower, float upper, float initial, String name) {
if (lower > initial) {
throw new IllegalArgumentException("ArrowSlider: lower bound is greater than initial value");
}
if (initial > upper) {
throw new IllegalArgumentException("ArrowSlider: initial value is greater than the upper bound");
}
this.upper = upper;
this.lower = lower;
this.val = initial;
this.name = name;
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
/** For testing purposes */
public static void main(String[] argv) {
javax.swing.JFrame frame;
frame = new javax.swing.JFrame("Visad Arrow Slider");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
ArrowSlider a = new ArrowSlider();
frame.getContentPane().add(a);
frame.setSize(a.getPreferredSize());
frame.setVisible(true);
}
/* CTR: 29 Jul 1998: added setBounds method */
/** Sets new minimum, maximum, and initial values for this slider */
// public synchronized void setBounds(float min, float max, float init) {
public void setBounds(float min, float max, float init) {
synchronized (lock) {
if (min > max) {
throw new IllegalArgumentException("ArrowSlider: min cannot be "
+"greater than max");
}
if (init < min || init > max) {
throw new IllegalArgumentException("ArrowSlider: initial value "
+"must be between min and max");
}
lower = min;
upper = max;
val = init;
}
notifyListeners(new SliderChangeEvent(SliderChangeEvent.LOWER_CHANGE, min));
notifyListeners(new SliderChangeEvent(SliderChangeEvent.UPPER_CHANGE, max));
notifyListeners(new SliderChangeEvent(SliderChangeEvent.VALUE_CHANGE, init));
// redraw
validate();
repaint();
}
/** Return the minimum value of this slider */
public float getMinimum() {
return lower;
}
/** Sets the minimum value for this slider */
// public synchronized void setMinimum(float value) {
public void setMinimum(float value) {
synchronized (lock) {
if (value > val || (value == val && value == upper)) {
throw new IllegalArgumentException("ArrowSlider: Attemped to set new minimum value greater than the current value");
}
lower = value;
}
notifyListeners(new SliderChangeEvent(SliderChangeEvent.LOWER_CHANGE, value));
// redraw
validate();
repaint();
}
/** Return the maximum value of this slider */
public float getMaximum() {
return upper;
}
/** Sets the maximum value of this scrolbar */
// public synchronized void setMaximum(float value){
public void setMaximum(float value){
synchronized (lock) {
if (value < val || (value == val && value == lower)) {
throw new IllegalArgumentException("ArrowSlider: Attemped to set new maximum value less than the current value");
}
upper = value;
}
notifyListeners(new SliderChangeEvent(SliderChangeEvent.UPPER_CHANGE, value));
// redraw
validate();
repaint();
}
/** Returns the current value of the slider */
public float getValue() {
return val;
}
/**
* Sets the current value of the slider
* @throws IllegalArgumentException if the new value is out of bounds for the slider
*/
// public synchronized void setValue(float value) {
public void setValue(float value) {
synchronized (lock) {
if (value > upper || value < lower) {
throw new IllegalArgumentException("ArrowSlider: Attemped to set new value out of slider range");
}
val = value;
}
notifyListeners(new SliderChangeEvent(SliderChangeEvent.VALUE_CHANGE, value));
// redraw
validate();
repaint();
}
/** Return the preferred sise of the arrow slider */
public Dimension getPreferredSize() {
if (prefSize == null) {
prefSize = new Dimension(256, 16);
}
return prefSize;
}
/** Set the preferred size of the arrow slider */
public void setPreferredSize(Dimension dim) { prefSize = dim; }
/** Return the maximum size of the arrow slider */
public Dimension getMaximumSize() {
if (maxSize == null) {
maxSize = new Dimension(Integer.MAX_VALUE, 16);
}
return maxSize;
}
/** Set the preferred size of the arrow slider */
public void setMaximumSize(Dimension dim) { maxSize = dim; }
/** Return the minimum size of the arrow slider */
public Dimension getMinimumSize() {
if (minSize == null) {
minSize = new Dimension(40, 16);
}
return minSize;
}
/** Set the preferred size of the arrow slider */
public void setMinimumSize(Dimension dim) { minSize = dim; }
/** Present to implement MouseListener, currently ignored */
public void mouseClicked(MouseEvent e) {
//System.out.println(e.paramString());
}
/** Present to implement MouseListener, currently ignored */
public void mouseEntered(MouseEvent e) {
//System.out.println(e.paramString());
}
/** Present to implement MouseListener, currently ignored */
public void mouseExited(MouseEvent e) {
//System.out.println(e.paramString());
}
/** Moves the slider to the clicked position */
public void mousePressed(MouseEvent e) {
//System.out.println(e.paramString());
updatePosition(e);
}
/** Present to implement MouseListener, currently ignored */
public void mouseReleased(MouseEvent e) {
//System.out.println(e.paramString());
}
/** Updates the slider position */
public void mouseDragged(MouseEvent e) {
//System.out.println(e.paramString());
updatePosition(e);
}
/** Present to implement MouseMovementListener, currently ignored */
public void mouseMoved(MouseEvent e) {
//System.out.println(e.paramString());
}
/** Recalculate the position and value of the slider given the new mouse position */
private void updatePosition(MouseEvent e) {
int x = e.getX();
if (x < 0) x = 0;
if (x >= getBounds().width) x = getBounds().width - 1;
float dist = (float) x / (float) (getBounds().width - 1);
setValue(lower + dist*(upper - lower));
}
/** the last position where the arrow was drawn */
private int oldxval;
/** update the slider */
public void update(Graphics g) {
g.setColor(Color.black);
g.drawLine(oldxval, 0, oldxval, getBounds().height - 1);
g.drawLine(oldxval, 0, oldxval - 4, 4);
g.drawLine(oldxval, 0, oldxval + 4, 4);
g.setColor(Color.white);
int xval = (int) Math.floor((val - lower) * (getBounds().width - 1) / (upper - lower));
g.drawLine(xval, 0, xval, getBounds().height - 1);
g.drawLine(xval, 0, xval - 4, 4);
g.drawLine(xval, 0, xval + 4, 4);
oldxval = xval;
}
/** Redraw the slider */
public void paint(Graphics g) {
// System.out.println("ArrowSlider.paint in");
// Test66 hangs between ArrowSlider.paint in and out
// but not with DebugGraphics in constructor
// the reason was JDC bug # 4252578 and the fact that
// lower, upper and val were NaNs
if (val != val || lower != lower || upper != upper) return;
g.setColor(Color.black);
g.fillRect(0, 0, getBounds().width, getBounds().height);
g.setColor(Color.white);
int xval = (int) Math.floor((val - lower) * (getBounds().width - 1) / (upper - lower));
g.drawLine(xval, 0, xval, getBounds().height - 1);
g.drawLine(xval, 0, xval - 4, 4);
g.drawLine(xval, 0, xval + 4, 4);
oldxval = xval;
// System.out.println("ArrowSlider.paint out");
}
}