2017-05-03 6 views
0

JDateChooser 구성 요소에서 날짜를 입력하고 입력 한 날짜까지의 일 수를 계산하는 작은 프로그램이 있습니다. MVC 패턴을 사용하고 Netbeans IDE에서 코딩되었으며 올바른 일 수를 계산하지만 JLabel 인 "labelDays"에는 표시하지 않습니다. labelDays.setText ("29")를 입력하면 labelDays.getText()의 값을 가져 와서 올바른 일 수를 검색하고 strDays는 정확하지만 레이블에 업데이트 된 내용이 표시되지 않습니다. 값. 다음은 샘플 코드입니다.JLabel setText는 업데이트되지 않지만 getText는 올바른 값을 반환합니다.

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 
    ================ 

감사합니다. 작동하게하려면 어떻게해야합니까? 추신 : 내 오류가 내가 설정 한 MVC 때문인지 궁금합니다.

필립

답변

0

내가 찾으 MVC는 여기에서 설정하는 방법을 조금 이상한.

우선, setDays을 할 때마다 CountDownView을 다시 만들 이유가 없다고 생각합니다. 이는 레이블에 새 텍스트가 표시되지 않는 이유 일 수 있습니다. CountDownView의 새 인스턴스는 단순히 보이지 않을 수 있습니다. 이전 인스턴스 인 CountDownView은 표시되지만 새 것은 표시되지 않습니다. 따라서 여기 컨트롤러는 객체 레벨 필드로 CountDownView의 인스턴스를 가질 수 있습니다. 나는 CountDownModel에 대해서도 똑같이 말할 수있다.

또한보기가 자체 컨트롤러를 만들지 만 효율성이 떨어집니다. 교차 결합 및 메모리 누수가 발생하기 때문입니다. 나는 CountDownView의 생성자가 CountDownController의 인스턴스를 받아 들여서 객체 수준의 약한 참조로 저장할 수 있다고 생각합니다.

또한, 예를 들어, Runnable의 새로운 인스턴스의 모든 스윙 작업을 시작하는 것이 일반적이다 :

java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      CountDownController controller = new CountDownController(); 
      controller.startApplication(); 
     } 
}); 

당신은 (그것이 도움이되기를 바랍니다) 다음과 같은 방법으로 코드를 수정할 수 있습니다

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(); 
      } 
     }); 
    } 
} 
+0

paintImmediately 및 oldValue 변수가 추가되었습니다. 아직 라벨을 업데이트하지 않습니다. –

+0

@ philip-stephens,이 레이블은 언제든지 텍스트를 나중에 업데이트합니까? 아니면 항상 동일한 값을 유지합니까? – arcquim

+0

함수 내에서 명시 적으로 설정하지 않으면 항상 0이 표시됩니다. –