【问题标题】:JSpinner jumping weeks rather than daysJSpinner 跳跃数周而不是数天
【发布时间】:2017-06-28 23:24:33
【问题描述】:

我创建了一个每天上下移动的 JSpinner 对象,点击时会跳过周末。然后我添加了一个功能,如果您在周六或周日打开程序,它应该回滚到周五。问题是 JSpinner 跳回一周而不是更改为星期五。

我尝试在新程序中隔离问题,但没有成功。代码应该完全相同,所以我不确定是什么导致了这个问题。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerDateModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@SuppressWarnings("serial")
public class MainFrame extends JFrame {

DecimalFormat df = new DecimalFormat("#.00");
SpinnerDateModel spinnerModel;
JSpinner spinner;
Integer loopStep;
Integer firstloopStep = 0;

MainFrame() {
    super("Spinner Control");

    setLayout(new BorderLayout());

    JPanel panel1 = new JPanel();
    JPanel panelNorth = new JPanel();

    // spinner for date information
    spinnerModel = new SpinnerDateModel();
    spinnerModel.setCalendarField(Calendar.WEEK_OF_MONTH);
    spinner = new JSpinner(spinnerModel);
    JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "EEEEE, dd MMMMM, yyyy");
    spinner.setEditor(editor);

    // add panels/buttons/etc to page
    add(panel1, BorderLayout.PAGE_START);
    panel1.setPreferredSize(new Dimension(1280, 100));
    panelNorth.setPreferredSize(new Dimension(1280, 40));

    panel1.add(panelNorth, BorderLayout.NORTH);
    panelNorth.add(spinner, BorderLayout.PAGE_START);

    //method executes on start up
    skipWeekends();

    loopStep = 0;
    //rotate the date, skip weekends, works fine here
    spinner.addChangeListener(new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent arg0) {
            Date date = (Date) spinner.getValue();
            System.out.println("todays date " + date);
            SimpleDateFormat sdf = new SimpleDateFormat("EEEEE, dd MMMMM, yyyy");
            String stringDate = sdf.format(date);
            System.out.println(stringDate);
            char c = stringDate.charAt(0);
            char c2 = stringDate.charAt(1);

            //skip the weekends
            if ((c == 'S') && (c2 == 'a') && (loopStep == 0)) {
                loopStep = 1;
                spinner.setValue(spinner.getNextValue());
                spinner.setValue(spinner.getNextValue());
                System.out.println("Saturday Spinner going back 2");
            }

            if ((c == 'S') && (c2 == 'u') && (loopStep == 0)) {
                loopStep = 1;
                spinner.setValue(spinner.getPreviousValue());
                spinner.setValue(spinner.getPreviousValue());
                System.out.println("Sunday Spinner going back 2");
            }
            if (loopStep == 1) {
                loopStep = 2;
            }
            if (loopStep == 2) {
                loopStep = 0;
            }


        }
    });


    setExtendedState(MAXIMIZED_BOTH);
    setMinimumSize(new Dimension(1280, 485));
    setSize(640, 485);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

}

@PostConstruct
private void skipWeekends(){
    //skips weekends when program opens, skips weeks for some reason
    Date date = (Date) spinner.getValue();
    System.out.println("todays date " + date);
    SimpleDateFormat sdf = new SimpleDateFormat("EEEEE, dd MMMMM, yyyy");
    String stringDate = sdf.format(date);
    System.out.println(stringDate);
    char c = stringDate.charAt(0);
    char c2 = stringDate.charAt(1);

    if ((c == 'S') && (c2 == 'a')) {

        spinner.setValue(spinner.getPreviousValue());
        System.out.println("Saturday Spinner going back 2");
    }

    if ((c == 'S') && (c2 == 'u')) {

        spinner.setValue(spinner.getPreviousValue());
        spinner.setValue(spinner.getPreviousValue());
        System.out.println("Sunday Spinner going back 2");
    }


}

}

【问题讨论】:

  • 据我所知,微调器设置为增加/减少 Calendar.WEEK_OF_MONTH,所以当您调用 getNextValue 时,它会从当前值滚动一周 - 也许,您应该创建Calendar 并将其回滚/向前滚动到您想要的日期并使用它来设置微调器的值
  • 为什么在完全正常工作的 changeListener 中的 stateChanged 方法会有什么不同?这就是让我感到困惑的地方。我曾想过那样做,但我认为我非常接近解决这个问题而无需更改一堆代码。如果没有其他问题,我会尝试这种方法。
  • 你这个微调器设置为旋转一周 - 为什么它会让你感到惊讶?
  • 在 stateChanged 方法中没有这样做。触发该方法时是否未设置?
  • 我会担心更新 ChangeListener 中的微调器,因为它可能会产生更多事件 - 我会考虑使用我自己的模型,但这就是我

标签: java swing date jspinner


【解决方案1】:

您将 SpinnerDateModel 的日历字段设置为 Calendar.WEEK_OF_MONTH 而不是 Calendar.DAY_OF_WEEK。

使用 Spinner 按钮时,此问题会被静默纠正,因为 Spinner 将在提交更改之前设置日历字段(这在 SpinnerDateModel 文档中有所提及)。不过,您的 @PostConstruct 方法会在这有机会发生之前运行。

如果我可以添加另一个建议:您计算当前星期几的方法非常复杂且非常脆弱(例如,它会在德国中断,因为“星期日”在这里是“Sonntag”)。这是一个替代方案。使用构造函数中的 initial == true 和 stateChanged() 中的 initial == false 调用它。

private Calendar cal = new GregorianCalendar();

private void skipWeekends(boolean initial) {
    cal.setTime(spinnerModel.getDate());

    switch (cal.get(Calendar.DAY_OF_WEEK)) {
    case Calendar.SATURDAY:
        cal.add(Calendar.DAY_OF_WEEK, initial ? -1 : 2);
        break;
    case Calendar.SUNDAY:
        cal.add(Calendar.DAY_OF_WEEK, -2);
        break;
    }
    spinnerModel.setValue(cal.getTime());
}

【讨论】:

  • 我使用了这个 DAY_OF_YEAR 并且效果也很好。尝试该解决方案后,我立即看到了此评论。无论如何,奖金信息非常适合学习。谢谢。
  • 不客气!我已经使用代码 sn-p 更新了响应,修复了人们的其他一些问题。
【解决方案2】:

我认为您需要选择当前日历字段,然后该字段将受到 JSpinner 的 getNextValue()getPreviousValue() 方法的影响。

要进行选择,您可以使用:

spinner.setCalendarField(Calendar.DAY_OF_YEAR);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多