making a playable jslider in java

2019-03-02 12:16发布

问题:

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.

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);
  }


}

回答1:

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...

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