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