我没有一个MCV代码示例,因为这个问题更具有全球性,而且我不认为具体的代码实际上会产生很大的影响。
我有一个GUI应用程序,它有几个元素(数据夹、下拉列表、入口字段、表视图),根据JavaFX one ControllerClass,随着时间的推移,这个应用程序变得相当大。
因此,我在研究一种把它分开的方法。在我的研究中,我发现了两种主要的方法:
把更多的程序逻辑从UI部分中提取出来,这当然是有意义的,我对某些部分也是这样做的,但是对于很多部分来说,这似乎非常不方便,例如,如果我有一个函数使用六个不同的GUI元素,那么从控制器类中提取这个方法似乎很奇怪,因为我需要在函数调用中给它提供所有的GUI元素引用。有什么更好的办法吗?就像只使用setters/getter填充Controller,并将每个方法this
作为参数,这样它就可以进入this.dropbox1
了吗?
我发现的第二种方法是将GUI本身分割成几个场景。类似于this问题,但我不知道如何将一个GUI分割成几个场景,并将其放在一个窗口中。我知道您可以在主FXML文件中加载其他FXML文件,但我不知道如何将它们合并到一个窗口中的GUI中。如果有人有一个小示例代码,我将不胜感激。
发布于 2018-09-18 01:07:23
欢迎来到Stackoverflow,关于拆分:
您可以有一个根FXML,例如只包含一个GridPane (或者其他的东西,但我将继续在一个GridPane的前提下),现在您在那个根FXML文件中设置网格(没有内容),如果您已经完成了一个GUI,您应该清楚地知道网格单元需要有多大。在你的主课里你有:
扩展应用程序并启动GUI的主类
public class GUI extends Application {
private Stage stage;
private GridPane rootGrid;
@Override
public void start(Stage stage) {
this.stage = stage;
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(WindowRoot.class.getResource("RootGrid.fxml"));
rootGrid = (GridPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootGrid);
stage.setTitle("Test");
stage.show();
//fill the Grid
setupGrid();
}
现在您有了rootGrid
作为类属性,它只是一个网格,其中包含在RootGrid.fxml
中设置的空行/列,可以简单到如下所示:
FXML示例,两行,两列,没有内容
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<GridPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.141">
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" />
<RowConstraints minHeight="10.0" prefHeight="30.0" />
</rowConstraints>
<columnConstraints>
<ColumnConstraints minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
</GridPane>
现在,为要填充的每个单元格创建FXML文档,在该AnchorPane中有一个包含该单元格内容的FXML。然后将其作为start
方法的一部分添加到网格中。假设在这个简单的例子中,你想要一个菜单栏。为菜单创建一个FXML:
简单菜单fxml示例:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.141">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</AnchorPane>
并将其作为start
方法的一部分添加到网格中(但可能将其解压到您在start中调用的方法中,如setupGrid()
)。
建立网格,在启动(阶段)阶段调用
private void setupGrid() {
// Add Menubar
FXMLLoader loader = new FXMLLoader();
loader.setLocation(WindowRoot.class.getResource("menubar.fxml"));
AnchorPane anchor = (AnchorPane) loader.load();
//put it in first column, first row
GridPane.setConstraints(anchor, 0, 0);
//optional, let it span both/all columns
GridPane.setRowSpan(anchor, 2);
rootGrid.getChildren().add(anchor);
您将需要尝试/除了IO块,为了更好的可读性,不要使用它们。对于其他“根窗格”,您将需要其他设置-方法,例如,有一个borderPane,您会有类似于rootGrid.setTop(anchor)
的东西。
希望能帮上忙。玩得开心。
发布于 2018-09-18 01:26:07
如果您使用FXML,简单的事情是为FXML (一对一)设置一个控制器,而且我还添加了一个css,这是一种模式。
然后,您必须将屏幕分割成小部分:2种方法:
然后,您必须在控制器之间进行组合,最好的方法是有一个模型层,并通过单例共享它,例如使用afterburnerfx (一个非常小的注射器)。
当使用fx:include时,您还可以使用“嵌套控制器”从父控制器获得子控制器的引用。
最后,您的对象可能是具有可观察性的javaFX Beans,并且您只向另一个控制器公开可观察的而不是可视的组件:这样您的组件之间就有了松散的耦合。
https://stackoverflow.com/questions/52361378
复制相似问题