在JSpinner中设置DateEditor的步骤

时间:2012-04-27 15:05:21

标签: java jspinner

如何为JSpinner指定步骤? (例如10分钟而不是1分钟)

有一个模型允许选择数字步长

SpinnerNumberModel(value, min, max, step); 

但如何为日期设置?

此代码

JSpinner timeSpinner = new JSpinner( new SpinnerDateModel() );
DateEditor timeEditor = new DateEditor(timeSpinner, "HH:mm:ss");
timeSpinner.setEditor(timeEditor);
timeSpinner.setValue(new Date()); // will only show the current time

(来自这个答案Is there any good and free Date AND Time Picker available for Java Swing?

仅允许编辑时间,但步骤始终为1小时,1分钟或1秒,具体取决于是否指定了“HH”,“HH:mm”或“HH:mm:ss”。


有没有简单的方法可以让min,max和step分钟?

由于

3 个答案:

答案 0 :(得分:1)

使用DateEditor.getModel()获取提供setStartsetEndsetCalendarField的{​​{3}}。

答案 1 :(得分:0)

正如您在SpinnerDateModel的代码中看到的那样:

public Object getNextValue() {
    Calendar cal = Calendar.getInstance(); //Current date.
    cal.setTime(value.getTime()); //Set the date to the current value of the model.
    cal.add(calendarField, 1); //Increment the date by 1 unit of the selected calendar field (e.g. 1 month).
    Date next = cal.getTime(); //Convert back to Date Object.
    return ((end == null) || (end.compareTo(next) >= 0)) ? next : null;
}

public Object getPreviousValue() {
    Calendar cal = Calendar.getInstance(); //Current date.
    cal.setTime(value.getTime()); //Set the date to the current value of the model.
    cal.add(calendarField, -1); //Decrement the date by 1 unit of the selected calendar field (e.g. 1 month).
    Date prev = cal.getTime(); //Convert back to Date Object.
    return ((start == null) || (start.compareTo(prev) <= 0)) ? prev : null;
}

它适用于添加或减少指定日历字段的1个单位 您想要将此数字1自定义为其他内容 所以我在这里看到两个选项:

  1. 重新实现AbstractSpinnerModel。只需复制粘贴SpinnerDateModel(它不大),然后引入整数字段&#34; step&#34;例如,而不是数字1,只需将&#34; step&#34;在getNextgetPrevious中。
  2. 实施SpinnerDateModel,其内部也适用于SpinnerDateModel。它会变得更小,但我觉得有点迟钝。
  3. 遵循此类SpinnerDateModel的代码(案例2):

    import java.awt.GridLayout;
    import java.util.Calendar;
    import java.util.Date;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JSpinner;
    import javax.swing.SpinnerDateModel;
    
    public class MultiStepDateSpinner extends JPanel {
        private static class StepperSpinnerDateModel extends SpinnerDateModel {
            private final SpinnerDateModel internal; //We let the internal SpinnerDateModel do the work for us.
            private final int step; //The number of steps to increment and decrement per click.
            private Object currentValue; //Needed to get restored each time getPreviousValue and getNextValue is called.
    
            private StepperSpinnerDateModel(final Date value, final Comparable start, final Comparable end, final int calendarField, final int step) {
                internal = new SpinnerDateModel(value, start, end, calendarField);
                if (step <= 0)
                    throw new IllegalArgumentException("Non positive step.");
                this.step = step;
                currentValue = internal.getValue();
            }
    
            private StepperSpinnerDateModel(final int step) {
                this(new Date(), null, null, Calendar.DAY_OF_MONTH, step);
            }
    
            @Override
            public Object getValue() {
                return currentValue;
            }
    
            @Override
            public void setValue(final Object value) {
                internal.setValue(value);
                currentValue = value;
                fireStateChanged(); //Important step for the spinner to get updated each time the model's value changes.
            }
    
            @Override
            public Object getNextValue() {
                Object next = null;
                for (int i=0; i<step; ++i) { //Calculate step next values:
                    next = internal.getNextValue();
                    internal.setValue(next); //We have to set the next value internally, in order to recalculate the next-next value in the next loop.
                }
                internal.setValue(currentValue); //Restore current value.
                return next;
            }
    
            @Override
            public Object getPreviousValue() {
                Object prev = null;
                for (int i=0; i<step; ++i) { //Calculate step previous values:
                    prev = internal.getPreviousValue();
                    internal.setValue(prev); //We have to set the previous value internally, in order to recalculate the previous-previous value in the next loop.
                }
                internal.setValue(currentValue); //Restore current value.
                return prev;
            }
        }
    
        private MultiStepDateSpinner() {
            super(new GridLayout(0, 1));
    
            //Increment and decrement by 4 minutes each step.
            //The null values indicate there shall be no minimum nor maximum date.
            //The current value is set to the current date.
            final JSpinner spinner = new JSpinner(new StepperSpinnerDateModel(new Date(), null, null, Calendar.MINUTE, 4));
    
            final JButton getValueButton = new JButton("Get value");
            getValueButton.addActionListener(e -> {
                JOptionPane.showMessageDialog(null, spinner.getValue(), "Got value", JOptionPane.PLAIN_MESSAGE);
            });
    
            add(spinner);
            add(getValueButton);
        }
    
        public static void main(final String[] args) {
            final JFrame frame = new JFrame("Frame");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new MultiStepDateSpinner());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    上面的示例代码是可运行的,因此您可以在实践中看到它。

    为什么不让它成为AbstractSpinnerModel而不是SpinnerDateModel?因为我们需要将其标识为SpinnerDateModel的实例,所以JSpinner内部默认为编辑器分配DateEditor
    即使您延长AbstractSpinnerModel并为微调器提供DateEditor,您也会收到一个例外,抱怨该模型不是SpinnerDateModel

    我认为最干净的方法是重新实现AbstractSpinnerModel并根据需要复制粘贴SpinnerDateModel的代码(这不大)并引入您感觉到的任何字段。

答案 2 :(得分:0)

Incrementa JSpinnerDateEditor_15_+_15_minutos
    Calendar Horacalendario = Calendar.getInstance();
    Horacalendario.setTime(cita_hora.getDate());
    Date HoraParaCita = Horacalendario.getTime();//para asignar luego del incremento de 15 formato date()'
    int minutos = Horacalendario.get(Calendar.MINUTE);
    Horacalendario.set(Horacalendario.get(Calendar.YEAR), Horacalendario.get(Calendar.MONTH),
            Horacalendario.get(Calendar.DATE), Horacalendario.get(Calendar.HOUR), 0);//hago cero los minutos
    if (minutos >= 1 & minutos <= 14) {
        Horacalendario.add(Calendar.MINUTE, 15); //minutos A Sumar 
        HoraParaCita = Horacalendario.getTime();
        cita_hora.setDate(HoraParaCita);
    }
    if (minutos >= 16 & minutos <= 29) {
        Horacalendario.add(Calendar.MINUTE, 30);
        HoraParaCita = Horacalendario.getTime();
        cita_hora.setDate(HoraParaCita);
    }
    if (minutos >= 31 & minutos <= 44) {
        Horacalendario.add(Calendar.MINUTE, 45);
        HoraParaCita = Horacalendario.getTime();
        cita_hora.setDate(HoraParaCita);
    }
    if (minutos >= 46 & minutos <= 59) {
        Horacalendario.set(Horacalendario.get(Calendar.YEAR), Horacalendario.get(Calendar.MONTH),
                Horacalendario.get(Calendar.DATE), Horacalendario.get(Calendar.HOUR), 0);//hago cero los minutos
        HoraParaCita = Horacalendario.getTime();
        cita_hora.setDate(HoraParaCita);
    }