我需要从另一个控制器类(javafx和SceneBuilder)访问和清除窗格

时间:2017-09-29 10:48:03

标签: java javafx fxml scenebuilder

我知道有很多问题已经解决了,但我无法理解它。它可能是重复的:

accessing a Pane from another class in javafx

JavaFX change Pane color from a different class

在我的应用程序中,我想从NotesScreenController中的mouseEvent清除MainWindowController中的changablePane(StackPane),以便只显示标记为已完成的注释。

MainWindowController.java

package gui;

import gui.mainWindow.issues.NotesScreenController;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Stack;

public class MainWindowController implements Initializable {

    private Stage stage = null;
    private StackPane paneNotes = null;
    private NotesScreenController secondPane;

    @FXML
    private AnchorPane mainContainer;

    @FXML
    private VBox vBoxContainer;

    @FXML
    private MenuBar menuBarTop;

    @FXML
    private HBox hBoxContainer;

    @FXML
    private StackPane navigationSection;

    @FXML
    private TreeView<Button> treeView;

    @FXML
    private StackPane changablePane;

    public static Button issuesNotes;


    //TAB SO FILTRI
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        createTreeView();
    }

    private void createTreeView()   {
        Button treeViewHeader = new Button("Zdravo");
        TreeItem<Button> treeViewHeaderItem = new TreeItem<>(treeViewHeader);
        treeViewHeader.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");
        treeViewHeaderItem.setExpanded(true);
        //ROOT FOR ISSUES TRACKING
        Button rootForIssues = new Button("Issues Tracker");
        Button issuesTable = new Button("Issues Table");
        issuesNotes = new Button("Request Notes");
        TreeItem<Button> rootForIssuesItem = new TreeItem<>(rootForIssues);
        TreeItem<Button> issuesTableItem = new TreeItem<>(issuesTable);
        TreeItem<Button> issuesNotesItem = new TreeItem<>(issuesNotes);

        rootForIssues.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");
        issuesTable.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");
        issuesNotes.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");

        rootForIssuesItem.setExpanded(true);
        rootForIssuesItem.getChildren().addAll(issuesTableItem, issuesNotesItem);

        //ROOT ZA NEKOE DRUGO - PROBNO
        Button buttonA = new Button("Proba");
        Button buttonB = new Button("Proba");
        Button buttonC = new Button("Proba");
        TreeItem<Button> nodeA = new TreeItem<>(buttonA);
        TreeItem<Button> nodeB = new TreeItem<>(buttonB);
        TreeItem<Button> nodeC = new TreeItem<>(buttonC);

        buttonA.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");
        buttonB.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");
        buttonC.getStylesheets().add("styles/Notes/TreeViewStyles/TreeButton.css");

        nodeA.setExpanded(true);
        nodeA.getChildren().addAll(nodeB, nodeC);

        //ADDING ALL ROOTs OF THE TREEVIEW
        treeViewHeaderItem.getChildren().addAll(rootForIssuesItem, nodeA);

        issuesNotes.setOnAction(event ->{
            clearPane();
            URL paneOneUrl = getClass().getClassLoader().getResource("gui/mainWindow/issues/NotesScreen.fxml");
            FXMLLoader loader = new FXMLLoader();
            NotesScreenController nsc = new NotesScreenController();
            loader.setController(nsc);
            try {
                paneNotes = loader.load(paneOneUrl);
                changablePane.getChildren().add(paneNotes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        issuesTable.setOnAction(event ->    {
            clearPane();
        });

        //TREE VIEW
        treeView.setId("tree-view-issues");
        treeView.getStylesheets().addAll("styles/Notes/TreeViewStyles/TreeView.css");
        treeView.setRoot(treeViewHeaderItem);
    }

    public void clearPane()  {
        changablePane.getChildren().clear();
    }

    public void getMainScreenController()   {

    }

    public static Button getIssuesNotes()   {
        return issuesNotes;
    }

    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.geometry.Insets?>
<?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="1.7976931348623157E308" maxWidth="1.7976931348623157E308" 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">
                     <StackPane.margin>
                        <Insets left="-25.0" />
                     </StackPane.margin>
                  </TreeView>
               </children>
            </StackPane>
            <StackPane fx:id="changablePane" prefHeight="575.0" prefWidth="950.0" stylesheets="@../styles/MainWindow/StackPaneChangable.css" HBox.hgrow="ALWAYS" />
         </children>
      </HBox>
   </children>
</AnchorPane>

NotesScreenController.java

package gui.mainWindow.issues;

import gui.MainWindowController;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class NotesScreenController extends AnchorPane implements Initializable {
    private NotesDirectory notesDirectory = new NotesDirectory();
    private MainWindowController mainController;

    @FXML
    private StackPane mainContainer;

    @FXML
    private VBox vBoxContainer;

    @FXML
    private HBox hBoxFilterContainer;

    @FXML
    private ScrollPane scrollPane;

    @FXML
    private TilePane tilePaneNotesScreen;

    @FXML
    private ComboBox<String> generalSortBox;

    @FXML
    private ComboBox<String> sortByNameBox;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        loadScreen();
    }

    public void loadScreen()    {
        try {
            notesDirectory.insertNotesToTilePane(tilePaneNotesScreen, notesDirectory.deserializedNotesList(notesDirectory.getFileName(new File("src/notesDirectory")), "src/notesDirectory/"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        generalSortBox.setItems(FXCollections.observableArrayList("Flagged", "Date added", "Done Notes"));
        sortByNameBox.setItems(FXCollections.observableArrayList("Priority", "Priority", "Priority", "Priority",
                "Priority", "Priority", "Priority", "Priority", "Priority", "Priority", "Priority", "Priority",
                "Priority", "Priority"));
        generalSortBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> selected, String oldValue, String newValue) {
                if (newValue != null)   {
                    switch (newValue)   {
                        case "Done Notes": try {
                            //THE ACTION NEED TO TAKE PLACE HERE
                            notesDirectory.insertNotesToTilePane(tilePaneNotesScreen, notesDirectory.deserializedNotesList(notesDirectory.getFileName(new File("src/notesRecycleBin")), "src/notesRecycleBin/"));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
    }

    public void setMainController(MainWindowController controller) {
        this.mainController = controller;
    }
}

NotesScreen

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.TilePane?>
<?import javafx.scene.layout.VBox?>


<StackPane fx:id="mainContainer" prefHeight="575.0" prefWidth="950.0" stylesheets="@../../../styles/MainWindow/StackPaneChangable.css" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="gui.mainWindow.issues.NotesScreenController">
   <children>
      <VBox fx:id="vBoxContainer" prefHeight="575.0" prefWidth="950.0">
         <children>
            <HBox fx:id="hBoxFilterContainer" stylesheets="@../../../styles/MainWindow/ChoiceBox/HBoxFilters.css">
               <children>
                  <ComboBox fx:id="generalSortBox" prefHeight="25.0" prefWidth="220.0" promptText="Sort by..." stylesheets="@../../../styles/MainWindow/ChoiceBox/ComboBox.css" />
                  <ComboBox fx:id="sortByNameBox" prefHeight="25.0" prefWidth="220.0" promptText="Choose name" stylesheets="@../../../styles/MainWindow/ChoiceBox/ComboBox.css" />
               </children>
            </HBox>
            <ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" hbarPolicy="NEVER" prefHeight="575.0" prefWidth="950.0" stylesheets="@../../../styles/MainWindow/StackPaneChangable.css" VBox.vgrow="ALWAYS">
               <content>
                  <TilePane fx:id="tilePaneNotesScreen" hgap="25.0" prefColumns="4" prefHeight="575.0" prefTileWidth="228.0" prefWidth="950.0" stylesheets="@../../../styles/MainWindow/StackPaneChangable.css" vgap="25.0">
                     <padding>
                        <Insets bottom="25.0" left="25.0" right="25.0" top="35.0" />
                     </padding>
                  </TilePane>
               </content>
            </ScrollPane>
         </children>
      </VBox>
   </children>
</StackPane>

1 个答案:

答案 0 :(得分:0)

基本上你缺少的是在NotesScreenController实例中设置主屏幕控制器:

FXMLLoader loader = new FXMLLoader();
NotesScreenController nsc = new NotesScreenController();
loader.setController(nsc);

nsc.setMainController(this);

然后从NotesScreenController开始,只需拨打

即可清除窗格
mainController.clearPane();

即。你可以这样做:

generalSortBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
    @Override
    public void changed(ObservableValue<? extends String> selected, String oldValue, String newValue) {
        if (newValue != null)   {
            switch (newValue)   {
                case "Done Notes": try {
                    //THE ACTION NEED TO TAKE PLACE HERE
                    mainController.clearPane();
                    notesDirectory.insertNotesToTilePane(tilePaneNotesScreen, notesDirectory.deserializedNotesList(notesDirectory.getFileName(new File("src/notesRecycleBin")), "src/notesRecycleBin/"));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
});

请注意,您有一个微妙的错误:当您致电

paneNotes = loader.load(paneOneUrl); 

您正在调用静态 FXMLLoader.load(URL)方法。由于它是一个静态方法,因此不会在您创建的FXMLLoader实例上调用,因此之前对setController(...)的调用实际上会被忽略。您需要设置FXMLLoader实例的位置,然后调用no-arg load()方法。所以你应该:

issuesNotes.setOnAction(event ->{
    clearPane();
    URL paneOneUrl = getClass().getClassLoader().getResource("gui/mainWindow/issues/NotesScreen.fxml");
    FXMLLoader loader = new FXMLLoader();
    NotesScreenController nsc = new NotesScreenController();
    nsc.setMainController(this);
    loader.setController(nsc);
    loader.setLocation(paneOneUrl);
    try {
        // note call to no-arg load() method:
        paneNotes = loader.load();
        changablePane.getChildren().add(paneNotes);
    } catch (IOException e) {
        e.printStackTrace();
    }
});

最后,由于您是从Java代码设置控制器,因此需要从fx:controller根元素中删除NotesScreen.fxml属性:

<StackPane fx:id="mainContainer" prefHeight="575.0" prefWidth="950.0" stylesheets="@../../../styles/MainWindow/StackPaneChangable.css" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">

    <!-- ... -->

</StackPane>