This is my GUI:
Below is a SSCCE that will produce exactly this. The JSlider
is connected to the JTextField
showing values between 0 and 100.
I have set the following to make it stop on intervals of 10. It works, but the textfield will still show values between the 10s (Like 73) when dragging, and then adjust it when i let go of the slider. Is there a way to ONLY show tens, even when dragging?
js.setMinorTickSpacing(10);
js.setSnapToTicks(true);
SSCCE:
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.text.NumberFormat;
import javax.swing.*;
import javax.swing.event.*;
import net.miginfocom.swing.MigLayout;
public class SSCCE {
public static void main(String[] args) {
JFrame frame = new JFrame("SSCCE JSlider + JTextField");
JPanel panel = new JPanel(new MigLayout("", "[200!][100!]", ""));
final JSlider js = new JSlider();
final JFormattedTextField tf = new JFormattedTextField(NumberFormat.getNumberInstance());
js.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
tf.setText(String.valueOf(js.getValue()));
}
});
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent ke) {
String typed = tf.getText();
js.setValue(0);
if (!typed.matches("\\d+")) {
return;
}
int value = Integer.parseInt(typed);
js.setValue(value);
}
});
js.setMinorTickSpacing(10);
js.setSnapToTicks(true);
panel.add(js);
panel.add(tf, "grow");
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
}
It works, but the textfield will still show values between the 10s (Like 73) when dragging, and then adjust it when i let go of the slider. Is there a way to ONLY show tens, even when dragging?
Simply round off current JSlider
value to the nearest 10 and than set the JTextField
to that number:
js.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if(js.getValueIsAdjusting()) {//slider value is still being adjusted
int num=(int)(Math.rint((double) js.getValue() / 10) * 10);//round to nearest 10
tf.setText(String.valueOf(num));//set textfield with value of nearest 10
} else {//slider value has been set/no adjustments happenening
tf.setText(String.valueOf(js.getValue()));
}
}
});
Also have a read on Concurrency in Swing, specifically on Event Dispatch thread
(EDT), which requires us to create and manipulate all Swing components on the EDT via SwingUtilities.invokeXXX
block:
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//create/manipulate UI, components etc here
}
});