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