Search code examples
javaswingwindowbuilderjslider

making a playable jslider in java


I'm making a grapher by using eclipse and windowbuilder that gets an mathematical expression from the user(for example ADD(MUL(X,Y),Z) ) and at one point asks the user to designate one of its variables as time . then the user will be asked to choose the starting point and the range of that variable. then the program will show a frame (and a panel) that has a jslider and a play button .when the user clicks the button the program should start drawing the expression . It should look like a Gapminder chart .

I have checked other questions about updating jsliders but they are usually about a music player slider or a slider that just changes with time(without the graphing part).

my question is specifically about the updating of slider( the intervals can be 1 ) but it would be great if you could also guide how can I make that playable slider that it could also be used for the graphing part.

enter image description here this the code so far:

package progGUI;

import java.awt.BorderLayout;

public class CanvasFrame extends JFrame {

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {

                CanvasFrame frame = new CanvasFrame();
                frame.setVisible(true);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public CanvasFrame() {
    setTitle("Graph");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 700, 542);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);

    JSlider slider = new JSlider();
    slider.setPaintLabels(true);
    slider.setMinorTickSpacing(1);
    slider.setMajorTickSpacing(5);
    slider.setPaintTicks(true);


    JLabel lblEnteredExpression = new JLabel("Entered Expression");

    JLabel lblVaraibles = new JLabel("Variables");

    JFormattedTextField formattedTextField = new JFormattedTextField();

    JFormattedTextField formattedTextField_1 = new JFormattedTextField();

    JPanel panel = new JPanel();
    panel.setBackground(Color.WHITE);

    JButton btnNewButton = new JButton("Play");
    GroupLayout gl_contentPane = new GroupLayout(contentPane);
    gl_contentPane.setHorizontalGroup(
        gl_contentPane.createParallelGroup(Alignment.LEADING)
            .addGroup(gl_contentPane.createSequentialGroup()
                .addContainerGap()
                .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 453, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED, 51, Short.MAX_VALUE)
                        .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
                            .addComponent(lblEnteredExpression, Alignment.TRAILING)
                            .addComponent(lblVaraibles)
                            .addComponent(formattedTextField, GroupLayout.PREFERRED_SIZE, 119, GroupLayout.PREFERRED_SIZE)
                            .addComponent(formattedTextField_1, GroupLayout.PREFERRED_SIZE, 123, GroupLayout.PREFERRED_SIZE))
                        .addGap(57))
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addComponent(btnNewButton, GroupLayout.PREFERRED_SIZE, 87, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(slider, GroupLayout.PREFERRED_SIZE, 454, GroupLayout.PREFERRED_SIZE)
                        .addContainerGap())))
    );
    gl_contentPane.setVerticalGroup(
        gl_contentPane.createParallelGroup(Alignment.TRAILING)
            .addGroup(gl_contentPane.createSequentialGroup()
                .addGap(18)
                .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addComponent(lblEnteredExpression)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(formattedTextField_1, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(ComponentPlacement.UNRELATED)
                        .addComponent(lblVaraibles)
                        .addPreferredGap(ComponentPlacement.RELATED)
                        .addComponent(formattedTextField, GroupLayout.PREFERRED_SIZE, 20, GroupLayout.PREFERRED_SIZE))
                    .addComponent(panel, GroupLayout.PREFERRED_SIZE, 350, GroupLayout.PREFERRED_SIZE))
                .addGroup(gl_contentPane.createParallelGroup(Alignment.LEADING)
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addGap(31)
                        .addComponent(btnNewButton))
                    .addGroup(gl_contentPane.createSequentialGroup()
                        .addGap(18)
                        .addComponent(slider, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
                .addGap(402))
    );
    contentPane.setLayout(gl_contentPane);
  }


}

Solution

  • User a javax.swing.Timer to schedule a periodical call back, which updates the JSlider's value. Use a ChangeListener attached to the JSlider to drive the graph, for example...

    Slider

    import java.awt.EventQueue;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    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 Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Timer timer;
            private JSlider slider;
            private JButton button;
            private JTextField field;
    
            public TestPane() {
                slider = new JSlider();
                field = new JTextField(4);
                button = new JButton(">");
                add(slider);
                add(button);
                add(field);
    
                slider.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        field.setText(Integer.toString(slider.getValue()));
                    }
                });
                slider.setValue(0);
    
                button.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        if (timer.isRunning()) {
                            stopTheClock();
                        } else {
                            startTheClock();
                        }
                    }
                });
                timer = new Timer(500, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        int value = slider.getValue() + 1;
                        if (value >= slider.getMaximum()) {
                            stopTheClock();
                        } else {
                            slider.setValue(value);
                        }
                    }
                });
            }
    
            protected void startTheClock() {
                slider.setValue(0);
                timer.start();
                button.setText("[]");
            }
    
            protected void stopTheClock() {
                timer.stop();
                button.setText(">");
            }
    
        }
    
    }
    

    See How to use Swing Timers and How to Use Sliders for more details