Jslider should fire change event when it come to rest

5.2k views Asked by At

I have one slider in my JAVA application.I have written change listener for that slider. Here is the code i have written

jSlider = new JSlider(JSlider.HORIZONTAL,0,30,2);
        jSlider.setFont(new Font("Dialog", Font.BOLD, 10));
        jSlider.setMinorTickSpacing(1);
        jSlider.setMajorTickSpacing(2);
        jSlider.setPaintTicks(true);
        jSlider.setPaintLabels(true);
        jSlider.setBounds(76, 564, 586, 55);
        jSlider.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent arg0) {
                // TODO Auto-generated method stub
                textField.setText(String.valueOf(jSlider.getValue()));
            }
        });
        getContentPane().add(jSlider);  

This code gives the continuous changing values of the slider.

but i want the value of rest position of the slider. What should I write to get the value only for the rest position?

2

There are 2 answers

0
rachana On BEST ANSWER

We can also use

jSlider.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                // TODO Auto-generated method stub
                JSlider source = (JSlider)e.getSource();
                if(!source.getValueIsAdjusting())
                {
                    //textField.setText(String.valueOf(source.getValue()));
                    int gain = source.getValue();
                    //System.out.println("***** GAIN ***** "+gain);
                    GetGain g = new GetGain(gain);
                }
            }
        });

Above code also gives the value for the rest position of the slider.

0
MadProgrammer On

Basically, what you can do is insert a "forced delay" between the time the stateChanged event is raised and the time that the textField is updated.

This basically means we are waiting for a fixed period of time between when the stateChanged method was last called BEFORE we try and update the textField.

Because we don't want to block the Event Dispatching Thread, because it would stop any new events from being processed, I've used a javax.swing.Timer.

Basically, whenever the stateChanged method is called, I restart the timer. Once the events stop, the timer is allowed to complete and triggers a actionPerformed event, which allows us to update the textField...easy ;)

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestSlider01 {

    public static void main(String[] args) {
        new TestSlider01();
    }

    public TestSlider01() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JSlider slider;
        private JTextField textField;

        private Timer slideTimer;

        public TestPane() {

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            textField = new JTextField(20);

            slider = new JSlider(JSlider.HORIZONTAL, 0, 30, 2);
            slider.setFont(new Font("Dialog", Font.BOLD, 10));
            slider.setMinorTickSpacing(1);
            slider.setMajorTickSpacing(2);
            slider.setPaintTicks(true);
            slider.setPaintLabels(true);
            slider.addChangeListener(new ChangeListener() {

                @Override
                public void stateChanged(ChangeEvent arg0) {
//                    textField.setText(String.valueOf(slider.getValue()));
                    slideTimer.restart();
                }
            });
            slideTimer = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    textField.setText(String.valueOf(slider.getValue()));
                }
            });
            slideTimer.setRepeats(false);
            add(slider, gbc);
            add(textField, gbc);
        }
    }
}

Now, I've deliberately used a largish value for the delay, you may wish to play with it...

Also, setBounds is a very bad idea. I would invest the time into learning the layout manager API, it will save you a lot of heart-ache in the long run ;)