2010-11-19 2 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

핵심 문제는 AWT-EDT이 아닌 스레드에서 스윙 GUI를 업데이트하는 것과 관련이 있습니다. (. 자바의 이전 버전과 함께 사용하기 위해 자바 6와 함께 제공된 available for download) :

당신에 대해 읽기 및/또는 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

그것은 내가 의도 한 것에 매우 가깝습니다. 그러나 기존 목록을 지우고 새로 생성 된 목록을 표시하려고했습니다. 귀하의 코드에서 목록, 모델 및 배열 목록을 지우려고했지만 성공적으로 지울 수 없습니다. 그러나, UI 업데이트를하기 위해 다른 Swing Worker를 호출하는 아이디어를 정말 좋아합니다. – Monk

+0

@Monk 새 데이터를 채우기 전에 목록을 지우도록 응용 프로그램을 업데이트했습니다. –

+0

죄송합니다. 방금 루프 위에 모델 선언을 옮기고 또한 그것을 지웠다. 버터 같이 작동합니다. 감사. 내 코드를 구현하려고합니다. – Monk

1

당신이하는 일 중 하나는 새 스레드를 만들고 EventDispatchThread 외부에서 GUI 구성 요소를 변경하는 것입니다. 이것은 일반적으로 좋은 생각이 아닙니다. 버튼 이벤트가 해당 스레드에서 처리되므로 updateList()을 EDT에 배치 해보십시오.

+0

내가 알아 차리면 목록이 처음으로 업데이트됩니다. 이 후, "List Updater"스레드가 실제로 죽습니다. 단추를 누르면 다시 시작됩니다. 따라서 스레드는 처음과 동일한 방식으로 작동해야합니다. 또한 올바르게 이해했다면 스레드가 종료 된 후 JList를 업데이트하는 것이 좋습니다. 그렇다면 스레드가 동시에 실행되고 빈 배열 목록을 호출 할 것이므로 코드를 어디에 배치해야합니까? 감사합니다. – Monk