Java: link JSlider and JTextfield for float value
Asked Answered
S

1

4

what is the best and easiest way to link a JSlider and a JTextField so that if one changes, the other gets updated too, but there is no recursive loop?

thanks!

Saraisaraiya answered 10/10, 2009 at 17:52 Comment(1)
related https://mcmap.net/q/810972/-jslider-for-doublesTelencephalon
S
15

Here's a quick and dirty demo:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Main {
    public static void main(String[] args) {
        final JFrame frame = new JFrame();
        final JTextField text = new JTextField(20);
        final JSlider slider = new JSlider(0, 100, 0);
        slider.addChangeListener(new ChangeListener(){
            @Override
            public void stateChanged(ChangeEvent e) {
                text.setText(String.valueOf(slider.getValue()));
            }
        });
        text.addKeyListener(new KeyAdapter(){
            @Override
            public void keyReleased(KeyEvent ke) {
                String typed = text.getText();
                slider.setValue(0);
                if(!typed.matches("\\d+") || typed.length() > 3) {
                    return;
                }
                int value = Integer.parseInt(typed);
                slider.setValue(value);
            }
        });
        frame.setLayout(new BorderLayout());
        frame.add(text, BorderLayout.NORTH);
        frame.add(slider, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.pack();
    }
}

EDIT

And if you want to use floats (as the title suggests), you could extends the JSlider class like this:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.text.DecimalFormat;

public class Main {
    public static void main(String[] args) {
        final DecimalFormat df = new DecimalFormat("0.####");
        final JFrame frame = new JFrame();
        final JTextField text = new JTextField(20);
        final DoubleJSlider slider = new DoubleJSlider(0, 100, 0, 1000);
        slider.addChangeListener(new ChangeListener(){
            @Override
            public void stateChanged(ChangeEvent e) {
                text.setText(df.format(slider.getScaledValue()));
            }
        });
        text.addKeyListener(new KeyAdapter(){
            @Override
            public void keyReleased(KeyEvent ke) {
                String typed = text.getText();
                slider.setValue(0);
                if(!typed.matches("\\d+(\\.\\d*)?")) {
                    return;
                }
                double value = Double.parseDouble(typed)*slider.scale;
                slider.setValue((int)value);
            }
        });
        frame.setLayout(new BorderLayout());
        frame.add(text, BorderLayout.NORTH);
        frame.add(slider, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.pack();
    }
}

class DoubleJSlider extends JSlider {

    final int scale;

    public DoubleJSlider(int min, int max, int value, int scale) {
        super(min, max, value);
        this.scale = scale;
    }

    public double getScaledValue() {
        return ((double)super.getValue()) / this.scale;
    }
}

The example above denotes the interval between 0 and 0.1 in 100 steps.

This (again) is just a quick and dirty example, but might help you on your way.

Seena answered 10/10, 2009 at 18:3 Comment(4)
@Guillaume, ah, it just occurred to me that the word float is mentioned in the topic title (and not in the question itself). But, since clamp accepted my answer, it seems the conversion to using floats wasn't all that hard, luckily. :)Seena
Well it's not trivial :) And the 'float' tag should be removed from the question: I though my quest for doing a slider using float was over, but it was not !Donar
This is wonderful. You're the only guy on the internet that has posted a short answer to this question.Hsu
For what it's worth, Guillaume was wrong; this answer including the material about how to add float-like behavior was very helpful to me AND, the suggestion the "float tag" should be removed is not accurate since a DecimalFormat solution can be addapted for any resolution you want (for the vast majority of use-cases, though perhaps not to the full range of the type). However, clearly a new class should be created to handle this for reasons having to do with labels and the tick marks...Intrigante

© 2022 - 2024 — McMap. All rights reserved.