简体   繁体   中英

Why is my stage not clickable

This is my first app and i have no idea why is my stage not clickable along with the menuBar. I use SceneBuilder for creating the fxml and I added the tree items in the controllers initialize method.

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>

The only thing different from my other stages is the TreeView. If i make it in the main class it works fine. I think that the problem is within the initialize method and the way I build the treeView, but I have no idea what it can be.

After trying what Gash suggested and running my MainWindow.fxml from Main, the MainWindowController and MainWindow.fxml worked fine. Now the only other thing that stands between the working example and my version is the way i start the stage and I'm doing that after successful login in the starting stage of the app.

HomeScreenController

    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();
    }
}

I should have provided this class earlier. Sorry for that.

It looks like your missing an import for your AbstractController, which should throw a compile error. I pasted your code into NetBeans and changed

public class MainWindowController extends AbstractController implements Initializable {

to

public class MainWindowController implements Initializable

Everything works as it should.

If you need the AbstractController, you will need to add the import. For example:

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

My working code looks nearly identical to yours. I'm not able to see any difference, but below are the copies of your code working for me.

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>

MainWindowController:

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: Added stage.setTitle here for window title to work.

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);
    }

}

I got a null pointer exception with your closeStage() call. Instead of using this.stage , try setting the stage using the signInButton and then close it. I'm guessing your login window is APPLICATION_MODAL and isn't closing properly which would prevent input events to your new window. You might find the Stage Docs very helpful.

Here's a snip for your closeStage:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM