Индикатор прогресса не будет отображаться до тех пор, пока основной код не остановится
Я боролся в течение нескольких дней из-за глупой проблемы, и мне нужна твоя помощь. Я просто пытаюсь отобразить неопределенный индикатор процесса, как показано ниже, в отдельной стадии, в то время как мой основной код выполняет цикл. Если во время цикла выполняется определенное условие, этап выполнения должен закрыться, и основной код продолжается.
Прямо сейчас я могу открыть новый этап до того, как основной код запустит цикл, но индикатор прогресса пока не появится на этапе. Но как только условие выполнено, индикатор внезапно появляется на сцене и вращается. НО, как только основной код снова начинает работать, индикатор замирает, но остается видимым.
Я кратко объясню, что делает каждый код ниже. Как сделать так, чтобы этап загрузки отображался изначально с видимым индикатором, а затем этот этап ЗАКРЫВАЕТСЯ, когда showMessage()
метод называется? По сути, я хочу показать пользователю, что происходит фоновое зацикливание, пока основной код не достигнет showMessage()
,
Main.java Я не буду публиковать его, поскольку он создает только ПЕРВЫЙ GUI. Оно использует menu.fxml
как ресурс в FXMLLoader
... а также menu.fxml
использования Controller.java
в качестве контроллера.
Controller.java Этот код изменяет сцену в главном графическом интерфейсе, чтобы иметь новый макет, который просит пользователя нажать одну из видимых кнопок. Затем он проверяет, является ли кнопка источника Button1
... и если это так, создайте / покажите новый этап, который использует sample.fxml
как ресурс. Затем он запускает окончательный файл, Loop.java
public class Controller implements Initializable {
public Stage loadingStage;
@FXML
ProgressIndicator progressIndicator;
public void handlerButtonClick() throws IOException {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("field.fxml"));
Parent rootOne = loader.load();
((Controller) loader.getController()).setPrimaryStage(primaryStage);
((Controller) loader.getController()).setPrimaryScene(scene);
sceneField = new Scene(rootOne, 420, 510);
primaryStage.setScene(sceneField);
primaryStage.setTitle("Import Data");
primaryStage.show();
}
public void fieldOption(ActionEvent e) throws Exception {
source = e.getSource();
if (source == Button1) {
Loop loopObj = new Main();
String[] args = {};
//Create new stage to contain the Progress Indicator
FXMLLoader loader2 = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root2 = loader2.load();
Controller2 controller = loader2.getController();
loadingStage = new Stage();
loadingStage.setTitle("Loading Stage");
Scene scene = new Scene(root2, 200, 200);
loadingStage.setScene(scene);
loadingStage.show();
//Runs the looper
loopObj.start(stage);
}
}
Sample.fxml
Этот код создает индикатор прогресса и использует контроллер Controller2
<AnchorPane prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml/1"
xmlns="http://javafx.com/javafx/2.2" fx:controller="Controller2">
<children>
<ProgressIndicator fx:id="progressIndicator" layoutX="78.0" layoutY="55.0" progress="-1.0"/>
</children>
</AnchorPane>
Controller2.java Этот код реализует Initializable
чтобы сделать индикатор прогресса видимым:
public class Controller2 implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
ProgressIndicator progressIndicator = new ProgressIndicator();
progressIndicator.setVisible(true);
}
}
Loop.java Это основной код, который выполняет цикл. На этапе загрузки должен отображаться индикатор хода выполнения до Loop.java
называет его showMessage()
функция, в которой этап загрузки закрывается. Я знаю, что кажется, что один из этих методов не является необходимым, но только потому, что они лишены демонстрационных целей.
public class Loop extends Application {
@Override
public void start(Stage ignored) throws Exception {
Platform.setImplicitExit(false);
for (int i = 0; i <= 100; i++) {
if (i == 75){
saveAttachment("Hello");
}
}
}
public static void saveAttachment(String subject) throws IOException, MessagingException {
showMessage(subject);
}
private static void showMessage(String subject) throws IOException, MessagingException {
// Close the loading stage here.
}
}
Обратите внимание, как он использует public void start(Stage ignored)
, Main.java использует public void start(Stage primaryStage)
, Возможно, это плохо. Я так расстроен, пожалуйста, помогите!
ОБНОВИТЬ
Я применил предложения Брайана, и в Controller.java
добавили новую задачу так:
Stage loadingStage = new Stage();
//create task object
Task<Void> task = new Task<Void>(){
@Override
protected Void call() throws Exception{
System.out.println("Background task started...");
FXMLLoader loader2 = new FXMLLoader(getClass().getResource("sample.fxml"));
Parent root2 = loader2.load();
Controller2 controller = loader2.getController();
loadingStage.setTitle("Hello World");
Scene scene = new Scene(root2, 450, 250);
System.out.println("HERE6");
loadingStage.setScene(scene);
System.out.println("HERE7");
loadingStage.show();
System.out.println("HERE8");
return null;
}
};
Thread th = new Thread(task);
th.setDaemon(true);
System.out.println("Starting background task...");
th.start();
Проблема сейчас в том, что она не доходит до строки распечатки с надписью "ЗДЕСЬ7". Он успешно входит в задачу и продолжает основной код, но задача не выходит за пределы того места, где печатается "ЗДЕСЬ6", поэтому новый этап не открывается. Что дает?
1 ответ
В Ctlr2 у вас есть ProgressIndicator progressIndicator = new ProgressIndicator();
но если он находится в файле FXML, вы не создаете новый. Просто делать @FXML ProgressIndicator progressIndicator;
как у вас в первом Ctlr почему-то??
Но это не решит вашу проблему, вы запускаете все в потоке приложений JavaFX (поток GUI). Вероятно, что происходит (я действительно не читал код), это то, что вы делаете обе вещи в одном и том же потоке, а индикатор прогресса должен ждать завершения main, а затем он может обновить GUI. Вы ставите метки для задачи и параллелизма, это то, что вам нужно.
Проверьте здесь и выполните поиск других примеров. /questions/24058127/indikator-vyipolneniya-v-javafx/24058132#24058132