为什么我的舞台不可点击

Why is my stage not clickable

这是我的第一个应用程序,我不知道为什么我的舞台无法与菜单栏一起点击。我使用 SceneBuilder 创建 fxml,并在控制器初始化方法中添加了树项。

MainWindowController.java

    package gui;


import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.MenuBar;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

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

public class MainWindowController extends AbstractController implements Initializable {

    private Stage stage = null;

    @FXML
    private AnchorPane mainContainer;

    @FXML
    private VBox vBoxContainer;

    @FXML
    private MenuBar menuBarTop;

    @FXML
    private HBox hBoxContainer;

    @FXML
    private StackPane navigationSection;

    @FXML
    private TreeView<String> treeView;



    final private TreeItem<String> rootIssues = new TreeItem<String>("IssueTracker");
    final private TreeItem<String> issuesTable = new TreeItem<String>("IssuesTable");
    final private TreeItem<String> stickers = new TreeItem<String>("Stickers");

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        rootIssues.setExpanded(true);
        rootIssues.getChildren().addAll(issuesTable, stickers);
        treeView.setRoot(rootIssues);

    }

    public void setStage(Stage stage)   {
        this.stage = stage;
        stage.setResizable(true);
        stage.setTitle("SoloStats - Welcome");
    }

    public void closeStage()    {
        if (this.stage != null) {
            this.stage.close();
        }
    }
}

MainWindow.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.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>

<AnchorPane fx:id="mainContainer" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.MainWindowController">
   <children>
      <VBox fx:id="vBoxContainer" layoutX="530.0" layoutY="230.0" prefHeight="25.0" prefWidth="1200.0" AnchorPane.bottomAnchor="572.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <children>
            <MenuBar fx:id="menuBarTop" prefHeight="25.0">
              <menus>
                <Menu mnemonicParsing="false" text="File">
                  <items>
                    <MenuItem mnemonicParsing="false" text="Close" />
                  </items>
                </Menu>
                <Menu mnemonicParsing="false" text="Edit">
                  <items>
                    <MenuItem mnemonicParsing="false" text="Delete" />
                  </items>
                </Menu>
                <Menu mnemonicParsing="false" text="Help">
                  <items>
                    <MenuItem mnemonicParsing="false" text="About" />
                  </items>
                </Menu>
              </menus>
            </MenuBar>
         </children>
      </VBox>
      <HBox fx:id="hBoxContainer" layoutX="384.0" layoutY="238.0" prefHeight="600.0" prefWidth="1200.0" style="-fx-background-color: rgb(247, 247, 247);" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="25.0">
         <children>
            <StackPane fx:id="navigationSection" prefHeight="150.0" prefWidth="300.0" style="-fx-background-color: #222;">
               <children>
                  <TreeView fx:id="treeView" fixedCellSize="24.0" prefHeight="200.0" prefWidth="200.0" />
               </children>
            </StackPane>
         </children>
      </HBox>
   </children>
</AnchorPane>

唯一与我的其他阶段不同的是 TreeView。如果我在主要 class 中做到这一点,它就可以正常工作。我认为问题出在初始化方法和我构建 treeView 的方式中,但我不知道它会是什么。

在尝试了 Gash 的建议和 运行 我的 MainWindow.fxml 来自 Main 的方法后,MainWindowController 和 MainWindow.fxml 工作正常。现在,工作示例和我的版本之间唯一的另一件事是我开始阶段的方式,我在应用程序的开始阶段成功登录后这样做。

主屏幕控制器

    package gui;

import connectivity.DataBaseHandler;
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;

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

public class HomeScreenController extends AbstractController implements Initializable {
    private DataBaseHandler dbHandler = new DataBaseHandler();

    @FXML
    private AnchorPane homeWindow;

    @FXML
    private TextField insertNameField;

    @FXML
    private PasswordField insertPasswordField;

    @FXML
    private TextField insertDepartmentField;

    @FXML
    private Button signInButton;

    @FXML
    private Button signupButton;
    private Main main;

    @FXML
    private Label mainAlertText;
    private Stage stage = null;

    @Override
    public void initialize(URL url, ResourceBundle rb)  {
        signupButton.setOnAction((event)->{
            showPopupWindow();
        });

        signInButton.disableProperty().bind(Bindings.createBooleanBinding( () -> (insertNameField.getText().isEmpty()
                || insertPasswordField.getText().isEmpty() || insertDepartmentField.getText().isEmpty()),
                insertNameField.textProperty(), insertPasswordField.textProperty(), insertDepartmentField.textProperty()));

        signInButton.setOnAction((event -> {
            if  (dbHandler.login(insertNameField.getText(), insertDepartmentField.getText(), insertPasswordField.getText()))    {
                mainAlertText.setTextFill(Color.GREEN);
                mainAlertText.setText("Login Successfull");
                closeStage();
                showMainWidow();
            } else  {
                mainAlertText.setTextFill(Color.RED);
                mainAlertText.setText("One or more of the values are not correct");
            }
        }));
    }

