2010-11-19 3 views
1

Я пытался обновить содержимое JList при нажатии кнопки. Итак, я очистил модель списка, затем очистил список, а затем приступил к добавлению новых значений в список. Вот раздели код:Окно обновления JList на кнопке

testList.java

public class testList extends javax.swing.JFrame { 

    private Thread t; 
    public DefaultListModel model; 
    public boolean first = true; 

    public testList() { 
     model = new DefaultListModel(); 
     initComponents(); 
     this.centre(this); 
    } 

    public static void centre(javax.swing.JFrame f) { 
     Dimension us = f.getSize(), them = Toolkit.getDefaultToolkit().getScreenSize(); 
     int newX = (them.width - us.width)/2; 
     int newY = (them.height - us.height)/2; 
     f.setLocation(newX, newY); 
    } 

    class updateList implements Runnable { 

     public void run() { 
      tmp.getTheList(); 
      model.clear(); 
      ouputList.removeAll(); 

      for (int i = 0; i < tmp.returnList.size(); i++) { 
       model.addElement(tmp.returnList.get(i)); 

      } 
      if (first) { 
       chList.setModel(model); 
      } 

     } 
    } 

    private void initComponents() { 
    // generated by NetBeans 6.9 
    } 

    private void buttonActionPerformed(java.awt.event.ActionEvent evt) { 
     t = new Thread(new updateList(), "List Updater"); 
     t.start(); 
    } 

    public static void main(String args[]) { 

     tmp = new aC(); 

     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       new chapList().setVisible(true); 
      } 
     }); 
    } 

    static aC tmp; 

    private javax.swing.JButton button; 
    public static javax.swing.JList outputList; 
    private javax.swing.JScrollPane jScrollPane1; 
} 

ac.java

public class aC extends testList { 

    ArrayList returnList = new ArrayList(); 

    void getTheList() { 
     returnList.clear(); 
     generateList(); 
    } 

    void generateList() { 
    // populate returnList with random values of random size using returnlist.add() 
    } 
} 

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

Может ли кто-нибудь помочь мне выяснить, что вызывает эту проблему? Спасибо.

+0

Если вам разрешено, запустите свои имена классов заглавными буквами. Это соглашение, которое использует большинство разработчиков Java, и поэтому многие разработчики Java упрощают чтение вашего кода. –

+0

Спасибо, что сообщили мне. Я буду менять имена классов. – Monk

ответ

3

Ваша основная проблема, вероятно, связана с обновлением графического интерфейса Swing из потока, который не является AWT-EDT. (. Поставляемую с Java 6, а также available for download для использования с более ранними версиями Java)

Вы можете читать и/или посмотреть в использовании SwingWorker

В качестве альтернативы, взглянуть на этот подход:

import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 
import javax.swing.*; 

public class BackgroundWorkerFrame extends javax.swing.JFrame { 
    public BackgroundWorkerFrame() { 
     initComponents(); 
     jList.setModel(new DefaultListModel()); 
    } 

    private void jButtonGoActionPerformed(ActionEvent evt) {           
     Thread t = new Thread(new WorkerRunnable()); 
     t.start(); 
    }           

    public class WorkerRunnable implements Runnable { 
     public void run() { 
      System.out.println("Working hard..."); 
      sleep(1000); 
      ArrayList<Integer> list = new ArrayList(); 
      for (int i = 0; i < 5; i++) { 
       list.add((int) (Math.random() * 100)); 
      } 
      System.out.println("Updating GUI..."); 
      SwingUtilities.invokeLater(new UpdateRunnable(list)); 
     } 
    } 

    public class UpdateRunnable implements Runnable { 
     private final ArrayList<Integer> list; 
     private UpdateRunnable(ArrayList<Integer> list) { 
      this.list = list; 
     } 
     public void run() { 
      DefaultListModel model = (DefaultListModel) jList.getModel(); 
      model.clear(); 
      for (Integer i : list) { 
       model.addElement(i); 
      } 
     } 
    } 

    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
    private void initComponents() { 

     jButtonGo = new JButton(); 
     jScrollPane = new JScrollPane(); 
     jList = new JList(); 

     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     jButtonGo.setText("Go"); 
     jButtonGo.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       jButtonGoActionPerformed(evt); 
      } 
     }); 
     getContentPane().add(jButtonGo, BorderLayout.PAGE_START); 

     jScrollPane.setViewportView(jList); 

     getContentPane().add(jScrollPane, BorderLayout.CENTER); 

     Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
     setBounds((screenSize.width-309)/2, (screenSize.height-338)/2, 309, 338); 
    }// </editor-fold> 

    public static void sleep(long ms) { 
     try { 
      Thread.sleep(ms); 
     } catch (InterruptedException ex) { 
      ex.printStackTrace(); 
      Thread.currentThread().interrupt(); 
     } 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new BackgroundWorkerFrame().setVisible(true); 
      } 
     }); 
    } 

    // Variables declaration - do not modify 
    JButton jButtonGo; 
    JList jList; 
    JScrollPane jScrollPane; 
    // End of variables declaration 
} 
+0

Это очень близко к тому, что я намеревался. Но я хотел очистить существующий список и отобразить вновь созданный список. Я попытался очистить список, модель и список массивов в вашем коде, но не смог его успешно очистить. Но мне очень нравится идея позвонить еще одному Swing Worker, чтобы обновить UI. – Monk

+0

@Monk Я обновил приложение, чтобы очистить список перед заполнением новых данных. –

+0

Извините. Я просто переместил объявление модели над циклом и также очистил его. Работает как масло. Благодарю. Я попытаюсь реализовать в своем коде. – Monk

1

Одна вещь, которую вы делаете, это создание новой темы и внесение изменений в компонент GUI за пределами EventDispatchThread. Это, как правило, не очень хорошая идея. Попробуйте запустить updateList() на месте, который будет на EDT, так как события кнопки обрабатываются в этом потоке.

+0

Из того, что я заметил, список обновляется в первый раз. После этого поток «Список обновлений» фактически умирает. Он только перезапускается после нажатия кнопки. Таким образом, поток должен работать так же, как и в первый раз. Кроме того, если я правильно вас понял, вы предлагаете обновить JList после того, как поток умер. Если да, где я должен поместить код, так как потоки будут выполняться одновременно, и я бы назвал пустой список массивов. Спасибо – Monk