Search code examples
javaswingjspinnerjformattedtextfield

combine JSpinner with JFormattedTextField


I want to make a customized JSpinner for editing day hours. I want the format to be 1HH:mm:ss a1, I already get this part.

I also want to add in some functionalities of JFormattedTextField:

  1. setplaceHolderCharacter('_')

    For example the time is 09:23:45, when the user delete 09,

    __:23:45 shows on screen.

  2. input restriction

    For example the time is 09:23:45, when the user delete 09,

    and try to enter anything, he can only enter numbers, no letter is allowed.

Any help would be appreciated!


Solution

  • There may be a better solution with JFormattedTextField, but here is one with built-in java classes. Also this doesn't fit your requirement replacing the deleted numbers with '_'. But you can select the seconds and then spinn the seconds instead of the hours. Also there is only almost an input restriction. You may write letters, but no ChangeEvent will be fired. Additional bonus: You don't have to think about when to change to the next hour after 60 minutes or something and it works, of course, with everything a Date can have (so spinning months or years is possible, too)

    public class HourSpinner implements ChangeListener {
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new HourSpinner();
            }
        });
    }
    
    public HourSpinner() {
    
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(100, 70);
        frame.setLocationRelativeTo(null);
    
        Container contentPane = frame.getContentPane();
    
        JSpinner dateSpinner = new JSpinner(new SpinnerDateModel(new Date(), null, null, Calendar.HOUR_OF_DAY));
        DateEditor editor = new JSpinner.DateEditor(dateSpinner, "HH:mm:ss");
        dateSpinner.setEditor(editor);
        dateSpinner.addChangeListener(this);
    
        contentPane.add(dateSpinner);
    
        frame.setVisible(true);
    
    }
    
    @Override
    public void stateChanged(ChangeEvent e) {
        JSpinner source = (JSpinner) e.getSource();
        System.out.println(source.getValue());
    }
    
    }