    private void showPopupWindow() {

        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("SignUpPopUp.fxml"));
        // initializing the controller
        SignUpPopUpController popupController = new SignUpPopUpController();
        loader.setController(popupController);
        Parent layout;
        try {
            layout = loader.load();
            Scene scene = new Scene(layout);
            // this is the popup stage
            Stage popupStage = new Stage();
            popupStage.setResizable(false);
            // Giving the popup controller access to the popup stage (to allow the controller to close the stage)
            popupController.setStage(popupStage);
            if(this.main != null) {
                popupStage.initOwner(main.getPrimaryStage());
            }
            popupStage.initModality(Modality.APPLICATION_MODAL);
            popupStage.setScene(scene);
            popupStage.showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void showMainWidow() {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("MainWindow.fxml"));
        //initializing the controller
        MainWindowController mainWindowController = new MainWindowController();
        Parent layout;
        try {
            layout = loader.load();
            Scene scene = new Scene(layout);
            //the main stage
            Stage mainStage = new Stage();
            mainWindowController.setStage(mainStage);
            if (this.main != null)  {
                mainStage.initOwner(main.getPrimaryStage());
            }
            mainStage.initModality(Modality.NONE);
            mainStage.setScene(scene);
            mainStage.showAndWait();
        } catch (IOException e)   {
            e.printStackTrace();
        }
    }

    public void showHomeScreen() {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("HomeScreen.fxml"));
        loader.setController(this);
        Parent layout;
        try {
            layout = loader.load();
            Scene scene = new Scene(layout);
            //this is the stage
            Stage mainStage = new Stage();
            this.setStage(mainStage);
            mainStage.initModality(Modality.APPLICATION_MODAL);
            mainStage.setScene(scene);
            mainStage.showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void setStage(Stage stage)   {
        this.stage = stage;
        this.stage.setResizable(false);
        this.stage.setTitle("SoloStats");
    }

    public Stage getStage() {
        return this.stage;
    }

    public void closeStage()    {
        this.stage.close();
    }
}

我应该早点提供这个 class。抱歉。

您似乎缺少对 AbstractController 的导入,这应该会引发编译错误。我将您的代码粘贴到 NetBeans 中并进行了更改

public class MainWindowController extends AbstractController implements Initializable {

public class MainWindowController implements Initializable

一切正常。

如果需要AbstractController,则需要添加import。例如:

import org.springframework.web.servlet.mvc.AbstractController;

我的工作代码看起来和你的几乎一样。我看不出有什么不同,但下面是您为我工作的代码副本。

MainWindow.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.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>

<AnchorPane fx:id="mainContainer" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.MainWindowController">
   <children>
      <VBox fx:id="vBoxContainer" layoutX="530.0" layoutY="230.0" prefHeight="25.0" prefWidth="1200.0" AnchorPane.bottomAnchor="572.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <children>
            <MenuBar fx:id="menuBarTop" prefHeight="25.0">
              <menus>
                <Menu mnemonicParsing="false" text="File">
                  <items>
                    <MenuItem mnemonicParsing="false" text="Close" />
                  </items>
                </Menu>
                <Menu mnemonicParsing="false" text="Edit">
                  <items>
                    <MenuItem mnemonicParsing="false" text="Delete" />
                  </items>
                </Menu>
                <Menu mnemonicParsing="false" text="Help">
                  <items>
                    <MenuItem mnemonicParsing="false" text="About" />
                  </items>
                </Menu>
              </menus>
            </MenuBar>
         </children>
      </VBox>
      <HBox fx:id="hBoxContainer" layoutX="384.0" layoutY="238.0" prefHeight="600.0" prefWidth="1200.0" style="-fx-background-color: rgb(247, 247, 247);" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="25.0">
         <children>
            <StackPane fx:id="navigationSection" prefHeight="150.0" prefWidth="300.0" style="-fx-background-color: #222;">
               <children>
                  <TreeView fx:id="treeView" fixedCellSize="24.0" prefHeight="200.0" prefWidth="200.0" />
               </children>
            </StackPane>
         </children>
      </HBox>
   </children>
</AnchorPane>

主窗口控制器:

package gui;


import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.MenuBar;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

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

public class MainWindowController implements Initializable {

    private Stage stage = null;

    @FXML
    private AnchorPane mainContainer;

    @FXML
    private VBox vBoxContainer;

    @FXML
    private MenuBar menuBarTop;

    @FXML
    private HBox hBoxContainer;

    @FXML
    private StackPane navigationSection;

    @FXML
    private TreeView<String> treeView;



    final private TreeItem<String> rootIssues = new TreeItem<String>("IssueTracker");
    final private TreeItem<String> issuesTable = new TreeItem<String>("IssuesTable");
    final private TreeItem<String> stickers = new TreeItem<String>("Stickers");

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        rootIssues.setExpanded(true);
        rootIssues.getChildren().addAll(issuesTable, stickers);
        treeView.setRoot(rootIssues);

    }

    public void setStage(Stage stage)   {
        this.stage = stage;
        stage.setResizable(true);
        stage.setTitle("SoloStats - Welcome");
    }

    public void closeStage()    {
        if (this.stage != null) {
            this.stage.close();
        }
    }
}

Gui.java:在此处添加 stage.setTitle 以获得 window 标题。

package gui;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Gui extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MainWindow.fxml"));
        stage.setTitle("SoloStats - Welcome");
        Scene scene = new Scene(root);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

我在调用 closeStage() 时遇到空指针异常。不要使用 this.stage,而是尝试使用 signInButton 设置舞台,然后关闭它。我猜你的登录 window 是 APPLICATION_MODAL 并且没有正确关闭,这会阻止输入事件到你的新 window。您可能会发现 Stage Docs 非常有帮助。

这是您的 closeStage 的片段:

public void closeStage() {
        Stage stage = (Stage) signInButton.getScene().getWindow();
        stage.close();
    }