簡體   English   中英

拆分JavaFX控制器類

[英]Splitting up JavaFX Controller Class

我沒有MCV代碼示例,因為問題更全局,我不認為具體的代碼實際上有很大的不同。

我有一個GUI應用程序,包含多個Elements(datepickers,下拉列表,輸入字段,tabletreeview),並且根據JavaFX,一個ControllerClass隨着時間的推移變得非常大。

因此,我正在尋找一種方法將其拆分。 在我的研究中,我找到了兩種主要方法:

從UI部分獲取更多的程序邏輯,這當然總是有意義的,我為某些部分做了這些,但對於許多人來說似乎非常不方便,例如,如果我有一個使用六個不同GUI元素的函數,它似乎很奇怪從控制器類中提取該方法,因為我需要在函數調用中為它提供所有那些GUI元素引用。 我錯過了一些更好的默默方式嗎? 像填充控制器類只是制定者/ getter和讓每一個方法, this作為參數,以便它可以去this.dropbox1

我找到的第二種方法是將GUI本身分成幾個場景。 這個問題,但我不知道如何將一個GUI分成幾個場景,並仍然在一個窗口中。 我確實知道你可以在main-FXML文件中加載其他FXML文件,但我不知道如何在一個窗口中將它們組合到一個GUI中。 如果有人為此提供了一些示例代碼,我將不勝感激。

歡迎來到Stackoverflow Labib,關於拆分:

您可以擁有一個根FXML,其中僅包含一個GridPane(或者其他,但我將繼續在GridPane前提下),現在您在該根FXML文件中設置了Grid(沒有內容),如果您已經有完成GUI后,你應該清楚地知道grid-Cells需要多大。 在您的主班中,您有:

擴展Application並啟動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>

現在,您為要填充的每個Cell創建FXML文檔,在FXML中,您有一個AnchorPane,其中包含該Cell的內容。 然后將其作為start方法的一部分添加到Grid中。 假設您想在這個簡單的示例中使用菜單欄。 為菜單創建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()

設置Grid,在start(階段階段)中調用

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塊,將它們留下以獲得更好的可讀性。 對於其他“Root-Panes”,您將需要其他設置方法,例如,您可以使用borderPane,例如rootGrid.setTop(anchor)
希望能幫助到你。 玩得開心。

如果你使用FXML,簡單的事情是有一個FXML的控制器(一對一)和personnaly我也添加一個CSS,它是一種模式。

然后你必須將屏幕分成小部分:2種方法:

  • 使用fx:include:你包含一個FXML,它本身聲明一個控制器
  • 使用組件:您包含組件的標簽,該標簽本身可以加載FXML和控制器

然后你必須在你的控制器之間進行通信,最好的是有一個模型層,並通過單例共享它,例如使用afterburnerfx(一個非常小的注入器)

使用fx:include時,您還可以使用“嵌套控制器”從父級獲取子控制器的引用。

最后你的對象可能是帶有observable的javaFX Beans,你只能將可觀察的和不可視的組件從控制器暴露給另一個:這樣你的組件之間就會松散耦合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM