2011-12-21 2 views
2

나는이 예제에서 wget을 사용하여 exe 파일을 다운로드하는 GUI 프로그램을 가지고있다. 파일을 다운로드하는 스레드를 설정했습니다. 파일의 크기를 유지하는 정적 변수가 있습니다. 그런 다음 실제 파일 크기를 확인하고 다운로드가 100 % 완료 될 때까지 JLabel을 업데이트하는 while 루프가 있습니다. GUI가 분명히 업데이트되지 않고 스레드가 완료 될 때까지 모든 것이 중단됩니다.이 스레드를 만드는 것이이 문제를 우회 할 것이라고 생각했기 때문에 이상한 것입니다. 내가 뭘 잘못했는지, 스레드에 대해 무엇을 바꿔야하는지 알려주세요. 나는 이것을 현재처럼 단순하게 유지하려고 노력하고 싶다.Java GUI 스레딩

참고 : 여기에 System.out.println()이 있습니다. 따라서 현재 파일 크기가 올바르게 업데이트됨을 알 수 있습니다. 또한 다운로드중인 파일이 이미 존재하는 경우 (while 루프가 즉시 true이므로) 전체 작업이 작동하지 않습니다.

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.net.*; 
import java.io.*; 

public class downloaderProgram implements ActionListener { 
    JFrame frame; 
    JPanel p1, p2, p3; 
    JButton start; 
    JLabel status; 

    downloaderProgram() { 
     frame = new JFrame("Downloader"); 
     frame.setSize(500, 400); 

     //p1 
     p1 = new JPanel(); 

     //p2 
     p2 = new JPanel(); 

     status = new JLabel(""); 
     p2.add(status); 

     //p3 
     GridLayout p3Grid = new GridLayout(0, 1); 
     p3 = new JPanel(); 
     p3.setLayout(p3Grid); 

     start = new JButton("Start"); 
     start.setMargin(new Insets(10,0,10,0)); 

     p3.add(start); 

     //frame 
     frame.add(p1, BorderLayout.NORTH); 
     frame.add(p2, BorderLayout.CENTER); 
     frame.add(p3, BorderLayout.SOUTH); 

     start.addActionListener(this); 

     //output.setEditable(false); 
     frame.setResizable(false); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 

    public void actionPerformed(ActionEvent e) { 
     if (e.getSource().equals(start)) { 
      long fileSize = 1110476; 

      downloadThread dt = new downloadThread(); 
      dt.start(); 

      long length = 0; 
      File download = new File("7z920.exe"); 
      while (length != fileSize) { 
       length = download.length(); 
       status.setText(Long.toString(length)); 
       System.out.println(Long.toString(length)); 
      } 

      start.setEnabled(false); 
     } 
    } 

    public static void main(String[] args) { 
     new downloaderProgram(); 
    } 
} 
class downloadThread extends Thread { 
    public void run() { 
     try { 
      String cmd = "wget http://downloads.sourceforge.net/sevenzip/7z920.exe"; 
      Runtime run = Runtime.getRuntime(); 
      Process pr = run.exec(cmd); 
     } catch(IOException io) { 
      System.out.println(io); 
     } 
    } 
} 

죄송합니다. 간격이 조금 엉망인 경우 - 내 IDE에서 잘 복사하지 못했습니다. 감사!

+0

Huhh .. 7 Zip을 설치하는 방법이 허약합니다. 어떻게 wget을 설치합니까? –

+0

방금 ​​예제 설치로 7zip exe를 사용했습니다 ... 설치 방법이 아닙니다. – carget

+0

자바 명명 규칙을 배우고 그들에게 붙이십시오 – kleopatra

답변

5

언제 라벨이 업데이트됩니까? Swing이 페인팅을 할 때 Event Dispatch Thread (EDT)를 반복합니다. 다운로드 스레드가 아닌 while 루프가 GUI 업데이트를 방해하고 있습니다.

대답은 간단합니다 : javax.swing.SwingWorker. 오라클의 comprehensive SwingWorker tutorial입니다.

JLabel 대신 또는 함께 JProgressBar을 사용하는 것도 고려하십시오. 그것에 대한 튜토리얼도 있습니다 : How to Use Progress Bars