0

OK so I have the uploader uploading files using the Java FTP, I would like to update the label and the progress bar. Label with the percent text, bar with the percent int value. Right now with the current code only get the 100 and full bar at the end of the upload. During the upload none of them change.

here it is:

    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);
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user1634307
  • 5
  • 1
  • 5
  • How did you instantiated the JLabel and the JProgressBar? How long does the ftp upload usually take? – Dan D. Aug 29 '12 at 20:33
  • i added the full code take a look, i can track the percentage in console window. Upload speed is not bad, depending on the server and the internet connection since i am using the ftp not stream write. – user1634307 Aug 29 '12 at 22:32
  • *"i added the full code"* I see an uncompilable code snippet. For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Aug 30 '12 at 00:30
  • look at the link below, there is a "compileable code" When I added this comment there was a link I dont see that anymore here. Thanks anyways – user1634307 Aug 30 '12 at 04:37

3 Answers3

2

From the sounds of it (and lacking any evidence to the contree) it sounds like your processing a time consuming action in the Event Dispatching Thread

You might like to read Concurrency in Swing for some further insight

I'd suggest using a SwingWorker to perform the actual transfer & take advantage of its built in progress support

UPDATE after seeing source code

  1. Don't mix heavy weight components with light weight components. Change Applet to JApplet, change TextField to JTextField, don't use Canvas use a JPanel or JComponent
  2. If you expect other people to read your code, please use proper names for your variables, I have no idea what p is.
  3. Your Thread is useless. Rather then starting the thread and using it's run method you simply make your download call within it's constructor. This will do nothing for you...

Remove your implementation of MyThread and replace it with

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;

    }
}

In your ActionListener of o (??) replace the thread execution code with

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

Note. You are ignoring the URL you pass to the constructor. http:// is not ftp:// so I doubt this will work...

user1634307
  • 5
  • 1
  • 5
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Please look at the link i posted and provide feed back, i really need to get this working. http://www.codr.cc/d14a40 – user1634307 Aug 30 '12 at 05:05
  • @user1634307 Please see updates, then please read [SwingWorker](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) – MadProgrammer Aug 30 '12 at 06:19
  • @user1634307 _i really need to get this working_ consider hiring a consultant to do it for you :-) – kleopatra Aug 30 '12 at 06:42
  • The URL actually passed for other purposes, It is actually going to be passed dynamically, which will be selected by the user to regenerate the target path. Right now URL is useless there are couple other parameters still missing. – user1634307 Aug 30 '12 at 17:32
1

During the upload you don't see changes to the GUI, because you run the upload and the GUI changes in the same thread. You should start one threayd that does the upload and another one in EDT (Event-Dispatch-Thread) that does the GUI updates.

For more info see:

  1. The Event Dispatch Thread
kovica
  • 2,443
  • 3
  • 21
  • 25
  • http://www.codr.cc/s/b94bb1b6/ here is my full code please provide code snippets – user1634307 Aug 29 '12 at 22:23
  • I'd create a new class that extends Thread and put what you have in upload method to the run method of the thread. Then I'd start the thread in my main program, do a for loop in my main program and ask the thread how many bytes did it transfer or something so that you can calculate the value for the progress bar. Then I'd use SwingWorker to update the GUI. Look at http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html – kovica Aug 29 '12 at 23:05
  • ok this is what I have now but still not getting the progress change http://www.codr.cc/d14a40 – user1634307 Aug 30 '12 at 00:45
  • This is because the updates for the GUI (method upd) are still run inside your thread that does the logic (MyThread). You should look at the SwingWorker class and run the updates to the GUI in EDT (Event-Dispath-Thread) – kovica Aug 30 '12 at 05:46
1

You should implement the transfer logic in a SwingWorker, that way the UI will have the chance to present the progress.

dan
  • 13,132
  • 3
  • 38
  • 49