2010-08-04 72 views
0

**您好,我正嘗試在java中創建存檔器。這意味着我不斷地從流中讀寫。我想能夠更新JProgressBar以顯示我寫了多少內容。我的代碼當前在歸檔中的每個條目之後更新進度條。我的變量和所有內容都表示代碼已更新,除非屏幕上未顯示。每次進入存檔後,我都會調用包含進度條和文本的JPanel上的revalidate()方法,但屏幕上沒有任何反應。屏幕不會更新,直到寫入存檔的輸出流完成寫入。然後,我會在進度文本中看到「24個文件中有24個已寫入」的完整進度條。直到代碼完成時JComponent.revalidate()纔會更新

任何人都可以告訴我如何讓我的代碼完成執行前更新的圖形?感謝名單

這裏是我的代碼:

WritingBox.java:

package org.apache.commons.compress; 
import javax.swing.JDialog; 
public class WritingBox extends javax.swing.JDialog { 

/** Creates new form WritingBox */ 
public WritingBox(java.awt.Frame parent, boolean modal) { 
    super(parent, modal); 
    initComponents(); 
    theprogressbar.setMaximum(1); 
    theprogressbar.setMinimum(0); 
    this.setLocation(parent.getLocationOnScreen().x+(parent.getWidth()-this.getWidth())/2, parent.getLocationOnScreen().y+(parent.getHeight()-this.getHeight())/2); 
    this.setVisible(true); 
} 
public void progressListener(Progress p) { 
    writtenxoutofx.setText("Written "+Integer.toString(p.doneSoFar)+" out of "+Integer.toString(p.total)+" files to the Archive"); 
    theprogressbar.setValue(p.doneSoFar/p.total); 
    if (p.doneSoFar == p.total) this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
    thecontainer.revalidate(); 
}; 
/** This method is called from within the constructor to 
* initialize the form. 
* WARNING: Do NOT modify this code. The content of this method is 
* always regenerated by the Form Editor. 
*/ 
@SuppressWarnings("unchecked") 
// <editor-fold defaultstate="collapsed" desc="Generated Code"> 
private void initComponents() { 

    thecontainer = new javax.swing.JPanel(); 
    jLabel1 = new javax.swing.JLabel(); 
    writtenxoutofx = new javax.swing.JLabel(); 
    theprogressbar = new javax.swing.JProgressBar(); 

    setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE); 
    setName("Form"); // NOI18N 

    thecontainer.setName("thecontainer"); // NOI18N 

    org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(targzipmanager.TarGzipManagerApp.class).getContext().getResourceMap(WritingBox.class); 
    jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N 
    jLabel1.setName("jLabel1"); // NOI18N 

    writtenxoutofx.setText(resourceMap.getString("writtenxoutofx.text")); // NOI18N 
    writtenxoutofx.setName("writtenxoutofx"); // NOI18N 

    theprogressbar.setName("theprogressbar"); // NOI18N 

    javax.swing.GroupLayout thecontainerLayout = new javax.swing.GroupLayout(thecontainer); 
    thecontainer.setLayout(thecontainerLayout); 
    thecontainerLayout.setHorizontalGroup(
     thecontainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(thecontainerLayout.createSequentialGroup() 
      .addContainerGap() 
      .addGroup(thecontainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addComponent(theprogressbar, javax.swing.GroupLayout.DEFAULT_SIZE, 307, Short.MAX_VALUE) 
       .addComponent(jLabel1) 
       .addComponent(writtenxoutofx)) 
      .addContainerGap()) 
    ); 
    thecontainerLayout.setVerticalGroup(
     thecontainerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addGroup(thecontainerLayout.createSequentialGroup() 
      .addContainerGap() 
      .addComponent(jLabel1) 
      .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
      .addComponent(writtenxoutofx) 
      .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 
      .addComponent(theprogressbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 
      .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) 
    ); 

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addComponent(thecontainer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
    ); 
    layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
     .addComponent(thecontainer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 
    ); 

    pack(); 
}// </editor-fold> 

// Variables declaration - do not modify 
private javax.swing.JLabel jLabel1; 
private javax.swing.JPanel thecontainer; 
private javax.swing.JProgressBar theprogressbar; 
private javax.swing.JLabel writtenxoutofx; 
// End of variables declaration 

} 

Progress.java

package org.apache.commons.compress; 

public class Progress { //This is basically a Struct 
public int total; 
public int doneSoFar; 
private Progress(){ 

} 
public Progress(int d, int t){ 
    total = t; 
    doneSoFar = t; 
} 
} 

TarArchive.java:DoSave就會方法

public void doSave(OutputStream output) throws ArchiveException { 
     // Stream initializing 
     //BufferedInputStream origin = null; 

     //out.setMethod(ZipOutputStream.DEFLATED); 
     //byte data[] = new byte[BUFFER]; 

     // get a list of files from current directory 
     // less than one file leads to an exception 
     Iterator iterator = this.getEntryIterator(); 
     if(!iterator.hasNext()) { 
       throw new ArchiveException("There must be at least one file to be pack."); 
     } 
     JFrame jf = targzipmanager.TarGzipManagerApp.getApplication().getMainFrame(); 
     WritingBox wb = new WritingBox(jf, false); 
     TarOutputStream out = null; 
     int x = 0; 
     try { 
       out = new TarOutputStream(new BufferedOutputStream(output)); 
       while(iterator.hasNext()) { 
        x++; 
        ArchiveEntry archiveEntry = (ArchiveEntry)iterator.next(); 
        InputStream fInputStream = archiveEntry.getStream(); 

        TarEntry entry = new TarEntry(archiveEntry.getName()); 
        entry.setModTime(0); 
       entry.setSize(fInputStream.available()); 
       entry.setUserID(0); 
       entry.setGroupID(0); 
       entry.setUserName("avalon"); 
       entry.setGroupName("excalibur"); 
       entry.setMode(0100000); 
       out.putNextEntry(entry); 
       out.copyEntryContents(fInputStream); 
       out.closeEntry(); 
       wb.progressListener(new Progress(x, entries.size())); 
       } 
     } catch (IOException e) { 
       throw new ArchiveException("Creation of this archive failed cause of IOExceptions.", e); 
     } finally { 
       try { 
        out.close(); 
       } catch (IOException e1) { 
        throw new ArchiveException("Creation of this archive failed cause of IOExceptions.", e1); 
       } 
     } 
    } 

人幫我?即使我在每次輸入後都調用revalidate(),它只會在代碼停止並且開始等待時更新。 **

回答

1

聽起來就像您正在AWT事件調度線程(EDT)上執行文件I/O。這會阻止任何重繪或事件處理。在另一個線程上運行I/O,然後通過java.awt.EventQueue.invokeLater更新GUI。

+0

我該怎麼做? – 2010-08-04 22:21:11

+0

@ user411316:有關示例,請參閱「繼續作爲對象」:http://en.wikipedia.org/wiki/Continuation_passing_style#Continuations_as_objects – trashgod 2010-08-05 02:57:07

相關問題