【问题标题】:JavaFX: How to split menu controller?JavaFX:如何拆分菜单控制器?
【发布时间】:2017-07-11 12:45:07
【问题描述】:

我正在开发 JavaFX 应用程序。我想写一个记事本。现在我正在处理我的菜单栏。这是我的 Menu.fxml 文件:

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

<?import javafx.scene.control.*?>
<MenuBar id="menuBar" fx:id="menuBar" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.menu.MenuController">
    <menus>
        <Menu id="fileMenu" fx:id="fileMenu" mnemonicParsing="false" text="File">
            <items>
                <MenuItem id="newFileItem" fx:id="newFileItem" text="New Ctrl+N" />
                <MenuItem id="openFileItem" fx:id="openFileItem" text="Open Ctrl+O" onAction="#openFile" />
                <MenuItem id="saveFileItem" fx:id="saveFileItem" text="Save Ctrl+S" />
                <MenuItem id="saveFileAsItem" fx:id="saveFileAsItem" text="Save file as... Ctrl+S"/>
            </items>
        </Menu>
        <Menu id="editionMenu" fx:id="editionMenu" mnemonicParsing="false" text="Edit">
        </Menu>
        <Menu id="settingsMenu" fx:id="settingsMenu" mnemonicParsing="false" text="Settings">
        </Menu>
        <Menu id="helpMenu" fx:id="helpMenu" mnemonicParsing="false" text="Help">
        </Menu>
    </menus>
</MenuBar>

我想为每个菜单编写一个通用控制器和几个专用控制器,这样我就没有一个负责文件管理、设置、编辑等的大控制器。 这是菜单控制器:

package controllers.menu;

import javafx.fxml.FXML;
import javafx.scene.control.MenuBar;

public class MenuController {

    @FXML
    private MenuBar menuBar;

    private FileMenuController fileMenuController;
    private EditMenuController editMenuController;
    private SettingsMenuController settingsMenuController;
    private HelpMenuController helpMenuController;

    public MenuController() {
        fileMenuController = new FileMenuController();
        fileMenuController.setMenuBar(menuBar);
    }

    public void openFile(){
        fileMenuController.openFile();
    }
}

这是 FileMenuController:

package controllers.menu;

import javafx.scene.control.MenuBar;
import javafx.stage.FileChooser;

import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;

class FileMenuController {

    private MenuBar menuBar;

    public void openFile() {
        FileChooser fileChooser = new FileChooser();
        fileChooser.setTitle("Open");
        fileChooser.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("*.txt", "*.txt"),
                new FileChooser.ExtensionFilter("All types", "*.*")
        );
        File file = fileChooser.showOpenDialog(menuBar.getScene().getWindow());
    }

    public void setMenuBar(MenuBar menuBar) {
        this.menuBar = menuBar;
    }

}

当我在文件菜单中选择打开选项时,出现以下异常:

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
Caused by: java.lang.NullPointerException
    at controllers.menu.FileMenuController.openFile(FileMenuController.java:23)
    at controllers.menu.MenuController.openFile(MenuController.java:19)

谁能给我一些建议如何解决这个问题?有没有更好的方法来拆分菜单控制器,以便每个控制器只负责一件事?

【问题讨论】:

  • 在设置 menuBar 之前调用构造函数,可能使用对 MenuController 的引用,然后有一个方法 getMenuBar?
  • 您能否在您的特定菜单中添加适当的标签,例如fx:controller="controllers.menu.FileMenuController"
  • 一个fxml文件只能有一个控制器,所以很遗憾我不能为每个菜单项添加一个控制器。
  • 我忘记了 Initializable 接口...谢谢你,马特!我可以在初始化方法中创建 FileMenuController 而不是在构造函数中创建它。然后就可以了。

标签: java javafx


【解决方案1】:

在设置 menuBar 之前调用了构造函数,因此 MenuController 应该使用 Initalizable 接口中的 initalize 方法。 固定菜单控制器:

package controllers.menu;

import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.MenuBar;

import java.net.URL;
import java.util.ResourceBundle;

public class MenuController implements Initializable{

    @FXML
    private MenuBar menuBar;

    private FileMenuController fileMenuController;
    private EditMenuController editMenuController;
    private SettingsMenuController settingsMenuController;
    private HelpMenuController helpMenuController;

    public void openFile(){
        fileMenuController.openFile();
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        fileMenuController = new FileMenuController();
        fileMenuController.setMenuBar(menuBar);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    相关资源
    最近更新 更多