簡體   English   中英

JavaFX - 許多靜態FXML控制器

[英]JavaFX - Many Static FXML Controllers

存在JavaFX應用程序,應用程序從Main.class文件開始,該文件extends Application

  public class Main extends Application {

    /**
     * Keep a reference to the main Stage
     */
    public static Stage                 stage;
    /**
     * MainScene Controller
     */
    public static MainScene             mainSceneController;
    /**
     * The Capture Window of the application
     */
    public static CaptureWindow         captureWindowController;
    /**
     * Settings Scene Controller
     */
    public static SettingsController    settingsController;

    @Override
    public void start(Stage primary) throws Exception {

        stage = primary;
        ..........

        // CaptureWindow
        FXMLLoader loader1 = new FXMLLoader(getClass().getResource("/fxml/CaptureWindow.fxml"));
        loader1.load();
        captureWindowController = loader1.getController();

        // MainScene
        mainSceneController = new MainScene();

        .........   
    }

  }

描述

正如你在上面看到的,我有3個FXMLControllers (一個是可重用的[ extends StackPane ],其他沒有)。我已經聲明所有這些都是靜態的,因為我想從一個FXMLController從其他FXMLControllers訪問變量。我每次都使用這個策略使用JavaFX ,我覺得不好......

我如何更改下面的代碼,以便從其他FXMLController訪問一個FXMLController變量或方法? 沒有使用static關鍵字可以嗎?

考慮控制器由不同的類表示,這些類可以位於不同的包中。


在寫這個問題之前,我在FXML Controller中查看了Static @FXML變量

實際上這個問題的答案看起來有點復雜,它與MVC模式和它的演化有關,直到現在。我們將使用MVP模式。

經過長時間的討論后,我在這個網站http://martinfowler.com/eaaDev/uiArchs.html上找到了一個鏈接,定義了從Smalltalk的舊時代到現在使用的不同模式的歷史演變。


實際的解決方案是使用Model Viewer Presenter Pattern(MVP) ,可以使用這些圖像直觀地描述:

在此輸入圖像描述

在此輸入圖像描述

欲了解更多信息,請閱讀( http://www.wildcrest.com/Potel/Portfolio/mvp.pdf


有關JavaFX的示例,請查看James_D答案( 使用JavaFx應用MVC


最后但並非最不重要的是看看這里的評論:

最后:

如果有任何不准確的地方,請隨時編輯。

我認為您不應該使用static關鍵字聲明@FXML帶注釋的屬性。 請參閱此GitHub項目 ,了解如何執行此操作。 就像你只在需要時實例化控制器一樣,你的應用程序將是無狀態的。

JavaFx主要由一組[精心設計]工具組成,但不幸的是,它本身並沒有為創建復雜的UI設計提供良好的框架,例如MVC / MVP模式,視圖流和多個控制器上的操作,所以你必須依賴第三方應用程序框架,例如:

在我看來,沒有一個被廣泛使用或成熟到足以被視為事實上的標准,但鼓勵使用它們。


使用DataFx的示例

DataFx使用名為Flow的概念來關聯共享事件流(以及可能的數據)的視圖。 通過將Flow與EventSystem結合使用,您可以定義和訪問其他控制器上的方法,並將自定義事件偵聽器分配給與共享流的不同控制器中的JavaFx節點關聯的各種事件。

以下是DataFx示例中的示例,它表示具有不同FXML文件和控制器的兩個獨立的發送者和接收者視圖:

在此輸入圖像描述

public class EventSystemDemo extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

    HBox box = new HBox();
    box.setSpacing(12);
    box.setPadding(new Insets(12));
    box.setFillHeight(true);
    box.setAlignment(Pos.CENTER);

    Flow senderFlow = new Flow(ProducerController.class);
    box.getChildren().add(senderFlow.start());

    Flow receiverFlow = new Flow(ReceiverController.class);
    box.getChildren().add(receiverFlow.start());

    primaryStage.setScene(new Scene(box));
    primaryStage.show();

    }

    public static void main(String... args) {
        launch(args);
    }
}

發件人視圖控制器:

@ViewController("producer.fxml")
public class ProducerController {

    @FXML
    @EventTrigger()
    private Button sendButton;

    @FXML
    private TextField textField;

    @EventProducer("test-message")
    private String getMessage() {
        return textField.getText();
    }

}

接收器視圖控制器:

@ViewController("receiver.fxml")
public class ReceiverController {

    @FXML
    private Label messageLabel;

    @OnEvent("test-message")
    private void onNewChatMessage(Event<String> e) {
        messageLabel.setText(e.getContent());
    }
}

發件人查看:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<VBox alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="12.0" style="-fx-border-color: darkgrey; -fx-border-width: 2;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Label text="Sender">
         <font>
            <Font name="System Bold" size="24.0" />
         </font>
      </Label>
      <TextField fx:id="textField" />
      <Button fx:id="sendButton" mnemonicParsing="false" text="send" />
   </children>
   <padding>
      <Insets bottom="12.0" left="12.0" right="12.0" top="12.0" />
   </padding>
</VBox>

接收者視圖:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<VBox alignment="TOP_CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" spacing="12.0" style="-fx-border-color: darkgrey; -fx-border-width: 2;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <Label text="Receiver">
         <font>
            <Font name="System Bold" size="24.0" />
         </font></Label>
      <Label fx:id="messageLabel" />
    </children>
    <padding>
        <Insets bottom="12.0" left="12.0" right="12.0" top="12.0" />
    </padding>
</VBox>

進一步閱讀:

http://www.oracle.com/technetwork/java/javafx/community/3rd-party-1844355.html

http://www.guigarage.com/2015/02/quick-overview-datafx-mvc-flow-api/

http://www.guigarage.com/2014/05/datafx-8-0-tutorials/

http://jacpfx.org/2014/11/03/JacpFX_DataFX_a_perfect_match.html

傳遞參數JavaFX FXML

您可以實現自己的控制器工廠,這樣您就可以創建自己的控制器上下文。

我使用spring和javaFX,並且我已經使用spring實現了我自己的控制器工廠,這樣你可以在另一個中注入一個控制器(你不應該需要它,因為那些連接應該在模型上)

如果你想用Java fx嘗試spring: 如何使用spring依賴注入連接多個fxml控制器?

當然,您應該使用可幫助您構建代碼的應用程序框架。

如果您想嘗試JRebirth,只需將您的應用程序分為4個部分:

  • MainModel組成:
    • MainSceneModel
    • CaptureWindowModel
    • SettingsModel

您可以使用getModel(Model.class)訪問任何人,也可以使用sendWave(Wave)發送異步消息。

MainModel可以使用innerComponent將子模型緊密鏈接到它。

它使用起來非常簡單,如果你對我感興趣,我可以為你做一個示例應用程序原型讓我知道。

暫無
暫無

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

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