0

I've been using the below technique to disable editing for JSpinners in the past. It doesn't seem to work with the JTextField in a DateEditor, however. Is there a reason that this editor.getTextField().setEditable(false) doesn't work in this scenario? And is there a way to get it to work?

Driver Class

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

Swing Class

public class ClockFrame extends JFrame implements ActionListener {

    private static final long serialVersionUID = -7009835158496820266L;
    public static final Dimension SIZE = new Dimension(400, 200);

    private final Timer secondsTimer = new Timer(1000, this);
    private final FluentGridBagConstraints gbc = new FluentGridBagConstraints();
    private JPanel mainPanel;
    private JLabel clockLabel;
    private JSpinner newAlarmHourSpinner, newAlarmMinuteSpinner, newAlarmAMPMSpinner;

    public ClockFrame() {
        super();
        setLayout(new GridBagLayout());
        initializeGUIComponents();
        setPreferredSize(SIZE);
        setResizable(false);
        setTitle(Constants.APPLICATION_NAME);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
        secondsTimer.start();
    }



    private void initializeGUIComponents() {
        mainPanel = new JPanel(new GridBagLayout());

        clockLabel = new JLabel();
        updateClock();
        mainPanel.add(clockLabel, gbc.setXY(0, 0));

        newAlarmHourSpinner = new JSpinner();
        newAlarmHourSpinner.setModel(new CyclingSpinnerNumberModel(9, 1, 12, 1));
        DefaultEditor editor = new JSpinner.DefaultEditor(newAlarmHourSpinner);
        editor.getTextField().setColumns(2);
        editor.getTextField().setEditable(false);
        newAlarmHourSpinner.setEditor(editor);
        mainPanel.add(newAlarmHourSpinner, gbc.reset().setXY(0, 1));

        newAlarmMinuteSpinner = new JSpinner();
        SpinnerDateModel model = new SpinnerDateModel();
        model.setCalendarField(Calendar.MINUTE);
        newAlarmMinuteSpinner.setModel(model);
        DateEditor dateEditor = new JSpinner.DateEditor(newAlarmMinuteSpinner, "mm");
        editor.getTextField().setColumns(2);
        editor.getTextField().setEditable(false);
        newAlarmMinuteSpinner.setEditor(dateEditor);
        mainPanel.add(newAlarmMinuteSpinner, gbc.reset().setXY(1, 1));

        newAlarmAMPMSpinner = new JSpinner();
        newAlarmAMPMSpinner.setModel(new CyclingSpinnerListModel("AM", "PM"));
        editor = new JSpinner.DefaultEditor(newAlarmAMPMSpinner);
        editor.getTextField().setColumns(2);
        editor.getTextField().setEditable(false);
        newAlarmAMPMSpinner.setEditor(editor);
        mainPanel.add(newAlarmAMPMSpinner, gbc.reset().setXY(2, 1));

        add(mainPanel, gbc.reset().setXY(0, 0));
    }

    private void updateClock() {
        clockLabel.setText(Alarm.TIME_FORMAT.format(new Date()));
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        if(event.getSource() == secondsTimer) {
            updateClock();
        }
    }


}
asteri
  • 11,402
  • 13
  • 60
  • 84

1 Answers1

2

Make sure your GUI is created on the EDT.

It works fine for me when I run the SpinnerDemo code from the Swing tutorial on How to Use Spinners with the following change:

    ftf = getTextField(spinner);
    ftf.setEditable(false);

However, I also had problems with my simple spinner test program when I didn't create the GUI on the EDT.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Hm... Yeah, I tried doing it precisely that way as well. How do I ensure that the GUI is created on a specific timezone? – asteri Oct 12 '13 at 05:23
  • EDT; see [event dispatch thread](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html). – trashgod Oct 12 '13 at 05:25
  • @trashgod Ah, I see. I threw the GUI initialization into an `invokeLater` block and it didn't help. Thanks for the clarification. – asteri Oct 12 '13 at 05:28
  • 1
    @JeffGohlke, `I threw the GUI initialization into an invokeLater block and it didn't help.` - Did you download the tutorial example and try it? Post your `SSCCE` that demonstrates the problem even when the frame and spinner are being created properly on the EDT. – camickr Oct 12 '13 at 05:33