2017-02-22 1 views
2

В моем приложении Java я столкнулся с проблемой, когда открываются новые jFrames, нажав jButton, litte-bit заморозить и после его открытия (время замораживания 1-2 минуты/3 минуты). Я еще не мог понять, что происходит. но у меня есть некоторые сомнения относительно приведенного ниже кода. этот код для принятия системного времени и даты и показать все jFrames. поэтому этот код находится во всех jFrames. теперь мой вопрос в том, что это замораживание происходит по этому коду ..? или могут возникнуть другие причины ..? если у этого кода есть какие-то ошибки plz, скажите мне, что тоже ... Я использую NEtbeans 8.2. заранее спасибо.jFrames заблокирован этим кодом? (код прилагается): Netbeans 8.2

код:

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(); 

} 

ответ

0

Вы могли создать отдельный поток, но все корни UI Updation до AWT нить. Следовательно, при вызове методов jLbl_date.setText() и jLbl_time.setText() очень часто этот поток фактически блокирует поток AWT напрямую.

Попробуйте добавить sleep(1000) после jLbl_Time.setText().

+0

Также вызовы 'setText' должны быть' SwingUtilities.InvokeLater'ed. –

+0

Я должен его исправить, если я ошибаюсь, но AWT не ограничивает многопоточный доступ к пользовательскому интерфейсу, как JavaFX. – Subhranil

+0

@Subhranil, tnx для ответа ур. Я попробовал, что ты сказал сейчас. но он показывает ошибку. пожалуйста, можете ли вы изменить мой код и комментарий здесь ...? это так полезно для меня. –

2

Эти два вызова:

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

должны происходить на EDT (Event отправка Thread) с элементами графического интерфейса должны быть манипулируют из EDT. Вы можете поместить их на EDT, окружив их с помощью 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]); 
}); 

Однако, было бы еще проблема. Поскольку ваш поток не спал между обновлением ярлыков, вы наводнили бы EDT запросами обновления, заставляя ваш графический интерфейс снова замораживаться. Вы можете исправить это, добавив Thread.sleep(1000); после обновления меток.

Более изящный подход заключается в использовании свинг таймер вместо вашего потока:

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(); 

Таймер качели заботится о том, что код жгутов в actionPerformed -метода выполняется на EDT. Он обладает дополнительным преимуществом, которое, в случае необходимости, углизует события - еще один механик, чтобы предотвратить наводнение EDT.

+0

Ты избил меня! +1 –

0

Похоже, вы создали поток для запуска бесконечного цикла для обновления некоторых полей даты и времени. Это не очень хороший способ добиться того, что вы хотите сделать.

Лучшим решением будет использование javax.swing.Timer с коротким интервалом и обновление вашего пользовательского интерфейса от подключенного прослушивателя действий.

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(); 

Что-то вроде вышеуказанного должно сделать трюк. Это избавит вас от необходимости пересекать границы потоков, чтобы обновить пользовательский интерфейс, и значительно снизит загрузку процессора с вашего предыдущего решения.

+0

Я добавил код ур. но получил эрро, и этот jframe тоже не запущен ... его мнение «не имеет основного метода» здесь приложите свой код в моем коде: –

+0

public AdminStudent() { initComponents(); ActionListener timerListener = новый ActionListener { общественных недействительный actionPerformed (ActionEvent е) { Дата д = новая дата(); SimpleDateFormat sd = new SimpleDateFormat ("yyyy - MM - dd"); Строка s = sd.format (d); Строка s1 = d.toString(); Строка ar [] = s1.split (""); jLbl_Date.setText (s); jLbl_Time.setText (ar [3]); } } Таймер t = новый javax.swing.timer (1000, timerListener) .start(); } –

+0

Я пропустил ';' от конца прослушивателя действий –

Смежные вопросы