2

使用摆动按钮,我正在尝试下载一个 html 文件并将其写入一个新的 html 文件,同时做一个进度条。当我单击按钮时,我的程序似乎冻结了,直到下载完成,然后进度条突然变为 100%。我不太确定如何解决这个问题,因为我是 java 新手。

private void jButton2MouseReleased(java.awt.event.MouseEvent evt) {
    try {    
        URL oracle = new URL("http://mywebsite.com");
        URLConnection yc = oracle.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()));
        String inputLine;
        String input_path = "d:/website/updatedsite.html";
        WriteFile data = new WriteFile(input_path, false);
        int length = yc.getContentLength();
        int current = 0;
        jProgressBar1.setMaximum(length);
        jProgressBar1.setValue(0);
        while ((inputLine = in.readLine()) != null) {
            data.writeToFile(inputLine);
            int i = 0;
            for (i = 0; i < length; i++) {
                jProgressBar1.setValue(i);
            }
        }
        in.close();
    }
    catch (java.io.IOException e) { 
    JOptionPane.showMessageDialog(Frame1.this, "Error " + e.getMessage());
}

}

4

2 回答 2

3

这是因为您在同一个线程中同时下载和更新进度条 - 这就是为什么在下载完成后 gui 实际更新的原因。

使用单独的工作线程进行下载,如此所述,它应该可以工作。

于 2013-07-01T09:25:08.953 回答
1

我建议使用SwingWorker. 它是为诸如此类的问题而设计的。这是我的代码库中使用不确定进度条的一些代码的片段,但它可以帮助您大致了解该做什么(vui是一个 JFrame):

vui.clearOutput();
vui.setOutput("Waiting for items to copy...\n"
            + "This could take several minutes. Please standby...");
vui.disableExit();
vui.disableInput();
vui.disableNext();
vui.showProgressBar();

// make thread so you can disable all options when zipping and enable progress bar
SwingWorker transferWorker = new SwingWorker() {
    @Override
    protected Void doInBackground() throws Exception {
        try {
            Process p = Runtime.getRuntime().exec("resources/bin/transferCopier.bat");

            StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");
            StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUTPUT");
            errorGobbler.start();
            outputGobbler.start();

            p.waitFor();
        } catch (IOException ex) {
            Logger.getLogger(VaderController.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InterruptedException ie) {
            Logger.getLogger(VaderController.class.getName()).log(Level.SEVERE, null, ie);
        }
        return null;
    }
    @Override
    public void done() {
        vui.hideProgressBar();
        vui.clearOutput();
        vui.setOutput("Transfer Complete!\n\n"
                    + "Push \"Exit\" to quit.\n\n");
        vui.enableExit();
        mode = VaderMode.END;
    }
};
transferWorker.execute();

transferWorker.execute();被执行时,doInBackground()被调用。一旦doInBackground()完成计算,done()然后调用。done()是您对 GUI 进行任何最终更新的地方。

关于我上面的代码要注意的关键事项是,我在执行之前启用了进度条,SwingWorker然后当SwingWorker完成执行时,我禁用了进度条。

资源:

http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

于 2013-07-02T04:09:10.147 回答