【发布时间】:2018-10-11 16:08:28
【问题描述】:
我正在尝试通过移植命令行 Java 应用程序来了解使用 Scene Builder 和 NetBeans 的 Java FX,并且大部分时间都可以正常工作。但是,在工作人员完成之前,进度条和文本区域都不会更新。“处理图像”按钮并不表示已单击,5 秒或更长时间后,光标显示应用程序正忙。我使用 NetBeans->New Project->JavaFX->Java FXML Application 启动了这个项目。我的代码在 Controller 文件中。
我了解到(感谢 Google)这是这种 GUI 的正常行为,更新需要在它们自己的线程中,而不是如何创建我需要的线程。
我创建了一个嵌套线程只是为了增加进度条,它不起作用。然后我为使用进度线程的工作人员创建了一个嵌套线程,没有任何改变。然后我将进度线程嵌套在嵌套的工作者中,但仍然没有变化。工作方法/线程管理过滤它们的文件列表,并一次将正确的文件提交给纠正可能发现的任何错误的方法。工作线程负责更新进度条,文本区域的更新由“修复”文件的方法负责。
单击此按钮开始处理。
@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);
}
}
}
【问题讨论】:
-
pf.run()在当前线程上调用线程的run()方法。您大概想开始一个新线程,即使用pf.start()。 -
@James_D 谢谢,我已经使用 pf.start() 和来自 Google 的一些帮助获得了进度条。但是,尝试更改其颜色时出现运行时错误。
标签: multithreading javafx progress-bar desktop-application scenebuilder