0

나는 bufferedInputStream을 사용하여 큰 파일을 저장하는 Java 응용 프로그램을 개발 중입니다. 업로드 된 파일의 비율을 나타내는 JDialog 안에 progressbar를 넣었습니다.이 막대는 매 n 초마다 증가합니다. 문제는 응용 프로그램이 대화 상자를 닫을 때까지 무기한 대기하기 때문에 종료되지 않습니다. 누구든지 도움을받을 수 있습니까?Java 업로드 비율 progressbar 스레드

JDialog dialog = new JDialog(Main.getMainFrame(), true); 
ProgressBarJPanel progressBarJPanel = new ProgressBarJPanel(); 
dialog.setContentPane(progressBarJPanel); 
Runnable r = new Runnable(){ 
    public void run(){ 
      SwingUtilities.invokeLater(new Runnable() 
      { 
        @Override 
        public void run() 
        { 
         progressBarJPanel.startProgress(); 
         dialog.pack(); 
         dialog.setVisible(true); 
        } 
      }); 

      //this is the long running job 
      while ((val = bufferedInputStream.read()) != -1) 
      { 
       fileOutputStream.write(val); 
      } 

      //here is the callback to UI thread 
      SwingUtilities.invokeLater(new Runnable(){ 
       public void run(){ 
        progressBarJPanel.end(); 
        dialog.setVisible(false); 
       } 
      } 
    }; 
Thread t = new Thread(r); 
t.start(); 
: ben75 조언에 따라 솔루션 EDIT 여기

한다 -

JDialog dialog = new JDialog(Main.getMainFrame(), true); 
        ProgressBarJPanel progressBarJPanel = new ProgressBarJPanel(); 
        dialog.setContentPane(progressBarJPanel); 
        dialog.pack(); 
        dialog.setVisible(true); 
        while ((val = bufferedInputStream.read()) != -1) 
        { 
         fileOutputStream.write(val); 
        } 
        progressBarJPanel.end(); 
        dialog.setVisible(false); 

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

public class ProgressBarJPanel extends JPanel 
     implements ActionListener 
{ 
    private JProgressBar progressBar; 
    private Timer timer; 
    public Thread updateThread; 
    public final static int ONE_SECOND = 1000; 
    private JTextArea taskOutput; 
    private String newline = "\n"; 
    int timeNow= 0; 
    int progress = 0; 

    public ProgressBarJPanel() 
    { 
     super(new BorderLayout()); 

     progressBar = new JProgressBar(0, 100); 
     progressBar.setValue(0); 
     progressBar.setStringPainted(true); 
     taskOutput = new JTextArea(5, 20); 
     taskOutput.setMargin(new Insets(5,5,5,5)); 
     taskOutput.setEditable(false); 
     taskOutput.setCursor(null); 

     JPanel panel = new JPanel(); 
     panel.add(progressBar); 

     add(panel, BorderLayout.PAGE_START); 
     add(new JScrollPane(taskOutput), BorderLayout.CENTER); 
     setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 

     //Create a timer. 
     timer = new Timer(ONE_SECOND, new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent evt) { 
       progressBar.setValue(progress); 
       progress+=10; 
       String s = "now at "+progress+"%"; 
       if (s != null) { 
        taskOutput.append(s + newline); 
        taskOutput.setCaretPosition(
          taskOutput.getDocument().getLength()); 
       } 
      } 
     }); 

    } 

    public void end() 
    { 
     timer.stop(); 
    } 

    public void startProgress() 
    { 
     timer.start(); 
    } 

    /** 
    * Create the GUI and show it. For thread safety, this method should be 
    * invoked from the event-dispatching thread. 
    */ 
    private static void createAndShowGUI() 
    { 
     //Make sure we have nice window decorations. 
     JFrame.setDefaultLookAndFeelDecorated(true); 

     //Create and set up the window. 
     JFrame frame = new JFrame("ProgressBarDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create and set up the content pane. 
     JComponent newContentPane = new ProgressBarJPanel(); 
     newContentPane.setOpaque(true); //content panes must be opaque 
     frame.setContentPane(newContentPane); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
       createAndShowGUI(); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) 
    { 
     throw new UnsupportedOperationException("Not supported yet."); 
    } 
} 

incriminated 클래스 : 여기

은 기본 응용 프로그램 코드 조각입니다
+1

조언을 사용하십시오 UI를 다루는 것보다는 시간이 많이 걸리는 작업에 다른 스레드를 사용하여 ... – ppeterka

+0

어떻게 두 사람은 의사 소통을 하는가? 또한 위의 넷빈즈는 저에게 updateThread.start(); 생성자 안에 있으면 안된다. 어떻게 바깥에 놓을 까? – dendini

+0

[this example] (http://stackoverflow.com/questions/15199091/progress-bar-java/15199220#15199220) – MadProgrammer

답변

3

너 다른 스레드에서 작업을 완료하는 데 시간을 소모해야합니다 (예 : 비 UI 스레드) 작업 콜백이 끝날 때 UI 스레드가 대화 상자를 닫습니다. 이 코딩 할 수있는 방법을

더 많은 이하 :

JDialog dialog = new JDialog(Main.getMainFrame(), true); 
ProgressBarJPanel progressBarJPanel = new ProgressBarJPanel(); 
dialog.setContentPane(progressBarJPanel); 
dialog.pack(); 
dialog.setVisible(true); 
Runnable r = new Runnable(){ 
     public void run(){ 
       //this is the long running job 
       while ((val = bufferedInputStream.read()) != -1) 
       { 
        fileOutputStream.write(val); 
       } 
       //here is the callback to UI thread 
       SwingUtilities.invokeLater(new Runnable(){ 
        public void run(){ 
         progressBarJPanel.end(); 
         dialog.setVisible(false); 
        } 
       } 
     }; 
Thread t = new Thread(r); 
t.start(); 
+0

progressJBar가 Runnable 외부에 생성되고 생성시 스레드를 시작하기 때문에 프로세스가 여전히 중단됨 매 초마다 진행 상황을 업데이트하기 위해 자체적으로 – dendini

+0

updateThread : progressBar를 직접 업데이트하는 대신 UI 스레드의 콜백에서 수행하십시오 (내 게시물에 표시된대로 SwingUtilities.invokeLater (...) 사용). – ben75

+0

당신의 솔루션을 기반으로 내 질문을 업데이 트,하지만 작동하지만 여전히 스레드 t 실제로 중지 항상 확실하지 않다 ... – dendini

3

이것은 SwingWorker위한 이상적인 작업이 될 것입니다 - doInBackground에 업로드를 수행하고 모든 너무 자주 업데이트 진행 번호 setProgress를 호출합니다. PropertyChangeListener을 사용하여 진행률 막대를 업데이트하고 done의 대화 상자를 닫습니다.이 두 가지 모두 이벤트 처리 스레드에서 실행되도록 보장됩니다.

위와 연결된 javadoc에 필요한 예제와 매우 흡사합니다.

0

던져 멀리 모든과 javax.swing.ProgressMonitorInputStream.

+0

어떻게? 이것은 대답보다 더 많은 논평입니다. –