2017-09-29 8 views
0

Je sais qu'il y a beaucoup de questions déjà posées pour cela, mais je ne peux pas comprendre. Il est un doublon possible:Je dois accéder et effacer un volet d'une autre classe de contrôleur (javafx et SceneBuilder)

accessing a Pane from another class in javafx

JavaFX change Pane color from a different class

Dans mon application, je veux effacer le changablePane (StackPane) dans le MainWindowController d'un mouseEvent dans la NotesScreenController sorte que seule la marque que des notes faites sera affiché.

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> 
+0

Faire la MainWindowController une classe singleton et créez une méthode publique dans la classe MainWindowController qui efface le volet. Puis appelez cette méthode à partir de la classe NotesScreenController en récupérant l'instance singleton à partir de MainWindowController Class. –

+0

Quoi que vous fassiez, ne faites pas ** ** du contrôleur un singleton. Si vous chargez plusieurs copies du fichier FXML, les champs du contrôleur se réfèrent à la mauvaise chose (si vous chargez plusieurs copies du FXML, vous avez besoin de plusieurs instances du contrôleur). –

+1

Votre problème (un problème: je n'ai pas encore lu tout le code) est dans la façon dont vous chargez le fichier FXML: 'paneNotes = loader.load (paneOneUrl)' appelle le ** static ** ['FXMLLoader.load (URL) '] (https://docs.oracle.com/javase/9/docs/api/javafx/fxml/FXMLLoader.html#load-java.net.URL-). Comme c'est une méthode statique, elle n'est pas invoquée sur l'instance 'FXMLLoader' que vous avez créée, et donc l'appel précédent' setController (...) 'est ignoré. Vous avez besoin de 'loader.setLocation (paneOneUrl);' et ensuite 'paneNotes = loader.load();'. Vous devez également supprimer 'fx: controller =" ... "' de 'NotesScreen.fxml'. –

Répondre

0

Fondamentalement, tout ce qui vous manque est le réglage de la commande de l'écran principal dans l'instance NotesScreenController:

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

nsc.setMainController(this); 

Et puis de la NotesScreenController vous pouvez effacer le volet simplement en appelant

mainController.clearPane(); 

que vous pouvez faire:

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

Notez que vous avez un bug subtil: lorsque vous appelez

paneNotes = loader.load(paneOneUrl); 

vous appelez la méthode statiqueFXMLLoader.load(URL). Comme il s'agit d'une méthode statique, elle n'est pas appelée sur l'instance FXMLLoader que vous avez créée. Par conséquent, l'appel précédent à setController(...) est ignoré. Vous devez définir l'emplacement de l'instance FXMLLoader, puis appeler la méthode no-arg load(). Donc, vous devriez avoir:

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

Enfin, puisque vous configurez le contrôleur à partir du code Java, vous devez supprimer l'attribut fx:controller de l'élément racine 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> 
+0

Salut James_D, merci pour la réponse. A propos de la première partie - Je ne peux pas appeler nsc.setMainController car la méthode a un MainScreenController dans le parametar. J'ai également essayé de corriger le bug, mais après avoir édité le code comme vous avez suggéré le NotesScreenCotroller n'est jamais initialisé, l'écran montre seulement les éléments du fichier fxml – ejfilip

+0

si vous pensez que je devrais avoir une approche différente dans la structuration de mon application afin de vas-y, s'il te plait fais le moi savoir. J'apprécierai vraiment cela. – ejfilip