ControlFX 动作使用

ControlFX Action Usage

我有一个同时包含 MenuBarToolBar 的应用程序。我在 ControlsFX 文档中发现可以在不同的 class 中定义动作事件逻辑并将其分配给由 fxml 定义的按钮、菜单项和切换按钮。或多或少像 php 框架中的路由器(例如 laravel)。

这是描述

An action in JavaFX can be used to separate functionality and state from a control. For example, if you have two or more controls that perform the same function (e.g. one in a Menu and another on a toolbar), consider using an Action object to implement the function. An Action object provides centralized handling of the state of action-event-firing components such as buttons, menu items, etc. The state that an action can handle includes text, graphic, long text (i.e. tooltip text), and disabled.

问题是我无法获得足够的信息来在我的应用程序中使用它。这是我到目前为止的一个简单示例

public class RootController implements Initializable {
@FXML
private MenuItem menuOne;
@FXML
private MenuItem menuTwo;
@FXML
private MenuItem menuThree;
@FXML
private Button tbOne;
@FXML
private Button tbTwo;
@FXML
private Button tbThree;

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
}
}

root.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.VBox?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1">
   <top>
      <VBox BorderPane.alignment="CENTER">
         <children>
            <MenuBar>
          <menus>
            <Menu mnemonicParsing="false" text="File">
              <items>
                <MenuItem fx:id="menuOne" mnemonicParsing="false" text="One" />
              </items>
            </Menu>
            <Menu mnemonicParsing="false" text="Edit">
              <items>
                <MenuItem fx:id="menuTwo" mnemonicParsing="false" text="Two" />
              </items>
            </Menu>
            <Menu mnemonicParsing="false" text="Whatever">
              <items>
                <MenuItem fx:id="menuThree" mnemonicParsing="false" text="Three" />
              </items>
            </Menu>
          </menus>
        </MenuBar>
        <ToolBar prefHeight="40.0" prefWidth="200.0">
          <items>
            <Button fx:id="tbOne" mnemonicParsing="false" text="One" />
              <Button fx:id="tbTwo" layoutX="10.0" layoutY="13.0" mnemonicParsing="false" text="Two" />
              <Button fx:id="tbThree" layoutX="66.0" layoutY="13.0" mnemonicParsing="false" text="Three" />
          </items>
        </ToolBar>
     </children>
  </VBox>
   </top>
</BorderPane>

主要

public class MainApp extends Application {
public static void main(String[] args) throws Exception {launch(args); }

public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/root.fxml"));
    loader.setController(new RootController());
    Scene scene = new Scene((Parent)loader.load(), 400, 200);
    stage.setTitle("ControlFX Action API");
    stage.setScene(scene);
    stage.show();
}
}

AppRouter

public class AppRouter {
public AppRouter(){
    ActionMap.register(this); 
}

public void testOne(){
    System.out.println("testOne");
}

public void testTwo(){
    System.out.println("testTwo");
}

public void testThree(){
    System.out.println("testThree");
}
}

我的问题是如何将 AppRouter 中的方法分配给 RootController

中的按钮和菜单项

更新

我也很乐意接受任何其他替代答案。

Let's assume that you will create an Instance of AppRouter class in the Application class:

public class MainApp extends Application {

AppRouter appRouter = new AppRouter(); //here................

public static void main(String[] args) throws Exception {launch(args); }

public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/root.fxml"));
    loader.setController(new RootController());
    Scene scene = new Scene((Parent)loader.load(), 400, 200);
    stage.setTitle("ControlFX Action API");
    stage.setScene(scene);
    stage.show();
}
}

Then you can have a method which accepts an AppRouter,in the FXMLController:

public class RootController implements Initializable {
@FXML
private MenuItem menuOne;
@FXML
private MenuItem menuTwo;
@FXML
private MenuItem menuThree;
@FXML
private Button tbOne;
@FXML
private Button tbTwo;
@FXML
private Button tbThree;

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
}

public void acceptRouter(AppRouter router){


   //register or call router methods here
  }
}

How to get the controller you just created into the MainApp class?

    FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/root.fxml"));
    loader.setController(new RootController());

    RootController controller = loader.getController(); //simple as this,although check the method name if it is the same cause i added this from phone
    controller.acceptRouter(appRouter);