【问题标题】:JSpinner giving old valuesJSpinner 给出旧值
【发布时间】:2013-01-22 04:09:06
【问题描述】:

我在我的项目中使用了几个显示小时和分钟的 JSpinner。当 JSpinner 递增或递减时,我必须将值保存到数据库中。但问题是 JSpinners 给了我旧的价值观。 例如 - 如果显示的时间是 09:30 并且我将时间增加到 10:30,我得到 09:30 作为返回值。我正在使用以下代码

更新的 SSCCE

package spinnerupdation;

import java.awt.Container;
import java.awt.FlowLayout;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.swing.JFormattedTextField;
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;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatterFactory;

/**
 *
 * @author Rohan Kandwal
 */
public class SpinnerUpdation extends JFrame{
 public JSpinner spinner;
    SpinnerUpdation(){
        Container pane=this.getContentPane();
        JPanel panel=new JPanel();
        panel.setLayout(new FlowLayout());
        SpinnerDateModel model=new SpinnerDateModel();
        model.setCalendarField(Calendar.HOUR);
        spinner=new JSpinner();
        spinner.setModel(model);
        spinner.setEditor(new JSpinner.DateEditor(spinner,"hh:mm"));
        panel.add(spinner);
        pane.add(panel);
        spinner.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                        JFormattedTextField tf = ((JSpinner.DefaultEditor) spinner.getEditor()).getTextField();
                        DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();
                        DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();

                        // Change the date format to only show the hours
                        formatter.setFormat(new SimpleDateFormat("hh:mm"));
                        //formatter.setCommitsOnValidEdit(true);

                System.out.println(spinner.getValue());
                //System.out.println(tf.getText());
            }
        });


            }
    public static void main(String[] args) {
        SpinnerUpdation ss=new SpinnerUpdation();

        ss.setDefaultCloseOperation(ss.EXIT_ON_CLOSE);
        ss.setSize(574, 445);
     //ss.pack();

     ss.setLocationRelativeTo(null);
     ss.setResizable(false);
     ss.setVisible(true);
    }
}

如果我使用tf.getText(),我将获得两次旧值,但如果我使用spinner.getValue,我将获得新值,但它是长格式

Thu Jan 01 10:18:00 IST 1970
Thu Jan 01 11:18:00 IST 1970

我应该如何格式化微调器以仅提供 11:18

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE
  • 不确定this 是否有帮助,但这可能就是您想要的。
  • @AndrewThompson 我很乐意,但代码太大,就我的问题而言,其他部分是不必要的
  • 我认为这与您的SimpleDateFormat 有关,它似乎正在从返回值中剥离日期信息......
  • 据我所知,格式化程序的stringToValue 方法没有设置Date 对象的日期部分的上下文,因此当它转换时间值时,日期部分重置回 0

标签: java swing event-listener jspinner changelistener


【解决方案1】:

您可以维护一个“主日期”,您可以在每个 stateChanged 事件中重新合并时间值。

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            add(new DateSpinner(new Date()));
        }

    }

    public class DateSpinner extends JSpinner {

        private Date masterDate;

        public DateSpinner(Date date) {
            super(new SpinnerDateModel());
            this.masterDate = date;
            SpinnerDateModel model = (SpinnerDateModel) getModel();
            model.setCalendarField(Calendar.HOUR);
            setEditor(new JSpinner.DateEditor(this, "hh:mm"));
            JFormattedTextField tf = ((JSpinner.DefaultEditor) getEditor()).getTextField();
            DefaultFormatterFactory factory = (DefaultFormatterFactory) tf.getFormatterFactory();
            DateFormatter formatter = (DateFormatter) factory.getDefaultFormatter();

            formatter.setFormat(new SimpleDateFormat("hh:mm"));

            setValue(date);

            addChangeListener(new ChangeListener() {
                @Override
                public void stateChanged(ChangeEvent e) {

                    Calendar cal = Calendar.getInstance();
                    cal.setTime(masterDate);

                    Calendar time = Calendar.getInstance();
                    time.setTime((Date) getValue());

                    cal.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY));
                    cal.set(Calendar.MINUTE, time.get(Calendar.MINUTE));

                    masterDate = cal.getTime();

                    System.out.println(masterDate);

                }

            });
        }

        public String getTime() {
            return new SimpleDateFormat("hh:mm").format((Date)getValue());
        }

    }

}

【讨论】:

  • 我认为他想要的答案是“格式微调器只给出 11:18”,您的解决方案给他的结果与以前相同,例如“Tue Jan 22 04:17:54 CST 2013”​​。
  • @snow8261 你可能是对的,这个答案是为了响应 OP 的请求。我可能对“原创”一词感到困惑。我添加了一个简单的getTime 方法,它使用SimpleDateFormat 将字段Date 值格式化为时间String
【解决方案2】:

Java swing 使用的是 MVC 模式,所以在 JSpinner 中也是如此。如果你查看JSpinner源码,你会发现getValue()方法实际上是调用getModel().getValue(),所以它调用的是模型的getValue。并且您使用的模型是 SpinnerDateModel,它的值将是 Date Object,当您打印 Date 对象时,它将显示默认格式,如“Thu Jan 01 11:18:00 IST 1970”,如果你想得到像“11:18”这样的东西,你需要自己格式化。像

 SimpleDateFormat sdf = new SimpleDateFormat("hh:mm");
 System.out.println(sdf.format(spinner.getValue()) );

你可能想知道为什么 tf.getText() 只获取旧值,因为在 spinner 上的 ChangeEvent 发生后,tf 上的 PropertyChangeEvent 会发生,会为其设置新值。当然,你可以像 tf.addPropertyChangeListener 一样监听 tf。但我会建议使用上面的解决方案。

【讨论】:

  • 感谢您的代码像魅力一样工作,您的描述也非常好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
相关资源
最近更新 更多