Mr.Robot Mr.Robot - 4 months ago 39
Java Question

JSpinner default changes years instead of days

Problem: When

dateSpin
arrow is clicked the spinner changes years instead of days. I would like to make it default so only days are changed + make it so the user cannot enter his own input into the spinner field.

import javax.swing.*;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.util.Calendar;
import java.util.Date;

public class Test1 extends JFrame
{

public static void main(String[] args)
{
Test1 frame1 = new Test1();
frame1.setVisible(true);
}

public Test1()
{
super("Test");
setLayout(new FlowLayout());

setSize(300,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);

JSpinner spinner = new JSpinner();
Date date = new Date();
spinner.setModel(new SpinnerDateModel(date, null, null, Calendar.DAY_OF_MONTH));

JSpinner.DateEditor dateEditor = new JSpinner.DateEditor(spinner, "yyyy/MM/dd");

spinner.setEditor(dateEditor);

add(spinner);

}

}


In oracle docs this problem is mentioned:


Note, however, that some types of look and feel ignore the specified field, and instead change the field that appears selected.


However, as I am not fluent in Java I don't understand how to fix this.

Answer

It's not a good solution, but you could just make sure that the caret position of the textfield is always at the end (the fact that you want the spinner to be uneditable maybe makes this technique a bit more tolerable):

dateEditor.getTextField().setEditable(false);
dateEditor.getTextField().addCaretListener(new CaretListener() {
    @Override
    public void caretUpdate(CaretEvent e) {
        int pos = dateEditor.getTextField().getDocument().getLength();
        if (e.getDot() != pos) {
            dateEditor.getTextField().setCaretPosition(pos);
        }
    }
});

This worked for me using the following LaFs: Metal, Nimbus, Motif, Windows, Windows Classic. (That's all the LaFs I can test right now)