Java Fx 数据绑定不适用于文件读取
我正在使用一个非常简单的 JavaFx 客户端来上传文件。我以 1 MB 为单位读取文件(使用字节缓冲区),并使用多部分 POST 上传到 PHP 脚本。我想更新客户端的进度条以在上传每个块后显示进度。上传进度的计算看起来正确,但进度条未更新。我正在使用绑定关键字。
我不是 JavaFx 专家,我希望有人能指出我的错误。我正在编写此客户端来解决此处发布的问题(使用分块上传 1GB 文件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
}
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 (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
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
GUI 未更新的真正原因是 JavaFx 中的所有内容都在一个线程 (EDT) 中运行。您需要使用 JavaFx 异步框架来更新 GUI,同时正在进行一些繁重的后台任务。请参阅 http://blogs.oracle.com/baechul/entry/javafx_1_2_async一个很好的参考。我现在通过创建一个单独的 JavaTaskBase 用于文件上传解决了这个问题。
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.oracle.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.