简体   繁体   中英

How to read the time from JSpinner using the Event ChangeListener() and Print it on the Console?

I want help to read the time from the JSpinner using the event ChangeListener. The problem is that the time is printed twice when I spin with one step . The Output, when I run the below code within the main program, is 00:00, 01:00 for a single spin up. Could you help me to know the reason and how it could be fixed to print only one value when I spin up or down? thanks..see Example

public class SpinnerTest {

private JFrame frame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                SpinnerTest window = new SpinnerTest();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public SpinnerTest() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    JPanel groupLayoutPanel = new JPanel();

    JSpinner spinner = new JSpinner(new SpinnerDateModel(new Date(1591563600775L), null, null, Calendar.HOUR_OF_DAY));
    spinner.addChangeListener(new ChangeListener() {
        public void stateChanged(ChangeEvent e) {
            JSpinner spinner = (JSpinner)e.getSource();
            Date sdate= (Date)spinner.getValue();
            String pattern = "HH:mm";
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
            String date = simpleDateFormat.format(sdate);
            System.out.println(date);

        }
    });
    JSpinner.DateEditor de= new JSpinner.DateEditor(spinner,"HH:mm");
    spinner.setEditor(de);

    GroupLayout grouplayout= new GroupLayout(groupLayoutPanel);
    grouplayout.setHorizontalGroup(
        grouplayout.createParallelGroup(Alignment.LEADING)
            .addGroup(grouplayout.createSequentialGroup()
                .addGap(83)
                .addComponent(spinner, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(321, Short.MAX_VALUE))
    );
    grouplayout.setVerticalGroup(
        grouplayout.createParallelGroup(Alignment.LEADING)
            .addGroup(grouplayout.createSequentialGroup()
                .addGap(25)
                .addComponent(spinner, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(216, Short.MAX_VALUE))
    );
    groupLayoutPanel.setLayout(grouplayout);
    frame = new JFrame();
    frame.setContentPane(groupLayoutPanel);
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

Could you help me to know the reason and how it could be fixed to print only one value when I spin up or down

You need to check the getValueIsAdjusting() property of the state listener to determine if the adjustment has finished.

Read the section from the Swing tutorial on How to Write a ChangeListener for more information and examples.

Edit:

The double event is only generated the first time a spinner button is clicked.

Here is a workaround that seems to work. I set the editor and commit the editor before adding the ChangeListener:

JSpinner spinner = new JSpinner(new SpinnerDateModel(new Date(1591563600775L), null, null, Calendar.HOUR_OF_DAY));
JSpinner.DateEditor de= new JSpinner.DateEditor(spinner,"HH:mm");
spinner.setEditor(de);

try
{
    spinner.commitEdit();
}
catch(Exception e) {}

spinner.addChangeListener(…);

The first time you change the value of the JSpinner , two change events are fired.

The first change event is because the initial value of the model is set as the value of the editor. That's why the first value printed is the initial value of the model.

The second change event is fired because the value is changed due to the user action. Hence the second value printed is the new value that results from the user change.

That's why the answer from camickr works. He forces the first change event to fire by calling method commitEdit() before adding the ChangeListener to the JSpinner . So when the user changes the spinner value the first time, only the second change event fires.

If you add the ChangeListener before calling method commitEdit() , then when the GUI is first displayed, you will see the initial value printed before actually interacting with the JSpinner .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM