简体   繁体   English

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

[英]JComponent.revalidate() doesn't update until code finishes

**Hello, I'm trying to create an archiver in java. **您好,我正在尝试用Java创建一个存档器。 This means that I am constantly reading and writing from streams. 这意味着我一直在从流中读取和写入。 I want to be able to update a JProgressBar to show how much I have written. 我希望能够更新JProgressBar以显示我写了多少。 My code currently updates the progress bar after each entry in the archive. 我的代码当前在归档中的每个条目之后都会更新进度栏。 My variables and everything say that the code is updated, except its not showing on the screen. 我的变量和所有内容都表明代码已更新,但未在屏幕上显示。 After each entry into the archive I call the revalidate() method on the JPanel that contains the progress bar and text, but nothing happens on the screen. 每次进入存档后,我都在JPanel上调用revalidate()方法,该方法包含进度条和文本,但是屏幕上没有任何反应。 The screen doesn't update until the output stream that is writing the archive has completely finished writing. 在写入归档文件的输出流完全完成写入之前,屏幕不会更新。 Then, I see the full progress bar with "24 out of 24 files written" in the progress text. 然后,我在进度文本中看到完整的进度条,其中显示“已写入24个文件中的24个”。

Can anyone tell me how I can get the graphics to update before my code finished executing? 谁能告诉我如何在代码执行完毕之前更新图形? Thanx 谢谢

Here is my code: 这是我的代码:

WritingBox.java: 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 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 method TarArchive.java:d​​oSave方法

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);
              }
        }
  }

Can anyone help me? 谁能帮我? Even though I'm calling revalidate() after each entry, it only updates when the code stops and it starts waiting. 即使我在每个条目之后都调用revalidate(),它仅在代码停止并开始等待时才更新。 ** **

Sounds like you are doing the file I/O on the AWT Event Dispatch Thread (EDT). 听起来您正在执行AWT事件调度线程(EDT)上的文件I / O。 This blocks any repaints or event handling. 这会阻止所有重绘或事件处理。 Run the I/O on a different thread, and update the GUI through java.awt.EventQueue.invokeLater . 在其他线程上运行I / O,并通过java.awt.EventQueue.invokeLater更新GUI。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在JComponent.revalidate和Container.validate之间选择 - how do I choose between JComponent.revalidate and Container.validate JPanel不会更新或重绘,直到For循环结束 - JPanel Doesn't Update or Repaint until For Loop Finishes JProgressBar在Try-catch完成之前不会启动 - JProgressBar Doesn't Start Until Try-catch finishes Java JComponent不刷新 - Java JComponent doesn't refresh 为什么此JComponent不能正确绘制? - Why doesn't this JComponent paints correctly? 在调整Jframe大小之前,JPanel不会更新 - JPanel doesn't update until resize Jframe 如何在Firebase-Android中链接2个EventListener,以使第一个EventListener直到第二个EventListener结束才继续? - How to chain 2 EventListeners in Firebase-Android so that the first one doesn't continue until second one finishes? 显示ProgressDialog,直到AsyncTask完成,然后更新UI - Display ProgressDialog until AsyncTask finishes, then update UI 为什么instanceof不能与JPanel和JComponent一起使用? - Why doesn't instanceof work with JPanel and JComponent? 只有在Runtime.getRuntime()。exec()完成执行之后,Swing消息才会显示 - Swing message doesn't get displayed until after Runtime.getRuntime().exec() finishes execution
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM