JavaFX:在数据准备就绪之前禁用大部分阶段

JavaFX:在数据准备就绪之前禁用大部分阶段,java,javafx,data-binding,Java,Javafx,Data Binding,我面临的问题很简单,但很普遍 问题设置 我有一个带有主窗口(主阶段)的JavaFX应用程序。此阶段使用一些(保持通用)数据。数据可能在启动时以某种方式加载(例如,从服务器、数据库、XML文件)。数据源(服务器地址、数据库名称、XML文件路径)将由用户提示。(请记住,用户可以取消输入,而不会加载数据。) 由于我想向用户展示舞台(了解应用程序并可能浏览帮助),然后通过菜单File->Load data,让用户加载数据 但是由于stage主要依赖于数据,因此我需要禁用大多数控件,直到用户正确加载数据并

我面临的问题很简单,但很普遍

问题设置 我有一个带有主窗口(主阶段)的JavaFX应用程序。此阶段使用一些(保持通用)数据。数据可能在启动时以某种方式加载(例如,从服务器、数据库、XML文件)。数据源(服务器地址、数据库名称、XML文件路径)将由用户提示。(请记住,用户可以取消输入,而不会加载数据。)

由于我想向用户展示舞台(了解应用程序并可能浏览帮助),然后通过菜单
File->Load data
,让用户加载数据

但是由于stage主要依赖于数据,因此我需要禁用大多数控件,直到用户正确加载数据并使stage可用

问题: 这里出现了我无法解决的难题。好的,我有两个选择,如何在数据准备就绪之前禁用大部分阶段:

  • 使用“或未加载数据”禁用绑定 更为JavaFX绑定友好的解决方案是使用布尔属性,如
    dataNotReadyProperty
    ,然后在初始化控制器时使用以下内容:

     private void init() { // call from initialize method
       // ....
       doFooButton.disableProperty().bind(
         Bindings.or(
           dataProperty().get().cannotBeFooDoneProperty(),
           dataNotReadyProperty()
         )
       );
       // ....
     }
    
  • 如您所见,此代码非常难看且很长(特别是当一些控件因额外的
    而失去功能时)

  • 数据准备就绪时禁用和绑定 第二个选项是在启动时(甚至在FXML中)简单地禁用所有内容。还可以为
    数据属性设置更改侦听器,并在加载数据时正确初始化绑定。用代码编写:

     private void init() { // call from initialize method
       // ....
       doFooButton.setDisabled(true);
       // ....
       dataProperty().addListener((observable, oldValue, newValue) -> {
         if (oldValue == null && newValue != null) {
           runInitialization();
         }
       });
     }
    
     private void runInitialization() {
       // ....
       doFooButton.disableProperty().bind(
         dataProperty().get().cannotBeFooDoneProperty());
       // ....
     }
    
  • 此解决方案将初始化分为两部分,但此处的“真正”初始化保持简单易懂。此外,我被迫修改每个控件两次

    结论 你喜欢什么?你有没有其他建议,如何解决这种情况

    附加信息
    • 与禁用属性的绑定相比,该阶段确实需要更多的初始化
    • 数据一旦加载,就不能“卸载”(只能由另一个重新加载)
    • 大约有20个控件在启动时被禁用,4个控件可访问
    最后,我决定使用基于@ItachiUchiha答案的解决方案

    我创建了两个不同的窗格,一个用于正确处理数据,另一个带有标签,如“加载数据以开始工作”和“加载按钮”


    其余(大约5个)控件由绑定禁用/启用(选项1)。因此,“丑陋”代码的数量迅速减少。

    尝试将所有需要禁用的控件放在一个窗格/组中(我个人从未在一个组中尝试过),然后禁用窗格/组。这可能不会有多大帮助,但是。无需使用Bindings类,您只需执行
    property1.或(property2)
    。由于数据源由用户决定,因此我建议保留此视图(您接受源信息的视图)作为默认视图。一旦用户填写了必要的信息并提交,您就可以用数据加载新视图。@Sedrick:不错,可能可以,但我需要选择性地启用窗格的某些控件。@VGR我知道,但我的一些绑定表达式非常复杂,无法读取或无法以这种方式创建事件。