Model view controller JLabel setText赢得';t更新,但getText返回正确的值

Model view controller JLabel setText赢得';t更新,但getText返回正确的值,model-view-controller,netbeans,jlabel,jdatechooser,Model View Controller,Netbeans,Jlabel,Jdatechooser,我有一个小程序,可以从JDateChooser组件输入一个日期,并计算从现在到输入日期的天数。它使用MVC模式,在Netbeans IDE中编码,并计算正确的天数,但不在“labelDays”中显示,后者是一个JLabel。当我输入labelDays.setText(“29”)时,它会工作,当我得到labelDays.getText()的值时,它会检索到正确的未来天数,strDays是正确的,但标签不会显示更新后的值。以下是示例代码: model: public class Co

我有一个小程序,可以从JDateChooser组件输入一个日期,并计算从现在到输入日期的天数。它使用MVC模式,在Netbeans IDE中编码,并计算正确的天数,但不在“labelDays”中显示,后者是一个JLabel。当我输入labelDays.setText(“29”)时,它会工作,当我得到labelDays.getText()的值时,它会检索到正确的未来天数,strDays是正确的,但标签不会显示更新后的值。以下是示例代码:

    model:
    public class CountDownModel {

        public LocalDate getCurrentDate() {
        return LocalDate.now();
    }

    public long getDays(LocalDate futureDate) {
        long daysBetween = DAYS.between(LocalDate.now(), futureDate);
        if(daysBetween <= 0) {
            return 0;
        }
        return daysBetween;
    }

    view:     
    public class CountDownView extends javax.swing.JFrame {
    ...       
        private CountDownController controller = new CountDownController();

        public CountDownView() {
            initComponents();
            Date input = new Date();
            Instant instant = input.toInstant();
            Date output = Date.from(instant);
            future_date.setDate(output);
        }

        private void button_calculateMouseClicked(java.awt.event.MouseEvent evt) {                                              

            Date futureDate;
            futureDate = future_date.getDate();
            String strDate = DateFormat.getDateInstance().format(futureDate);
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MMM-yyyy");
            LocalDate localDate = LocalDate.parse(strDate, formatter);

            controller.setDays(localDate);
        }                                             
        ...
        public void setDays(long days) {
            String strDays = String.valueOf(days);

            System.out.print("strDays:");
            System.out.println(strDays);

            String oldValue = labelDays.getText();

            labelDays.setText(strDays);
            labelDays.paintImmediately(labelDays.getVisibleRect());
            String newValue = labelDays.getText();

            System.out.print("oldValue:");
            System.out.println(oldValue);
            System.out.print("newValue:");
            System.out.println(newValue); 
            System.out.println("================");
        }
    }

    controller:

    public class CountDownController {
        public void startApplication() {
            CountDownView view = new CountDownView();
            view.setDays(0);
            view.setVisible(true);
        }

        public void setDays(LocalDate futureDate) {
            CountDownModel model = new CountDownModel();
            CountDownView view   = new CountDownView();

            long longDays = model.getDays(futureDate);
            if(longDays <= 0) {
                longDays = 0;
            }

            view.setDays(longDays);        
        }
    }

    main:
    public class DateCountDown {
        public static void main(String[] args) {
            // TODO code application logic here
            CountDownController controller = new CountDownController();
            controller.startApplication();
        }   
    }

    Output:
    run:
    strDays:0
    oldValue:200
    newValue:0
    ================
    strDays:28
    oldValue:200
    newValue:28
    ================
模型:
公共类倒计时模型{
public LocalDate getCurrentDate(){
返回LocalDate.now();
}
公共长getDays(LocalDate futureDate){
long daysBetween=DAYS.between(LocalDate.now(),futureDate);

如果(daysBetween我觉得这里的MVC设置有点奇怪

首先,我认为没有理由在每次执行
setDays
时都重新创建
CountDownView
。这可能是标签不显示其新文本的原因-一个
CountDownView
的新实例可能根本不可见:一个
CountDownView
的旧实例可见,而一个新实例不可见。因此,这里控制器可以有一个
CountDownView
实例作为对象级字段。我可以对
CountDownModel
说同样的话

此外,视图创建自己的控制器,这是没有效率的,因为会导致交叉链接和内存泄漏。我认为
CountDownView
的构造函数可以接受
CountDownController
的实例作为一个图形,并将其存储为对象级弱引用

此外,在
Runnable
的新实例中启动所有Swing作业是一种常见做法,例如:

java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
           CountDownController controller = new CountDownController();
           controller.startApplication();
      }
});
您可以通过以下方式修改代码(希望有帮助):

模型:
公共类倒计时模型{
public LocalDate getCurrentDate(){
返回LocalDate.now();
}
公共长getDays(LocalDate futureDate){
long daysBetween=DAYS.between(LocalDate.now(),futureDate);

如果(在添加的PaintInstance和oldValue变量之间的日期。仍然不更新标签。@philip stephens,此标签是否会在以后随时更新其文本?还是始终保持相同的值?除非我在函数中显式设置它,否则它始终显示0。在标签上执行
setText
之后,标签t需要多长时间o显示一个新值?多亏了你的建议,我才让它工作起来。我将于10月20日休假,所以我想写一个程序来计算还剩多少天。今天的答案是还剩167天。
model:
public class CountDownModel {

    public LocalDate getCurrentDate() {
        return LocalDate.now();
    }

    public long getDays(LocalDate futureDate) {
        long daysBetween = DAYS.between(LocalDate.now(), futureDate);
        if(daysBetween <= 0) {
            return 0;
        }
        return daysBetween;
    }
}

view:     
public class CountDownView extends javax.swing.JFrame {
...       
    private WeakReference<CountDownController> controller;

    public CountDownView(CountDownController controller) {
        this.controller = new WeakReference<>(controller);
        initComponents();
        Date input = new Date();
        Instant instant = input.toInstant();
        Date output = Date.from(instant);
        future_date.setDate(output);
    }

    private void button_calculateMouseClicked(java.awt.event.MouseEvent evt) {                                              

        Date futureDate;
        futureDate = future_date.getDate();
        String strDate = DateFormat.getDateInstance().format(futureDate);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MMM-yyyy");
        LocalDate localDate = LocalDate.parse(strDate, formatter);

        controller.get().setDays(localDate);
    }                                             
    ...
    public void setDays(long days) {
        String strDays = String.valueOf(days);

        System.out.print("strDays:");
        System.out.println(strDays);

        String oldValue = labelDays.getText();

        labelDays.setText(strDays);
        labelDays.paintImmediately(labelDays.getVisibleRect());
        String newValue = labelDays.getText();

        System.out.print("oldValue:");
        System.out.println(oldValue);
        System.out.print("newValue:");
        System.out.println(newValue); 
        System.out.println("================");
    }
}

controller:

public class CountDownController {
    private CountDownView view;
    private CountDownModel model;         

    public void startApplication() {
        view = new CountDownView(this);
        model = new CountDownModel();
        view.setDays(0);
        view.setVisible(true);
    }

    public void setDays(LocalDate futureDate) {
        long longDays = model.getDays(futureDate);
        if(longDays <= 0) {
            longDays = 0;
        }

        view.setDays(longDays);        
    }
}

main:
public class DateCountDown {
    public static void main(String[] args) {
        // TODO code application logic here
        java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                CountDownController controller = new CountDownController();
                controller.startApplication();
             }
        });
    }   
}