Question

I have jSpinner using for time picking. Problem 1: User can edited hour minutes and second seperator ":" and can write extra digits like "123" Problem 2: model get always current time. I want "00:00:00" When i write this in code instead "hh:mm:ss" user can't edit the values.

My Code is;

spinner1 = new javax.swing.JSpinner();
SpinnerDateModel spinnermodel = new SpinnerDateModel();
spinnermodel.setCalendarField(Calendar.MINUTE);
spinner1 .setModel(spinnermodel);
spinner1 .setEditor(new JSpinner.DateEditor(spinner1 , "hh:mm:ss"));

Any help appreciated. Thanks.

Was it helpful?

Solution

Problem 1: User can edited hour minutes and second seperator ":" and can write extra digits like "123"

You can use the editor's formatter to accomplish this through getTextField() method:

JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "HH:mm:ss");
DateFormatter formatter = (DateFormatter)editor.getTextField().getFormatter();
formatter.setAllowsInvalid(false); // this makes what you want
formatter.setOverwriteMode(true);

The text field is in fact a JFormattedTextField with a DateFormatter as formatter. Take a look to How to Use Formatted Text Fields for a better understanding on how to work with this component.

Note the pattern used when the editor is created. It's "HH:mm:ss" because of your 2nd requirement.

Problem 2: model get always current time. I want "00:00:00"

You need to provide to your spinner with an initial date at 12 PM (24 hours) which will be translated in "00:00:00":

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 24);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);

SpinnerDateModel model = new SpinnerDateModel();
model.setValue(calendar.getTime());

JSpinner spinner = new JSpinner(model);

Example

Here is a quite simple example to test what I've said. Hope it be helpful.

import java.util.Calendar;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.SwingUtilities;
import javax.swing.text.DateFormatter;

public class Demo {

    private void createAndShowGUI() {

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 24); // 24 == 12 PM == 00:00:00
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        SpinnerDateModel model = new SpinnerDateModel();
        model.setValue(calendar.getTime());

        JSpinner spinner = new JSpinner(model);

        JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "HH:mm:ss");
        DateFormatter formatter = (DateFormatter)editor.getTextField().getFormatter();
        formatter.setAllowsInvalid(false); // this makes what you want
        formatter.setOverwriteMode(true);

        spinner.setEditor(editor);

        JPanel content = new JPanel();
        content.add(spinner);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {                
                new Demo().createAndShowGUI();
            }
        });
    }    
}

Edit

When user try manually write hours or minutes (not using arrows) some logical problem ocures i think. Example i write 12 but spinner shows 21.

First off sorry I didn't note that before. This creepy behaviour happens because formatter's overwrite mode property is set to false somewhere during JSpinner.DateEditor's initialization (but couldn't find where). This property is true by default according to javadoc. To solve this you only need to add this line (I've also edited my code above):

formatter.setOverwriteMode(true);

OTHER TIPS

The JSpinner class was not specifically designed to be used as a time picker, so it can be difficult to customize its behavior. The TimePicker class in the LGoodDatePicker library could be a better alternative for this usage.

You mentioned wanting to display the minutes and seconds in your format. The TimePicker format can be customized using the java.time DateTimeFormatter class.

Project Home page: https://github.com/LGoodDatePicker/LGoodDatePicker .

Screenshots of the components and the demo application are pasted below.

DateTimePicker screenshot Demo screenshot

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top