无法在微调器上更改日期的值

时间:2019-04-30 23:12:15

标签: java swing jspinner changelistener

我想编写一些代码来接收来自两个JSpinners的输入。我想要它,以便可以更改JSpinners的值并从Spinners中显示的内容获取字符串值。我通过添加一个ChangeListener来做到这一点。但是,在实际应用程序中,我无法更改微调器上的值,换句话说,我无法向上或向下移动微调器

import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


  public class SalesApplication extends JFrame {

    SpinnerModel model1;
   JSpinner spinner1;
   SpinnerModel model2;
   JSpinner spinner2;

   public SalesApplication(){

        model1 = new SpinnerDateModel();
           spinner1 = new JSpinner(model1);


 //Sub any date you want
           Date firstDate1 = null;
           model1 = new SpinnerDateModel(firstDate1, null, null, Calendar.DAY_OF_MONTH);


            class SpinnerListener1 implements ChangeListener {
             public void stateChanged(ChangeEvent e) {
             JSpinner spinner = (JSpinner) e.getSource();
             initialDate = (String) spinner.getValue();
      }
         }; 
          spinner1.addChangeListener(new SpinnerListener1());


           model2 = new SpinnerDateModel();
           spinner2 = new JSpinner(model2);
           Date firstDate2 = null ;
           model2 = new SpinnerDateModel(firstDate2, null, null, Calendar.DAY_OF_MONTH);

            class SpinnerListener2 implements ChangeListener {
           public void stateChanged(ChangeEvent e) {
             JSpinner spinner = (JSpinner) e.getSource();
             endDate = (String) spinner.getValue();
      }
         };
    spinner2.addChangeListener(new SpinnerListener2());
       JPanel rightPanel = new JPanel();
       rightPanel.add(spinner1);
       rightPanel.add(spinner2);
       add(rightPanel, java.awt.BorderLayout.EAST);
 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       setSize(600, 300);                       
       setVisible(true);

2 个答案:

答案 0 :(得分:2)

您正在使用以下代码创建两个SpinnerDateModel:

model1 = new SpinnerDateModel(); // SpinnerDateModel (1)
spinner1 = new JSpinner(model1);  // holds the first model
Date firstDate1 = dateObj[4];
model1 = new SpinnerDateModel(firstDate1, null, null, Calendar.DAY_OF_MONTH); // SpinnerDateModel (2)

spinner1 JSpinner仅保存第一个SpinnerDateModel对象,而没有JSpinner 保存第二个SpinnerDateModel对象,因此该对象将被忽略并被浪费掉。如果您需要使用第二个模型,那么甚至不用创建第一个模型:

// model1 = new SpinnerDateModel(); // SpinnerDateModel (1)
// spinner1 = new JSpinner(model1);
Date firstDate1 = dateObj[4];
model1 = new SpinnerDateModel(firstDate1, null, null, Calendar.DAY_OF_MONTH); // SpinnerDateModel (2)
spinner1 = new JSpinner(model1); // now holds the second model

您对model2变量有完全相同的问题。

上面的关键问题是您似乎将变量与其所持有的对象等同起来。一旦将SpinnerDateModel传递给JSpinner,然后更改您的model1 SpinnerDateModel持有的变量将对JSpinner本身持有的模型对象无效

答案 1 :(得分:1)

您似乎正在猜测如何创建SpinnerDateModel对象并在JSpinner中使用它们。简单来说,模型需要一个开始日期,结束日期以及一个值或日期才能显示。例如,类似这样:

// current value will be *today*
private Date value = new Date();  // today

// start will be the first of the year
private Date start = new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime();

// end will be the last of the year
private Date end = new GregorianCalendar(2019, Calendar.DECEMBER, 31).getTime();

// create date model using the above values
private SpinnerDateModel dateModel1 = new SpinnerDateModel(value, start, end, Calendar.DAY_OF_MONTH);

// put into JSpinner
private JSpinner spinner1 = new JSpinner(dateModel1);    

然后在ChangeListener中,从Spinner中提取Date对象,因为它就是其中的内容。您似乎正在尝试提取无效的字符串。例如:

spinner1.addChangeListener(evt -> {
    Date currentDate = (Date) spinner1.getValue(); // holds date values
    String dateText = format.format(currentDate); // if we want to extract a String from it
    System.out.println("Current Date: " + dateText);  // display it
});

一个有效的示例如下:

import java.awt.Dimension;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import javax.swing.*;

@SuppressWarnings("serial")
public class SpinnerTester extends JPanel {
    // current value will be *today*
    private Date value = new Date();  // today

    // start will be the first of the year
    private Date start = new GregorianCalendar(2019, Calendar.JANUARY, 1).getTime();

    // end will be the last of the year
    private Date end = new GregorianCalendar(2019, Calendar.DECEMBER, 31).getTime();

    // create date model using the above values
    private SpinnerDateModel dateModel1 = new SpinnerDateModel(value, start, end, Calendar.DAY_OF_MONTH);

    // put into JSpinner
    private JSpinner spinner1 = new JSpinner(dateModel1);

    public SpinnerTester() {
        // get the format from the spinner's editor
        SimpleDateFormat format = ((JSpinner.DateEditor) spinner1.getEditor()).getFormat();

        // have our spinner show the date only, and not the time
        format.applyPattern("MM/dd/yyyy");

        // add to GUI
        add(spinner1);
        setPreferredSize(new Dimension(400, 200));

        spinner1.addChangeListener(evt -> {
            Date currentDate = (Date) spinner1.getValue(); // holds date values
            String dateText = format.format(currentDate); // if we want to extract a String from it
            System.out.println("Current Date: " + dateText);  // display it
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SpinnerTester mainPanel = new SpinnerTester();
            JFrame frame = new JFrame("Spinner Tester");
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.add(mainPanel);
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        });
    }
}

感谢mKorbel's answer展示了如何格式化JSpinner中呈现的日期。