代码之家  ›  专栏  ›  技术社区  ›  Zephyr

两种加载fxml的方法;为什么一种比另一种更受欢迎?

  •  1
  • Zephyr  · 技术社区  · 6 年前

    我正在寻找关于为什么我们应该使用一种方法而不是另一种方法来加载和显示新的fxml阶段的反馈。

    大多数时候,我都会看到教程,这样可以显示从一个单独的类完成的一个阶段的加载。但是,它也可以在fxml文件的控制器内部完成,我个人认为这样做更干净,更易于管理。

    考虑以下内容 主类 班级:

    public class Main extends Application {
    
        @Override
        public void start(Stage stage) throws Exception {
    
            // Method 1:
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
                loader.setController(new LayoutController());
    
                stage.setScene(new Scene(loader.load()));
                stage.show();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    这似乎是流行的方法。它创建控制器并设置 Scene 然后显示出来。

    但是,如果我们改变 start() 方法改为:

    @Override
    public void start(Stage stage) throws Exception {
    
        LayoutController controller = new LayoutController();
        controller.showStage();
    
    }
    

    并将fxml加载代码移到 LayoutController 构造,结果相同:

    public class LayoutController {
    
        @FXML
        private Label label;
    
        private Stage stage = new Stage();
    
        public LayoutController() {
    
            // Method 2:
            try {
                FXMLLoader loader = new FXMLLoader(getClass().getResource("Layout.fxml"));
                loader.setController(this);
    
                stage.setScene(new Scene(loader.load()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public void showStage() {
            this.stage.showAndWait();
        }
    }
    

    我在这里看到的好处是视图和逻辑之间有更多的分离。关于 布局控制器 其关联的fxml文件包含在一个位置。

    所以我的问题是:第二种方法有什么问题?我认为这不是标准方法的原因,但我看不到任何缺点。

    这样的问题是否更适合代码审查?我不是真的在征求意见,因为似乎有一个一般的“规则”是第一种方法被使用。

    1 回复  |  直到 6 年前
        1
  •  5
  •   fabian    6 年前

    在这种情况下,没有什么区别。

    对于较大的项目,第二种方法是不受欢迎的困难:

    它违反了 single responsibility principle :

    班级负责:

    • 创建场景
    • 创造舞台
    • 显示阶段(更糟的是,它以可能干扰其他逻辑的方式进行显示( showAndWait )
    • 它是视图的控制器,可能负责处理多个事件

    此外,类的设计方式可以防止责任转移到其他没有问题的类中。

    在较大的程序中,您可能希望创建一个类,该类管理将数据传递到视图、排列窗口或将视图显示为场景的一部分等。第二种方法不适合这样做。

    此外,如果不重复自己的话,那就更难了。除非将逻辑移动到公共父类型,否则还需要实现在每个控制器类中显示场景的逻辑。重复相同或相似的代码会导致难以维护的代码。


    注: 使用一个类来加载fxml并将其用作控制器并不一定是一件坏事,但是您应该使用 自定义组件 方法介绍于 Introduction to FXML .