В JavaFX - много статических регуляторов FXML-файл

A JavaFX приложение существует, и приложение начинается с , который 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 в контроллере FXML

5 ответов


на самом деле ответ на этот вопрос кажется немного сложным, это связано с шаблона MVC и его эволюция до сих пор.Мы будем использовать шаблон MVP.

после долгого обсуждения я получил ссылку на этот сайт http://martinfowler.com/eaaDev/uiArchs.html определение исторической эволюции различных моделей, используемых с древних времен Smalltalk до сих пор.


фактически решение использует Model Viewer Presenter Pattern(MVP) который можно визуально описать используя эти изображения:

enter image description here

enter image description here

подробнее вы можете прочитать (http://www.wildcrest.com/Potel/Portfolio/mvp.pdf)


для примера на JavaFX посмотрите на James_D ответ здесь (применение MVC с JavaFx)


последний, но не в последнюю очередь взглянуть на комментарии здесь:

и наконец:

Если что-то неточно, не стесняйтесь редактировать.


Я думаю, что вы не должны объявлять аннотированные атрибуты @FXML со статическим ключевым словом. Смотрите это проект GitHub о том, как вы должны сделать это. Похоже, что вы создаете экземпляр контроллера только тогда, когда это необходимо, и ваше приложение будет без гражданства.


JavaFx в основном состоит из набора [хорошо разработанных] инструментов, но, к сожалению, сам по себе не обеспечивает хорошую основу для создания сложных конструкций пользовательского интерфейса, например, шаблонов MVC/MVP, потоков просмотра и действий на нескольких контроллерах, поэтому вам нужно полагаться на сторонние рамки приложений для тех, например:

на мой взгляд, ни один из них не используется широко или достаточно зрелый, чтобы считаться стандартом де-факто, но их использование поощряется.


Пример Использования DataFx

DataFx использует концепцию с именем поток связать представления, разделяющие поток событий (и, возможно, данных) между собой. Используя Flow в сочетании с EventSystem вы можете определить и методы доступа на других контроллерах и назначьте пользовательские прослушиватели событий различным событиям, связанным с узлами JavaFx в разных контроллерах, совместно использующих поток.

вот пример образцы DataFx который представляет собой два отдельных представления отправителя и получателя с различными файлами FXML и контроллерами:

enter image description here

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, таким образом, вы можете вводить один контроллер в другой (вам это не нужно, так как эти соединения должны быть на модели)

Если вы хотите попробовать spring с Java fx:как подключить несколько контроллеров fxml с помощью spring зависимость-инъекций?


Наверняка вы должны использовать фреймворк, который поможет вам структурировать ваш код.

Если вы хотите попробовать JRebirth, просто разрежьте приложение на 4 части:

  • MainModel сочинил:
    • MainSceneModel
    • CaptureWindowModel
    • SettingsModel

вы можете получить доступ к одному из любого с помощью getModel (модель.класса) или отправить асинхронное сообщение, используя sendWave (волна).

MainModel может использовать innerComponent, чтобы плотно связать с ним дочернюю модель.

Это довольно простой в использовании, если вы заинтересованы в я могу прототип вам образец приложения просто дайте мне знать.