Связывание данных Java Fx не работает с File Read - PullRequest
0 голосов
/ 25 марта 2010

Я использую очень простой клиент JavaFx для загрузки файлов. Я читаю файл кусками по 1 МБ (используя Byte Buffer) и загружаю POST с несколькими частями в скрипт PHP. Я хочу обновить индикатор выполнения моего клиента, чтобы он отображал прогресс после загрузки каждого чанка. Расчеты для прогресса загрузки выглядят правильно, но индикатор выполнения не обновляется. Я использую ключевое слово bind.

Я не эксперт по JavaFx, и я надеюсь, что кто-то может указать на мою ошибку. Я пишу этот клиент, чтобы исправить проблемы, опубликованные здесь ( Загрузка файлов 1 ГБ с использованием чанкинга в 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
}

1 Ответ

0 голосов
/ 27 марта 2010

Реальная причина, по которой графический интерфейс не был обновлен, заключалась в том, что все в JavaFx выполняется в одном потоке (EDT). Вам нужно использовать JavaFx Async Framework, чтобы обновить GUI, пока идет какая-то тяжелая фоновая задача. Пожалуйста, смотрите http://blogs.oracle.com/baechul/entry/javafx_1_2_async для отличного справочника. Я исправил эту проблему, создав отдельную JavaTaskBase для загрузки файлов.

...