我试图通过移植命令行Java应用程序来使用Scene Builder和NetBeans来学习Java FX,并且大部分都在使用它。然而,在工人完成之前,进度条和文本区域都不会更新。"处理图像"按钮不表示已被点击,5秒或更长时间后光标显示应用程序正忙。我使用NetBeans-> New Project-> JavaFX-> Java FXML应用程序启动了该项目。我的代码在Controller文件中。
我已经了解(感谢Google),这是此类GUI的正常行为,并且更新需要在他们自己的线程中,而不是如何创建我需要的线程。
我创建了一个嵌套线程只是为了增加进度条,它没有用。然后我为使用进度线程的worker创建了一个嵌套线程,没有任何改变。然后我嵌套了嵌套worker中的进度线程,但仍然没有变化。工作方法/线程管理过滤它们的文件列表,并一次一个地提交正确的文件到一个方法,该方法可以纠正可能发现的任何错误。工作线程负责更新进度条,文本区域的更新是修复'修复的方法的责任。文件。
此按钮单击开始处理。
@FXML
private void handleBtnProcessImagesClick(ActionEvent event) {
btnProcess.setText("Processing");
if (!sourceDirExists) {
updateLog("Need valid source folder to process images.",
WARNING);
return;
}
sourceDir = new File(txtFldSourceFolder.getText());
createDestFolder();
//processFiles();
ThreadProcessImages pf = new ThreadProcessImages();
pf.run();
}
主要工作人员
class ThreadProcessImages extends Thread {
/**
* manage the progress bar while calculations are running
*/
class ThreadProgress extends Thread {
double progress = 0.0;
double max = 1.0 - 0.0005;
ThreadProgress(double progress) {
this.progress = progress;
}
@Override
public void run() {
if (progress == 0.0) {
progressBar.setStyle("-fx-accent: SKYBLUE;");
progressBar.setProgress(0.0);
System.out.println("Thread start.");
} else if (progress >= max) {
progressBar.setStyle("-fx-accent: SPRINGGREEN;");
progressBar.setProgress(1.0);
System.out.println("Thread end.");
} else {
progressBar.setProgress(progress);
}
}
}
@Override
public void run() {
if (chkBoxSaveEdits.isSelected() && isEdited) {
try {
appProps.saveProperties();
isEdited = false;
} catch (IOException ex) {
updateLog("processFiles can't save edits.", SEVERE);
}
}
if (chkBxVerbose.isSelected()) {
updateLog("FileName" + Common.COMMA + "HighCut" + Common.COMMA
+ "LowCut" + Common.COMMA + "MaxDN" + Common.COMMA + "MinDN"
+ Common.COMMA + "NewMax" + Common.COMMA + "newMin"
+ Common.COMMA + "numHighs" + Common.COMMA + "numLows");
}
long start = System.nanoTime();
// get a sorted list of files in the folder
File[] listOfFiles = sourceDir.listFiles();
Arrays.sort(listOfFiles, (f1, f2) -> f1.compareTo(f2));
// ignores directoriesI
int numFilesFound = 0;
int numTIFsFound = 0;
double progBarMax = (double) listOfFiles.length;
ThreadProgress progThread = new ThreadProgress(0.0);
progThread.run();
try {
Thread.sleep(1l, 0);
} catch (InterruptedException ex) {
Logger.getLogger(FixBsPixController.class.getName()).log(Level.SEVERE, null, ex);
}
for (File inFile : listOfFiles) { // Filter files
if (inFile.isFile()) { // exclude folders
++numFilesFound;
// Process only the files of interest
if (inFile.getName().contains(METADATA)) {
copyFile(inFile, new File(destinationDir.getAbsolutePath()
+ Common.PATH_SEP + inFile.getName()));
} else {
if (inFile.getName().contains(ZIPTIF)
|| inFile.getName().contains(TIF)) {
if ((inFile.getName().contains(BWB)
&& chkBoxBWB.isSelected())
|| (inFile.getName().contains(B08)
&& chkBoxB08.isSelected())
|| (inFile.getName().contains(B10)
&& chkBoxB10.isSelected())
|| (inFile.getName().contains(B12)
&& chkBoxB12.isSelected())) {
++numTIFsFound;
File outFile = new File(destinationDir
+ Common.PATH_SEP + inFile.getName());
// The file is corrected here
fixThePix(inFile, outFile);
}
}
progThread
= new ThreadProgress(numTIFsFound / progBarMax);
progThread.run();
try {
Thread.sleep(1l, 0);
} catch (InterruptedException ex) {
Logger.getLogger(FixBsPixController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
progThread
= new ThreadProgress(1.0);
progThread.run();
try {
Thread.sleep(1l, 0);
} catch (InterruptedException ex) {
Logger.getLogger(FixBsPixController.class.getName()).log(Level.SEVERE, null, ex);
}
btnProcess.setText("Process Images");
if (numTIFsFound == 0) {
updateLog("No image files found! Wrong folder?", WARNING);
updateLog("Might want to delete " + destinationDir, INFO);
} else {
updateLog("Files processed " + numFilesFound
+ " TIFFs found: " + numTIFsFound, INFO);
long elapsedTime = System.nanoTime() - start;
updateLog("Elapsed time: " + elapsedTime / 1_000_000 + " ms.", INFO);
updateLog(" That's "
+ ((double) elapsedTime / (double) numFilesFound) / 1_000_000
+ " ms per file.", INFO);
}
}
}
答案 0 :(得分:0)
我跟进了James_D的评论并编写了一个可运行的线程来操纵ProgressBar的进展。
/** ThreadProgress updates the progress-bar in real time if
* started with '.start()'
*/
class ThreadProgress implements Runnable {
ProgressBar progressBar;
ThreadProgress(double progress, ProgressBar progressBar) {
this.progress = progress;
this.progressBar = progressBar;
}
@Override
public void run() {
progressBar.setProgress(progress);
}
}
我还将工作放入自己的runnable线程并启动它 在' handleBtnProcessImagesClick'方法
@FXML
private void handleBtnProcessImagesClick(ActionEvent event) {
Thread qif = new Thread(new QueueImageFiles());
qif.start();
}
然后,在qif(worker)线程中,我在需要时更新了ProgressBar。
// first invocation
Thread progThread = new Thread(new ThreadProgress(0.0, progressBar));
progThread.start();
这很有效,我很满意,但我不能做的是改变进度条的颜色。