0

好的,我让上传者使用 Java FTP 上传文件,我想更新标签和进度条。带有百分比文本的标签,带有百分比 int 值的条形图。现在使用当前代码只能在上传结束时获得 100 条和完整条。在上传期间,它们都没有改变。

这里是:

    OutputStream output = new BufferedOutputStream(ftpOut);
    CopyStreamListener listener = new CopyStreamListener() {
        public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
            System.out.printf("\r%-30S: %d / %d", "Sent", totalBytesTransferred, streamSize);
            ftpup.this.upd(totalBytesTransferred,streamSize);
        }
        public void bytesTransferred(CopyStreamEvent arg0) { }
    };

    Util.copyStream(input, output, ftp.getBufferSize(), f.length(), listener);      
}

public void upd(long num, long size){
    int k = (int) ((num*100)/size);
    System.out.println(String.valueOf(k));
    this.d.setText(String.valueOf(k));
    //d.setText(String.valueOf(k));
    progressBar.setValue(k);
}
4

3 回答 3

2

从它的声音(并且缺乏任何关于contree的证据)听起来你在事件调度线程中处理一个耗时的动作

您可能想阅读Swing中的并发以获得进一步的见解

我建议使用SwingWorker执行实际传输并利用其内置的进度支持

看到源代码后更新

  1. 不要将重量较重的组件与重量较轻的组件混合使用。更改AppletJApplet, 更改TextFieldJTextField, 不要使用Canvas使用JPanelorJComponent
  2. 如果您希望其他人阅读您的代码,请为您的变量使用正确的名称,我不知道是什么p
  3. Thread的没用。而不是启动线程并使用它的run方法,您只需在它的构造函数中进行下载调用。这对你没有任何作用...

删除您的实现MyThread并将其替换为

public class MyWorker extends SwingWorker<Object, Object> {

    private URL host;
    private File outputFile;

    public MyWorker(URL host, File f) {
        this.host = host;
        outputFile = f;
    }

    @Override
    protected Object doInBackground() throws Exception {

        // You're ignoring the host you past in to the constructor
        String hostName = "localhost";
        String username = "un";
        String password = "pass";
        String location = f.toString();

        //FTPClient ftp = null;

        ftp.connect(hostName, 2121);
        ftp.login(username, password);

        ftp.setFileType(FTP.BINARY_FILE_TYPE);

        ftp.setKeepAlive(true);
        ftp.setControlKeepAliveTimeout(3000);
        ftp.setDataTimeout(3000); // 100 minutes
        ftp.setConnectTimeout(3000); // 100 minutes

        ftp.changeWorkingDirectory("/SSL");

        int reply = ftp.getReplyCode();
        System.out.println("Received Reply from FTP Connection:" + reply);

        if (FTPReply.isPositiveCompletion(reply)) {
            System.out.println("Connected Success");
        }
        System.out.println(f.getName().toString());

        File f1 = new File(location);
        in = new FileInputStream(f1);

        FileInputStream input = new FileInputStream(f1);
        // ftp.storeFile(f.getName().toString(),in);

        //ProgressMonitorInputStream is= new ProgressMonitorInputStream(getParent(), "st", in);
        OutputStream ftpOut = ftp.storeFileStream(f.getName().toString());


        System.out.println(ftpOut.toString());
        //newname hereSystem.out.println(ftp.remoteRetrieve(f.toString()));
        OutputStream output = new BufferedOutputStream(ftpOut);
        CopyStreamListener listener = new CopyStreamListener() {
            public void bytesTransferred(final long totalBytesTransferred, final int bytesTransferred, final long streamSize) {

                setProgress((int) Math.round(((double) totalBytesTransferred / (double) streamSize) * 100d));

            }

            @Override
            public void bytesTransferred(CopyStreamEvent arg0) {
                // TODO Auto-generated method stub
            }
        };

        Util.copyStream(input, output, ftp.getBufferSize(), f.length(), listener);

        return null;

    }
}

在您ActionListenero(??) 中,将线程执行代码替换为

try {
    MyWorker worker = new MyWorker(new URL("http://localhost"), file);
    worker.addPropertyChangeListener(new PropertyChangeListener() {

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getPropertyName().equals("progress")) {
                Integer progress = (Integer) evt.getNewValue();
                progressBar.setValue(progress);
            }
        }
    });
    worker.execute();
} catch (MalformedURLException ex) {
    ex.printStackTrace();
}

笔记。您忽略了传递给构造函数的 URL。http:// 不是 ftp:// 所以我怀疑这会起作用......

于 2012-08-29T20:39:17.537 回答
1

在上传期间,您看不到 GUI 的更改,因为您在同一线程中运行上传和 GUI 更改。您应该启动一个执行上传的线程,并在 EDT(事件调度线程)中启动另一个执行 GUI 更新的线程。

有关更多信息,请参阅:

  1. 事件调度线程
于 2012-08-29T20:34:17.610 回答
1

您应该在 SwingWorker 中实现传输逻辑,这样 UI 将有机会呈现进度。

于 2012-08-29T20:35:28.520 回答