2017-02-22 2 views
2

Je rencontre un problème dans mon application java qui, lorsque de nouveaux jFrames s'ouvrent en cliquant sur jButton, gèle un peu et après son ouverture (temps de congélation 1-2 minutes/3 minutes). Je ne pouvais pas encore trouver ce qui ne va pas. mais j'ai quelques doutes de ci-joint le code ci-joint. ce code pour prendre l'heure et la date du système et montrer tous les jFrames. donc ce code est dans tous les jFrames. maintenant ma question est, est ce gel se passe par ce code ..? ou peut-il d'autres raisons? si ce code a des torts plz dis moi aussi ... J'utilise NEtbeans 8.2. Merci d'avance.jFrames sont gelés par ce code? (code joint): Netbeans 8.2

Code:

public AdminHome() { 
    initComponents(); 

    new Thread(new Runnable() { 
     @Override 
     public void run() { 

      while (true) { 
      Date d=new Date(); 

      SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd"); 
      String s = sd.format(d); 
      String s1 = d.toString(); 
      String ar[]=s1.split(" "); 

      jLbl_Date.setText(s); 
      jLbl_Time.setText(ar[3]); 
      } 
     } 
    }).start(); 

} 

Répondre

0

Vous avez créé un thread séparé, mais toutes les racines de updation de l'interface utilisateur vers le bas au fil de AWT. Par conséquent appeler les méthodes jLbl_date.setText() et jLbl_time.setText() très fréquemment par ce thread bloquent réellement le thread AWT directement.

Essayez d'ajouter un sleep(1000) après jLbl_Time.setText().

+0

Les appels 'setText' doivent également être' SwingUtilities.InvokeLater'ed. –

+0

Ya il devrait, corrigez-moi si je me trompe, mais AWT ne restreint pas l'accès à l'interface utilisateur multithread comme JavaFX. – Subhranil

+0

@Subhranil, tnx pour votre réponse. J'ai essayé ce que tu as dit maintenant. mais il montre une erreur. s'il vous plaît pouvez-vous modifier mon code et commenter ici ...? C'est tellement utile pour moi. –

2

Ces deux appels:

jLbl_Date.setText(s); 
jLbl_Time.setText(ar[3]); 

doivent se produire sur l'EDT (Thread Dispatch Event) car les composants de l'interface graphique doivent être manipulés de l'EDT. Vous pouvez les mettre à l'EDT en les enveloppant en utilisant SwingUtilities:

SwingUtilities.invokeLater(() -> { 
    Date d=new Date(); 

    SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd"); 
    String s = sd.format(d); 
    String s1 = d.toString(); 
    String ar[]=s1.split(" "); 

    jLbl_Date.setText(s); 
    jLbl_Time.setText(ar[3]); 
}); 

Cependant, il y aurait encore un problème. Puisque votre thread ne dort pas entre la mise à jour des étiquettes, vous inonderez l'EDT avec des demandes de mise à jour provoquant à nouveau votre interface graphique à geler. Vous pouvez résoudre ce problème en ajoutant un Thread.sleep(1000); après la mise à jour des étiquettes.

Une approche plus élégante consiste à utiliser une minuterie swing au lieu de votre fil:

Timer timer = new Timer(1000, new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      Date d=new Date(); 

      SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd"); 
      String s = sd.format(d); 
      String s1 = d.toString(); 
      String ar[]=s1.split(" "); 

      jLbl_Date.setText(s); 
      jLbl_Time.setText(ar[3]); 
     } 
});    
timer.setInitialDelay(0); 
timer.start(); 

Une minuterie swing veille à ce que le code withing la actionPerformed -method est exécuté sur l'EDT. Il a l'avantage additionnel qu'il coaleceses les événements si nécessaire - un autre mécanisme pour empêcher les événements d'inonder l'EDT.

+0

Tu m'as battu dessus! +1 –

0

Il semble que vous ayez créé un thread pour exécuter une boucle infinie afin de mettre à jour certains champs de date et d'heure. Ce n'est pas un très bon moyen de réaliser ce que vous voulez faire.

Une meilleure solution consisterait à utiliser un javax.swing.Timer avec un intervalle plus court et à mettre à jour votre interface utilisateur à partir d'un programme d'écoute d'action associé.

ActionListener timerListener = new ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     Date d=new Date(); 

     SimpleDateFormat sd=new SimpleDateFormat("yyyy - MM - dd"); 
     String s = sd.format(d); 
     String s1 = d.toString(); 
     String ar[]=s1.split(" "); 

     jLbl_Date.setText(s); 
     jLbl_Time.setText(ar[3]); 
    } 
}; 

Timer t = new javax.swing.timer(1000, timerListener).start(); 

Quelque chose comme ce qui précède devrait faire l'affaire. Cela vous évite d'avoir à franchir les limites des threads pour mettre à jour l'interface utilisateur, et réduira considérablement la charge CPU de votre solution précédente.

+0

J'ai ajouté le code ur. mais eu erro et ce jframe n'est pas exécuté aussi bien ... son dire "n'a pas de méthode principale" ici attaché votre code dans mon code: –

+0

public AdminStudent() { initComponents(); ActionListener timerListener = new ActionListener { public void actionPerformed (ActionEvent e) { date d = new Date(); SimpleDateFormat sd = new SimpleDateFormat ("aaaa-MM-jj"); Chaîne s = sd.format (d); Chaîne s1 = d.toString(); Chaîne ar [] = s1.split (""); jLbl_Date.setText (s); jLbl_Time.setText (ar [3]); } } Minuterie t = new javax.swing.timer (1000, timerListener) .start(); } –

+0

J'ai manqué un ';' à la fin de l'écouteur d'action –