在Java applet中显示FTP文件上载期间的进度

好的,所以我让上传者使用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); } 

从它的声音(并且没有任何证据到the contree)听起来像你在事件调度线程中处理一个耗时的动作

您可能希望阅读Swing中的Concurrency以获得更深入的了解

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

看到源代码后更新

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

删除MyThread的实现并替换为

 public class MyWorker extends SwingWorker { 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; } } 

在你的ActionListener中使用o (??)替换线程执行代码

 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://所以我怀疑这会起作用……

在上传过程中,您看不到GUI的更改,因为您在同一个线程中运行上载和GUI更改。 你应该启动一个执行上传的threayd和另一个执行GUI更新的EDT(Event-Dispatch-Thread)。

有关详情,请参阅:

  1. 事件派遣线程

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