直到代码完成时JComponent.revalidate()才会更新

问题描述:

**您好,我正尝试在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(),它只会在代码停止并且开始等待时更新。 **

听起来就像您正在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