作为对话框(JavaFX10)的一部分时,不确定ProgressBar不会设置动画
当作为对话框(JavaFX10)的一部分时,不确定ProgressBar不会设置动画,java,javafx,java-10,Java,Javafx,Java 10,当ProgressBar不确定时,它会有一个来回的动画。当ProgressBar是正常阶段的一部分时,此功能正常工作,但当对话框的一部分时,此功能不起作用。相反,它似乎只是坐在动画的开始。然而,当设置为某个确定值时,ProgressBar会正确更新。注意:这个问题在Java8中没有出现 没有迹象表明有任何例外情况 这是一个MCVE(): 导入javafx.application.application; 导入javafx.concurrent.Task; 导入javafx.geometry.In
ProgressBar
不确定时,它会有一个来回的动画。当ProgressBar
是正常阶段的一部分时,此功能正常工作,但当对话框的一部分时,此功能不起作用。相反,它似乎只是坐在动画的开始。然而,当设置为某个确定值时,ProgressBar
会正确更新。注意:这个问题在Java8中没有出现
没有迹象表明有任何例外情况
这是一个MCVE():
导入javafx.application.application;
导入javafx.concurrent.Task;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ButtonType;
导入javafx.scene.control.Dialog;
导入javafx.scene.control.Label;
导入javafx.scene.control.ProgressBar;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.StackPane;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类应用程序扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
按钮detButton=新按钮(“启动确定任务”);
detButton.setOnAction(ae->{
消费();
createDialog(primaryStage,true)
.showAndWait();
});
按钮不确定按钮=新按钮(“启动不确定任务”);
索引按钮设置动作(ae->{
消费();
createDialog(primaryStage,false)
.showAndWait();
});
HBox btnBox=新的HBox(detButton,indetButton);
btnBox.setspace(10);
btnBox.setAlignment(位置中心);
StackPane root=新的StackPane(btnBox,createDummyProgressNode());
场景=新场景(根,500,300);
初级阶段。场景(场景);
primaryStage.setTitle(“ProgressBar发行”);
primaryStage.SetResizeable(假);
primaryStage.show();
}
私有节点createDummyProgressNode(){
Label Label=新标签(“在舞台上显示动画的进度条”);
ProgressBar ProgressBar=新的ProgressBar();
progressBar.setMaxWidth(双倍最大值);
VBox框=新的VBox(标签、进度条);
box.setMaxHeight(VBox.USE\u PREF\u SIZE);
框。设置间隔(3);
框。设置对齐(位置中心左);
框。设置填充(新插图(5));
StackPane.setAlignment(框,位置底部\中心);
返回框;
}
专用对话框createDialog(后台所有者,布尔确定){
任务任务=新的背景任务(确定);
Dialog=新建Dialog();
dialog.initOwner(所有者);
对话框.setTitle(“后台任务-”
+(确定?“确定”:“不确定”);
dialog.getDialogPane().setPrefWidth(300);
getDialogPane().setContent(createDialogContent(任务));
dialog.getDialogPane().getButtonTypes().add(ButtonType.OK);
dialog.getDialogPane().lookupButton(ButtonType.OK)
.disableProperty().bind(task.runningProperty());
对话框。设置显示(de->{
去消费();
执行任务;
});
返回对话框;
}
专用节点createDialogContent(任务){
标签=新标签();
label.textProperty().bind(task.messageProperty());
ProgressBar ProgressBar=新的ProgressBar();
progressBar.setMaxWidth(双倍最大值);
progressBar.progressProperty().bind(task.progressProperty());
VBox框=新的VBox(标签、进度条);
框。设置间隔(3);
框。设置对齐(位置中心左);
返回框;
}
私有void executeTask(任务){
线程线程=新线程(任务,“后台线程”);
setDaemon(true);
thread.start();
}
私有静态类BackgroundTask扩展任务{
私有最终布尔确定;
私有背景任务(布尔确定){
this.determinate=determinate;
}
@凌驾
受保护的Void调用()引发异常{
最终整数循环=1_000;
对于(int i=0;i错误报告可在此处找到:
- 受影响的版本:
9
、10
和openjfx-11
- 受影响的平台:通用(所有)
- 固定版本:
openjfx-12
原来对话框
不是问题的根源。问题是在场景
已添加到阶段
后,将进度条
添加到场景
而引起的;导致问题的原因是。有关更多更好的解释,请参阅。下面是附加的测试代码将问题分层:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class IndeterminateProgressBar extends Application {
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 150);
stage.setScene(scene);
// If the progress bar is added to the root after the root is
// added to the scene and the scene is added to the stage, it will
// fail to be shown.
ProgressBar progBar = new ProgressBar();
progBar.setProgress(-1);
root.getChildren().add(progBar);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
如果将stage.setScene(场景)
移动到root.getChildren().add(progBar)
之后,将设置ProgressBar
动画
基于此信息,我认为使用对话框时不可能找到解决方法。对话框有一个内部阶段
用于显示。当对话框
上设置了对话框窗格
时,它会创建一个场景
,然后将该场景添加到此阶段
通常,对话框
是用对话框窗格
初始化的,因此无论场景
是什么,在添加进度条
之前都会添加到阶段
为避免此问题,请使用JavaFX 8或OpenJFX 12+。修复程序可能(或将)后端口到OpenJFX 11,但我不确定(如果您知道其中一种方法,请留下评论).看起来Java 10确实破坏了JavaFX中的许多功能。也许你可以试试Java 9看看是否会发生这种情况。一个猜测是,他们没有正确实现模块
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class IndeterminateProgressBar extends Application {
@Override
public void start(Stage stage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 300, 150);
stage.setScene(scene);
// If the progress bar is added to the root after the root is
// added to the scene and the scene is added to the stage, it will
// fail to be shown.
ProgressBar progBar = new ProgressBar();
progBar.setProgress(-1);
root.getChildren().add(progBar);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}