Staging
v0.5.0
v0.5.0
https://repo1.maven.org/maven2/org/prefuse/prefuse
JValueSlider.java
package prefuse.util.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import prefuse.util.StringLib;
/**
* Swing component that contains a slider, and title label, and editable
* text box displaying the slider value.
*
* @author <a href="http://jheer.org">jeffrey heer</a>
*/
public class JValueSlider extends JComponent {
private Number m_min, m_max, m_value;
private boolean m_ignore = false;
private JLabel m_label;
private JSlider m_slider;
private JTextField m_field;
private List m_listeners;
private int m_smin = 0;
private int m_srange = 100;
/**
* Create a new JValueSlider.
* @param title the title label of the slider component
* @param min the value associated with the minimum slider position
* @param max the value associated with the maximum slider position
* @param value the value associated with the starting slider position
*/
public JValueSlider(String title, double min, double max, double value) {
this(title, new Double(min), new Double(max), new Double(value));
}
/**
* Create a new JValueSlider.
* @param title the title label of the slider component
* @param min the value associated with the minimum slider position
* @param max the value associated with the maximum slider position
* @param value the value associated with the starting slider position
*/
public JValueSlider(String title, float min, float max, float value) {
this(title, new Float(min), new Float(max), new Float(value));
}
/**
* Create a new JValueSlider.
* @param title the title label of the slider component
* @param min the value associated with the minimum slider position
* @param max the value associated with the maximum slider position
* @param value the value associated with the starting slider position
*/
public JValueSlider(String title, int min, int max, int value) {
this(title, new Integer(min), new Integer(max), new Integer(value));
m_smin = min;
m_srange = max-min;
m_slider.setMinimum(min);
m_slider.setMaximum(max);
setValue(new Integer(value));
}
/**
* Create a new JValueSlider.
* @param title the title label of the slider component
* @param min the value associated with the minimum slider position
* @param max the value associated with the maximum slider position
* @param value the value associated with the starting slider position
*/
public JValueSlider(String title, long min, long max, long value) {
this(title, new Long(min), new Long(max), new Long(value));
}
/**
* Create a new JValueSlider.
* @param title the title label of the slider component
* @param min the value associated with the minimum slider position
* @param max the value associated with the maximum slider position
* @param value the value associated with the starting slider position
*/
public JValueSlider(String title, Number min, Number max, Number value) {
m_min = min;
m_max = max;
m_value = value;
m_slider = new JSlider();
m_label = new JLabel(title);
m_field = new JTextField();
m_listeners = new ArrayList();
m_field.setBorder(null);
setSliderValue();
setFieldValue();
initUI();
}
/**
* Initialize the UI
*/
protected void initUI() {
m_slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
if ( m_ignore ) return;
m_ignore = true;
// update the value
m_value = getSliderValue();
// set text field value
setFieldValue();
// fire event
fireChangeEvent();
m_ignore = false;
}
});
m_field.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
if ( m_ignore ) return;
m_ignore = true;
Number v = getFieldValue();
if ( v != m_value ) {
// update the value
m_value = v;
// set slider value
setSliderValue();
}
// fire event
fireChangeEvent();
m_ignore = false;
}
});
m_field.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
String s = m_field.getText();
if ( isTextObscured(m_field, s) )
m_field.setToolTipText(s);
}
public void mouseExited(MouseEvent e) {
m_field.setToolTipText(null);
}
});
m_label.addMouseListener(new MouseAdapter() {
public void mouseEntered(MouseEvent e) {
String s = m_label.getText();
if ( isTextObscured(m_label, s) )
m_label.setToolTipText(s);
}
public void mouseExited(MouseEvent e) {
m_label.setToolTipText(null);
}
});
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(m_label);
add(m_slider);
add(m_field);
}
/**
* Check if any label text is obscured.
*/
private static boolean isTextObscured(JComponent c, String s) {
Graphics g = c.getGraphics();
FontMetrics fm = g.getFontMetrics(c.getFont());
int sw = fm.stringWidth(s);
return ( sw > c.getWidth() );
}
// ------------------------------------------------------------------------
/**
* Get the current value ssociated with the slider position.
* @return the current value
*/
public Number getValue() {
return m_value;
}
/**
* Set the current value ssociated with the slider position.
* @param value the current value to set
*/
public void setValue(Number value) {
m_value = value;
setSliderValue();
setFieldValue();
}
/**
* Compute the current slider value from the current slider position
* @return the current value
*/
private Number getSliderValue() {
if ( m_value instanceof Integer ) {
int val = m_slider.getValue();
int min = m_min.intValue();
int max = m_max.intValue();
return new Integer(min + (val-m_smin)*(max-min)/m_srange);
} else if ( m_value instanceof Long ) {
int val = m_slider.getValue();
long min = m_min.longValue();
long max = m_max.longValue();
return new Long(min + (val-m_smin)*(max-min)/m_srange);
} else {
double f = (m_slider.getValue()-m_smin)/(double)m_srange;
double min = m_min.doubleValue();
double max = m_max.doubleValue();
double val = min + f*(max-min);
return (m_value instanceof Double ? (Number)new Double(val)
: new Float((float)val));
}
}
/**
* Private set the slider position based upon the current value
*/
private void setSliderValue() {
int val;
if ( m_value instanceof Double || m_value instanceof Float ) {
double value = m_value.doubleValue();
double min = m_min.doubleValue();
double max = m_max.doubleValue();
val = m_smin + (int)Math.round(m_srange*((value-min)/(max-min)));
} else {
long value = m_value.longValue();
long min = m_min.longValue();
long max = m_max.longValue();
val = m_smin + (int)((m_srange*(value-min))/(max-min));
}
m_slider.setValue(val);
}
/**
* Get the value in the text field.
* @return the current text field value
*/
private Number getFieldValue() {
if ( m_value instanceof Double || m_value instanceof Float ) {
double v;
try {
v = Double.parseDouble(m_field.getText());
} catch ( Exception e ) {
// TODO handle exception
return m_value;
}
if ( v < m_min.doubleValue() || v > m_max.doubleValue() ) {
// TODO handle exception
return m_value;
}
return m_value instanceof Double ? (Number)new Double(v)
: new Float((float)v);
} else {
long v;
try {
v = Long.parseLong(m_field.getText());
} catch ( Exception e ) {
// TODO handle exception
return m_value;
}
if ( v < m_min.longValue() || v > m_max.longValue() ) {
// TODO handle exception
return m_value;
}
return m_value instanceof Long ? (Number)new Long(v)
: new Integer((int)v);
}
}
/**
* Set the text field value based upon the current value.
*/
private void setFieldValue() {
String text;
if ( m_value instanceof Double || m_value instanceof Float )
text = StringLib.formatNumber(m_value.doubleValue(),3);
else
text = String.valueOf(m_value.longValue());
m_field.setText(text);
}
// ------------------------------------------------------------------------
/**
* Add a change listener to listen to this component.
* @param cl the change listener to add
*/
public void addChangeListener(ChangeListener cl) {
if ( !m_listeners.contains(cl) )
m_listeners.add(cl);
}
/**
* Remove a change listener listening to this component.
* @param cl the change listener to remove
*/
public void removeChangeListener(ChangeListener cl) {
m_listeners.remove(cl);
}
/**
* Fire a change event to listeners.
*/
protected void fireChangeEvent() {
Iterator iter = m_listeners.iterator();
ChangeEvent evt = new ChangeEvent(this);
while ( iter.hasNext() ) {
ChangeListener cl = (ChangeListener)iter.next();
cl.stateChanged(evt);
}
}
// ------------------------------------------------------------------------
/**
* @see java.awt.Component#setBackground(java.awt.Color)
*/
public void setBackground(Color c) {
m_field.setBackground(c);
m_label.setBackground(c);
m_slider.setBackground(c);
super.setBackground(c);
}
/**
* @see java.awt.Component#setForeground(java.awt.Color)
*/
public void setForeground(Color c) {
m_field.setForeground(c);
m_label.setForeground(c);
m_slider.setForeground(c);
super.setForeground(c);
}
/**
* @see java.awt.Component#setFont(java.awt.Font)
*/
public void setFont(Font f) {
m_field.setFont(f);
m_label.setFont(f);
m_slider.setFont(f);
super.setFont(f);
}
/**
* @see javax.swing.JComponent#setPreferredSize(java.awt.Dimension)
*/
public void setPreferredSize(Dimension d) {
int fw = Math.min(40, d.width/5);
int lw = Math.min(100, (d.width-fw)/2);
int sw = d.width-fw-lw;
super.setPreferredSize(d);
Dimension dd = new Dimension(lw, d.height);
m_label.setPreferredSize(dd);
dd = new Dimension(sw, d.height);
m_slider.setPreferredSize(dd);
dd = new Dimension(fw, d.height);
m_field.setPreferredSize(dd);
}
} // end of class JValueSlider