2015-07-20 3 views
0

Я новичок в javafX, прошел множество различных учебных пособий и широко разобрал по всему миру. Я пытаюсь написать многоэкранную программу javaFX, у которой на втором экране есть разделенная панель, в правой панели которой должна отображаться сетка и кнопка. Рамка, которую я использую для нескольких экранов, скопирована в виде учебника по MultipleScreens Framework от Angela Caiedo (https://github.com/acaicedo/JFX-MultiScreen/tree/master/ScreensFramework).javaFX не может получить доступ к элементам сцены

Что работает: Рамки экранов успешны с точки зрения переключения между моими экранами.

Моя проблема: я нажимаю кнопку на экране 1 для перехода к экрану 2. Экран 2 успешно отображается. На экране 2 я нажимаю кнопку, чтобы заполнить данные в моем vBox. Код в моем классе контроллера для экрана 2 не может получить доступ к vbox (или любым другим определенным контейнерам на этом экране).

Мой главный класс устанавливает экраны контроллеров.

public class FieldMapCreator extends Application { 
    public static String mainID = "main"; 
    public static String mainFile = "MainMapFXMLDocument.fxml"; 
    public static String initialMapID = "initialMap"; 
    public static String initialMapFile = "FXMLMapPicture.fxml"; 
    @Override 
    public void start(Stage stage) throws Exception { 

    ScreensController mainContainer = new ScreensController(); 
    mainContainer.loadScreen(FieldMapCreator.mainID, FieldMapCreator.mainFile); 
    mainContainer.loadScreen(FieldMapCreator.initialMapID, FieldMapCreator.initialMapFile); 

    mainContainer.setScreen(FieldMapCreator.mainID); 
    Group root = new Group(); 
    root.getChildren().addAll(mainContainer); 
    Scene scene = new Scene(root); 

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

я ко второму экрану, нажав кнопку на экране 1. Button1 код выглядит следующим образом:

@FXML 
private void initialMapButtonAction(ActionEvent event) { 
    myController.setScreen(FieldMapCreator.initialMapID); 
} 

Экран 2 имеет кнопку, при нажатии на которую выполняет метод, который создает данные для VBox , FXML для экрана 2 заключается в следующем:

<AnchorPane id="AnchorPane" fx:id="mainAnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FieldMapCreator.FXMLMapPictureController"> 
    <children> 
     <SplitPane fx:id="mapSplitPane" dividerPositions="0.29797979797979796" layoutX="3.0" layoutY="7.0" prefHeight="400.0" prefWidth="600.0"> 
     <items> 
      <AnchorPane fx:id="anchorPaneLeft" minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0"> 
       <children> 
        <Button fx:id="backButton" layoutX="14.0" layoutY="348.0" mnemonicParsing="false" onAction="#goToMainScreen" text="Back" /> 
       </children> 
      </AnchorPane> 
      <AnchorPane fx:id="anchorPaneRight" minHeight="0.0" minWidth="0.0" prefHeight="364.0" prefWidth="401.0"> 
       <children> 
        <Button fx:id="vBoxShowMap" layoutX="24.0" layoutY="346.0" mnemonicParsing="false" onAction="#buildMapFromNurseries" prefHeight="26.0" prefWidth="91.0" text="show map" /> 
        <VBox fx:id="mapVBox" layoutX="24.0" layoutY="24.0" onMouseClicked="#vBoxMouseClicked" prefHeight="200.0" prefWidth="309.0" /> 
       </children></AnchorPane> 
     </items> 
     </SplitPane> 
    </children> 
</AnchorPane> 

код, который не может находится в «showInitialMap()» метод класса контроллера для экрана 2. При выполнении последней строки этого метода «mapVBox.getChildren () .add (root) ", приводит к исключению нулевого указателя. Я ожидал, что это будет разрешено с помощью инъекции fxml. Я также попытался прокомментировать код, чтобы получить «mapVBox», используя поиск сцены, но также приводит к исключению нулевого указателя. Код контроллера находится ниже:

public class FXMLMapPictureController implements Initializable, ControlledScreen { 

    ScreensController myController; 
    static MyNode[][] mainField ; 

    @FXML 
    private AnchorPane mainAnchorPane; 
    @FXML 
    private static SplitPane mapSplitPane; 
    @FXML 
    private AnchorPane anchorPaneLeft; 
    @FXML 
    private static AnchorPane anchorPaneRight; 
    @FXML 
    private static VBox mapVBox; 
    @FXML 
    private Button vBoxShowMap; 
    /** 
    * Initializes the controller class. 
    */ 
    @Override 
    public void initialize(URL url, ResourceBundle rb) { 
    // Should something be in here ?? 
    } 

    public void goToMainScreen() { 
    myController.setScreen(FieldMapCreator.mainID); 
    } 

    public void showInitialMap() { 
    int row = userFieldMap.getNumRows(); 
    int col = userFieldMap.getNumCols(); 

    double gridWidth = 309/col; 
    double gridHeight = 200/row; 
    Group root = new Group(); 
    // initialize the field 
    for (int idx = 0; idx < col; idx++) { 
     for (int jdx = 0; jdx < row; jdx++) { 
      // create plot 
      Plot plot = new Plot(idx, jdx, "Plot" + idx + "/" + jdx); 
      // Create node to hold the Plot 
      MyNode node = new MyNode(idx*gridWidth, jdx*gridHeight, gridWidth, gridHeight, plot); 
      // add plot to group 
      root.getChildren().add(node); 
     } 
    } 
    //Scene myScene = myController.getScene(); 
    //VBox mapVBox = (VBox)myScene.lookup("#mapVBox"); 
    mapVBox.getChildren().add(root); 
    } 

    @Override 
    public void setScreenParent(ScreensController screenParent) { 
    myController = screenParent; 
    } 

Есть что-то не хватает в методе initialize()? Я задаюсь вопросом, не устанавливаю ли я что-то правильно, когда меняю экраны. Я могу без проблем получить доступ к контейнерам начального экрана из всех методов экрана 1, включая класс initialize. Когда я пытаюсь сделать то же самое на экране 2, я получаю сообщение «Экран не загружен !!!»

Спасибо за любую помощь, которую вы можете предоставить.

ответ

0

Вы используете static поля как FXML Цели инъекции, которые не работают на Java 8 и не должны были реализовываться для работы в любой другой версии, поскольку статические элементы пользовательского интерфейса просто не имеют смысла. Вот несколько подробностей answer. В большинстве случаев использование поля static означает, что дизайн программного обеспечения приложения должен быть пересмотрен.

+0

Спасибо! Я не помню, почему я добавил «статические» в поля (неопытный новый пользователь!), Но удаление его решило проблему. Экран не загружался правильно, поэтому я не мог получить доступ к контейнерам. Теперь он загружается. – lynnj

Смежные вопросы