2016-04-24 2 views
0

У меня есть проблема с этим кодом:Java: Нить не изменяет GUI даже с SwingUtilities.invokeLater

public class Gui_01 extends JFrame { 

private JPanel display; 
private ActionListener visualizza() { 
    ActionListener evento = new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent e) { 

      display.removeAll(); 

      Thread t = new Thread(new Runnable() { 
       public void run() { 
        JPanel visualizza = new JPanel(); 
        visualizza.add(new JLabel("Test", SwingConstants.CENTER)); 

        display.add(visualizza, BorderLayout.SOUTH); 

        updateProgress(visualizza); 
       } 
      } 
      ); 

      t.start(); 
     } 
    }; 
    return evento; 
} 

private void updateProgress(final JPanel visualizza) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      display.add(visualizza, BorderLayout.SOUTH); 
     } 
    }); 
}} 

Я не понимаю, почему этот код не работает должным образом, нить т и поток в updateProgress работает нормально, но любая модификация отображения не повлияет на графический интерфейс даже с invokeLater.

display.add(visualizza, BorderLayout.SOUTH) 

Этот код не изменить графический интерфейс, я знаю, что это нормально (из-за свинг), но почему invokeLater не работают.

Извините за мой плохой английский, спасибо за ответы.

ответ

1

Сначала избавьтесь от заявления display.add(visualizza, BorderLayout.SOUTH); в своей теме. как вы никогда не должны обновлять или модифицировать пользовательский интерфейс из-за пределы контекста EDT ...

Thread t = new Thread(new Runnable() { 
    public void run() { 
     JPanel visualizza = new JPanel(); 
     visualizza.add(new JLabel("Test", SwingConstants.CENTER)); 

     //display.add(visualizza, BorderLayout.SOUTH); 

     updateProgress(visualizza); 
    } 
} 

На самом деле, я бы препятствовать ваш от создания элементов пользовательского интерфейса за пределами EDT, так как вы не можете гарантировать, когда они могут начать взаимодействовать с пользовательским интерфейсом.

Во-вторых, вызов revalidate и repaint после того как вы обновили пользовательский интерфейс ...

private void updateProgress(final JPanel visualizza) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      display.add(visualizza, BorderLayout.SOUTH); 
      display.revalidate(); 
      display.repaint(); 
     } 
    }); 
}} 

Качели ленив, когда дело доходит до обновления пользовательского интерфейса, это хорошо, так как это позволяет сделать радикальные изменения и только обновлять пользовательский интерфейс, когда вы будете готовы это сделать.

Я бы также рекомендовал использовать вместо этого SwingWorker, поскольку он имеет функциональные возможности, которые можно использовать для синхронизации обновлений с помощью EDT. См. Worker Threads and SwingWorker для получения более подробной информации.

+0

Отличный ответ, большое вам спасибо.^_^ – xSanciopanzax

+0

Рад, что это может помочь – MadProgrammer