views:

292

answers:

1

Hi I am using a very simple JavaFx client to upload files. I read the file in chunks of 1 MB (using Byte Buffer) and upload using multi part POST to a PHP script. I want to update the progress bar of my client to show progress after each chunk is uploaded. The calculations for upload progress look correct but the progress bar is not updated. I am using bind keyword.

I am no JavaFx expert and I am hoping some one can point out my mistake. I am writing this client to fix the issues posted here (http://stackoverflow.com/questions/2447837/upload-1gb-files-using-chunking-in-php)


 /*
 * Main.fx
 *
 * Created on Mar 16, 2010, 1:58:32 PM
 */
package webgloo;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.geometry.VPos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import javafx.scene.layout.LayoutInfo;
import javafx.scene.text.Font;
import javafx.scene.control.ProgressBar;
import java.io.FileInputStream;

/**
 * @author rajeev jha
 */
var totalBytes:Float = 1;
var bytesWritten:Float = 0;
var progressUpload:Float;

var uploadURI = "http://www.test1.com/test/receiver.php";
var postMax = 1024000 ;


function uploadFile(inputFile: java.io.File) {

    totalBytes = inputFile.length();
    bytesWritten = 1;
    println("To-Upload - {totalBytes}");

    var is = new FileInputStream(inputFile);
    var fc = is.getChannel();
    //1 MB byte buffer

    var chunkCount = 0;
    var bb = java.nio.ByteBuffer.allocate(postMax);

    while(fc.read(bb) >= 0){

        println("loop:start");
        bb.flip();

        var limit = bb.limit();

        var bytes = GigaFileUploader.getBufferBytes(bb.array(), limit);
        var content = GigaFileUploader.createPostContent(inputFile.getName(), bytes);
        GigaFileUploader.upload(uploadURI, content);

        bytesWritten = bytesWritten + limit ;
        progressUpload = 1.0 * bytesWritten / totalBytes ;
        println("Progress is  - {progressUpload}");

        chunkCount++;
        bb.clear();
        println("loop:end");


    }

}


var label = Label {
            font: Font { size: 12 }
            text: bind "Uploaded - {bytesWritten * 100 / (totalBytes)}%"
            layoutInfo: LayoutInfo { vpos: VPos.CENTER maxWidth: 120 minWidth: 120 width: 120 height: 30 }
        }
def jFileChooser = new javax.swing.JFileChooser();

jFileChooser.setApproveButtonText("Upload");
var button = Button {
            text: "Upload"
            layoutInfo: LayoutInfo { width: 100 height: 30 }
            action: function () {
                var outputFile = jFileChooser.showOpenDialog(null);
                if (outputFile == javax.swing.JFileChooser.APPROVE_OPTION) {
                    uploadFile(jFileChooser.getSelectedFile());
                }
            }
        }
var hBox = HBox {
            spacing: 10
            content: [label, button]
        }
var progressBar = ProgressBar {
            progress: bind progressUpload
            layoutInfo: LayoutInfo { width: 240 height: 30 }
        }
var vBox = VBox {
            spacing: 10
            content: [hBox, progressBar]
            layoutX: 10
            layoutY: 10
        }

Stage {
    title: "Upload File"
    width: 270
    height: 120
    scene: Scene {
        content: [vBox]
    }
    resizable: false
}
A: 

The real reason the GUI was not update was because everything in JavaFx is run in one thread (EDT). You need to use JavaFx Async framework To update GUI while some heavy background task is going now. Please see http://blogs.sun.com/baechul/entry/javafx_1_2_async for an excellent reference. I have fixed this issue now by creating a separate JavaTaskBase for file upload.

rjha94