首先我想道歉,如果这个问题有明显的答案,但我没有在互联网上找到合适的答案。我已经遵循了一些教程,但我碰到了一个问题,无法理解我的错误。我正在尝试运行多线程桌面应用程序,其中有一个任务(TaskGetRetailersURL实现Runnable)我想在模态窗口上放置进度条。我有一个运行我的应用程序的主线程。在这个MAIN线程上,我为这个任务启动了新的Thread - TaskGetRetailersURL和Modal窗口的另一个第二个Thread - TaskModalWindow也实现了runnable。我在两个线程上启动它们的原因是,如果Modal窗口不在另一个帖子上,那么模态窗口被阻止显示“没有响应!”。 TaskGetRetailersURL需要一些时间来收集一些数据x项目,这些项目是进度条大小所需要的(我不知道将会有多少项目,我不知道它将需要的时间。)我正在使用一个标志和while循环来等待为此初始化控制器中的参数。我想在点击搜索按钮后显示模态窗口(我不想等到收集数据x。如果窗口显示并且进度条的值为0,则可以。)。如果我执行方法progressWindowController.setProgressBarListener();和progressWindowController.setProgressIndicator(); progressWindowController.startTask();现在使用此代码,在TaskGetRetailersURL完成并收集数据后显示模态窗口。
startSearchUsers(ActionEvent event)
方法之后显示带有进度条的模态窗口,而不显示在任务结尾?它显示前有30秒的时间段。 我发送文件: UsersTabController.java - 这是主线程运行的seacrh方法。
package com.mjp.java.controllers;
@Component
public class UsersTabController implements FxmlController {
@FXML
private TextField fromRating;
@FXML
private TextField toRating;
@FXML
private TextField searchWord;
@FXML
private Tab usersTab;
@FXML
private ComboBox<String> valuesComboBox;
private final ExceptionWriter exceptionsWriter;
@Autowired
private RetailerDao retailerDao;
public static ExecutorService executorUsers = Executors.newFixedThreadPool(CrawlerConstants.MYTHREADS);
@Autowired
public UsersTabController(ExceptionWriter exceptionsWriter) {
this.exceptionsWriter = exceptionsWriter;
}
@Override
public void initialize() {
valuesComboBox.getItems().removeAll(valuesComboBox.getItems());
valuesComboBox.getItems().addAll("1000", "2000", "3000","4000");
valuesComboBox.getSelectionModel().select("1000");
}
@FXML
private void startSearchUsers(ActionEvent event) throws IOException, InterruptedException {
String searchString = searchWord.getText();
int numbers = Integer.parseInt(valuesComboBox.getValue());
System.out.println(numbers);
List<Element> result = this.getArrayElementsFirstSearch(searchString);
if(!result.isEmpty()){
TaskModalWindow mdc = new TaskModalWindow(event);
Platform.runLater(mdc);
TaskGetRetailersURL tsu = new TaskGetRetailersURL (result, numbers, retailerDao);
Thread t2 = new Thread(tsu);
t2.start();
}
}
private List<Element> getArrayElementsFirstSearch(String input) throws IOException{
String searchWordInput = CrawlerUtil.fixSearchWordForUsers(input);
String inputSearchURL = CrawlerConstants.SEARCH_URL_INPUT_PREFFIX + searchWordInput + CrawlerConstants.SEARCH_URL_INPUT_SUFFIX;
Document document = Jsoup.connect(inputSearchURL).timeout(10*1000).get();
List<Element> check = document.select(CrawlerConstants.SELECTOR_FOR_PAGINATION);
HeapContainer.firstSetPaginationsAsElement = check;
return check;
}
}
TaskModalWindow.java - 启动模态窗口。
package com.mjp.java.threads;
import java.io.IOException;
import com.mjp.java.spring.config.SpringFXMLLoader;
import javafx.event.ActionEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class TaskModalWindow implements Runnable {
private ActionEvent event;
public TaskModalWindow (ActionEvent event) {
this.event = event;
}
private void showProgressBar(ActionEvent event){
Stage stage = new Stage();
Parent root;
try {
root = FXMLLoader.load(SpringFXMLLoader.class.getResource("/fxml/ProgressWindow.fxml"));
stage.setScene(new Scene(root));
} catch (IOException e) {
e.printStackTrace();
}
stage.setTitle("Searching....");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(((Node) event.getSource()).getScene().getWindow() );
stage.show();
}
@Override
public void run() {
this.showProgressBar(event);
}
}
ProgressWindowController.java
package com.mjp.java.controllers;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.ProgressIndicator;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import org.springframework.stereotype.Component;
@Component
public class ProgressWindowController implements FxmlController {
@FXML
private Button buttonStop;
@FXML
private ProgressBar progressBar;
@FXML
private ProgressIndicator progressIndicator;
@FXML
private Text txtState;
private Task<?> searchWorker;
public ProgressWindowController (){
}
@FXML
private void onButtonClick() {
}
private void changeStateProcessIndicator() {
}
public ProgressBar getProgressBar(){
return progressBar;
}
public ProgressIndicator getProgressIndicator(){
return progressIndicator;
}
private Task<?> createSearchTaskItems(int searchedUrls) {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
while (TaskItemsFeedback.workDoneItems + TaskItemsSold.workDoneItems <= searchedUrls ) {
updateProgress(TaskItemsFeedback.workDoneItems+TaskItemsSold.workDoneItems, searchedUrls);
}
return true;
}
};
}
private Task<?> createSearchUserTask(int searchedUrls) {
return new Task<Object>() {
@Override
protected Object call() throws Exception {
while (TaskFilterRetailers.workDoneUsers <= searchedUrls ) {
updateProgress(TaskFilterRetailers.workDoneUsers, searchedUrls);
}
return true;
}
};
}
public void setProgressBarListener(){
progressBar.indeterminateProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if (t1) {
txtState.setText("Calculating Time");
} else {
txtState.setText("In Progress");
}
}
});
progressBar.progressProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> ov, Number t, Number t1) {
if(t1.doubleValue() == 1){
txtState.setText("Work Done");
txtState.setFill(Color.GREEN);
buttonStop.setDisable(true);
}
}
});
}
public void setProgressIndicator(){
progressIndicator.indeterminateProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
if(t1){
txtState.setText("Calculating Time");
txtState.setFill(Color.BLUE);
} else{
txtState.setText("In Progress");
}
}
});
}
public void startTask() throws InterruptedException{
while(TaskGetRetailersURL.productsSize == 0 && TaskItemsStart.allUrlsAndItemsForExecuting==0){
System.out.println("Items Finder");
}
if(TaskGetRetailersURL.productsSize != 0){
searchWorker = createSearchUserTask(TaskGetRetailersURL.productsSize);
} else if(TaskItemsStart.allUrlsAndItemsForExecuting!=0){
searchWorker = createSearchTaskItems((TaskItemsStart.allUrlsAndItemsForExecuting));
}
progressBar.progressProperty().unbind();
progressBar.progressProperty().bind(searchWorker.progressProperty());
new Thread(searchWorker).start();
}
@Override
public void initialize() {
progressBar.setProgress(0);
setProgressBarListener();
setProgressIndicator();
startTask();
}
}
ProgressWindow.fxml
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.ProgressIndicator?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>
<AnchorPane prefHeight="201.0" prefWidth="399.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.mvp.java.controllers.ProgressWindowController">
<children>
<ProgressBar fx:id="progressBar" layoutX="50.0" layoutY="63.0" prefHeight="12.0" prefWidth="150.0" progress="0.0" />
<Button fx:id="buttonStop" alignment="CENTER" contentDisplay="RIGHT" layoutX="314.0" layoutY="126.0" mnemonicParsing="false" onAction="#onButtonClick" prefHeight="25.0" prefWidth="61.0" text="Stop" textAlignment="CENTER" />
<ProgressIndicator fx:id="progressIndicator" layoutX="231.0" layoutY="61.0" progress="0.0" />
<Text fx:id="txtState" fill="#2708d7" layoutX="274.0" layoutY="79.0" strokeType="OUTSIDE" strokeWidth="0.0" text="In Progress" textAlignment="CENTER" wrappingWidth="101.13671875">
<font>
<Font size="18.0" />
</font>
</Text>
</children>
</AnchorPane>
TaskGetRetailersURL.java
package com.mjp.java.threads;
import java.io.IOException;
public class TaskGetRetailersURL implements Runnable {
public int productsSize = 0;
public TaskGetRetailersURL (List<Element> result, int numberOfPages, RetailerDao retailerDao){
//setting the element
}
@Override
public void run() {
try {
searchUsers(result, numberOfPages);
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void searchUsers(List<Element> result, int numberOfPages){
//This method take long time to collect data and initialize productsSize
}
}