У меня есть приложение JavaFX, которое я делаю. У меня возникают трудности при передаче экземпляра списка со списком на другой экран. Моя переменная ComboBox называется reportBox. Он определен в home.fxml и вставлен в MyController.java. Когда я пытаюсь переключать экраны в MyController, я создаю объект ReportScene (класс, который я создал) и передаю ComboBox в конструктор сцены отчета. Report Scene также загружает report.fxml.
Во время игры с кодом, чтобы сделать эту работу, я либо получу ошибку при попытке установить элементы reportScenebox, либо я не получу ошибку, но Combobox будет пуст (так что, похоже, он не получает передал ссылку). В конечном счете, мне не нужно было бы напрямую устанавливать поле элементов отчетов, если я говорю, что reportSceneBox = MyController.SceneBox. Ошибка, которую я иногда получаю в зависимости от итерации кода: ReportScene.reportBox = MyController.ReportBox, я получаю «Исключение в потоке» Поток приложения JavaFX »java.lang.NullPointerException».
Я не понимаю, почему происходит эта ошибка или почему reportSceneBox неправильно заполняется / копируется из Mycontroller.reportbox. Может кто-нибудь помочь объяснить или помочь с решением этой проблемы? Спасибо.
MyController.java
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseEvent;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
public class MyController {
private final static String[] REPORT_TYPES = {"Sales Report", "Inventory Report", "Guacamole Metrics"};
@FXML
private ComboBox<String> reportBox;
private ObservableList<String> items = FXCollections.observableArrayList(REPORT_TYPES);
public static final String[] getReportTypes()
{
return REPORT_TYPES;
}
/**
* Initializes the controller class. This method is automatically called
* after the fxml file has been loaded.
*/
@FXML
public void initialize()
{
//initialized drop down of report types
reportBox.setItems(items);
//Handles reportBox event
reportBox.setOnAction((ActionEvent event) -> {
String inputReport = reportBox.getValue();
int reportIndex = indexOf(inputReport); //is do while loop here useful for input validation. it might not be, but something to consider.
if( reportIndex > -1)
{
System.out.println(reportIndex);
ReportScene rs = new ReportScene(reportIndex, this.reportBox);
//MATCH FOUND, create report scene;
}
else
{
// NO MATCH FOUND. NEED NEW INPUT.
}
// if input is valid, create new Report Scene of given REPORT_TYPE
System.out.println(reportBox.getValue());
});
}
private int indexOf(String reportType)
{
int index = -1;
for(int i = 0; i < REPORT_TYPES.length; i++)
{
if(reportType.equalsIgnoreCase(REPORT_TYPES[i]))
{
index = i;
i = REPORT_TYPES.length + 2;
}
}
return index;
}
Home.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuButton?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.collections.FXCollections?>
<?import java.lang.String?>
<VBox prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MyController">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="New" />
<MenuItem mnemonicParsing="false" text="Open…" />
<Menu mnemonicParsing="false" text="Open Recent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Close" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Save As…" />
<MenuItem mnemonicParsing="false" text="Revert" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Preferences…" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Quit" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Undo" />
<MenuItem mnemonicParsing="false" text="Redo" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Cut" />
<MenuItem mnemonicParsing="false" text="Copy" />
<MenuItem mnemonicParsing="false" text="Paste" />
<MenuItem mnemonicParsing="false" text="Delete" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Select All" />
<MenuItem mnemonicParsing="false" text="Unselect All" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About Report Generator" />
</items>
</Menu>
</menus>
</MenuBar>
<AnchorPane maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS" id="pane">
<children>
<Label alignment="CENTER" layoutX="271.0" layoutY="26.0" style=" " text="" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false">
<font>
<Font size="18.0" />
</font>
</Label>
<!-- <DatePicker layoutX="390.0" layoutY="44.0" />
<DatePicker layoutX="189.0" layoutY="44.0" />
<MenuButton layoutX="43.0" layoutY="44.0" mnemonicParsing="false" text="MenuButton">
<items>
<MenuItem mnemonicParsing="false" text="Sales Report 1" onAction="#processReport1" fx:id="menuItem1"/>
<MenuItem mnemonicParsing="false" text="Inventory Report 1" />
<MenuItem mnemonicParsing="false" text="InOut Report 1" />
</items>
</MenuButton> -->
<Button layoutX="43.0" layoutY="317.0" mnemonicParsing="false" text="Run" />
<ComboBox layoutX="43.0" layoutY="44.0" prefWidth="150.0" promptText="Select a Report" fx:id="reportBox" editable="True" >
<items>
<FXCollections fx:factory="observableArrayList">
</FXCollections>
</items>
</ComboBox>
</children>
</AnchorPane>
</children>
</VBox>
ReportScene.java
import java.util.Arrays;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class ReportScene {
private int reportIndex;
private final String[] reportTypes = MyController.getReportTypes();
private Scene reportScene;
@FXML
private ComboBox<String> reportSceneBox;
private Button homeBtn;
private final double[] reportWidths = new double[reportTypes.length];
private final double[] reportHeights = new double[reportTypes.length];
public ReportScene()
{
System.out.println("Default constructor for report scene");
}
public ReportScene(int reportIndex, ComboBox<String> reportBox)
{
//reportTypes = MyController.REPORT_TYPES;//getReportTypes();
//destroy old scene and generate new one
//destroy old scene here
this.reportIndex = reportIndex;
this.reportSceneBox = reportBox;
//ObservableList<String> items = FXCollections.observableArrayList(MyController.getReportTypes());
//this.reportSceneBox.setItems(items);
//this.reportBox.setVisible(true);
//this.homeBtn = new Button
Arrays.fill(reportWidths, Main.getHomeWidth());
Arrays.fill(reportHeights, Main.getHomeHeight());
this.generateScene();
}
//@FXML
public void generateScene()
{
try
{
Parent newRoot = FXMLLoader.load(getClass().getClassLoader().getResource("Reports/" + reportTypes[this.reportIndex] + ".fxml"));
//newRoot.getChildrenUnmodifiable().add(this.reportBox);
//newRoot.getParent().get
Stage stageInstance = Main.getPrimaryStage();
// @SuppressWarnings("unchecked")
// ComboBox<String> ap = (ComboBox<String>) newRoot;
// ap.getChildren().add(this.reportBox);
// ap.setLayoutY(-580.0);
// this.reportBox.setVisible(true);
this.reportScene = new Scene(newRoot,reportWidths[this.reportIndex],reportHeights[this.reportIndex]);
//this.reportScene.
reportScene.getStylesheets().addAll(this.getClass().getResource("application.css").toExternalForm());
stageInstance.setScene(this.reportScene);
stageInstance.show();
}
catch (Exception e)
{
e.printStackTrace();
}
report.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.control.MenuItem?>
<?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.collections.FXCollections?>
<?import java.lang.String?>
<VBox prefHeight="600.0" prefWidth="1000.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.ReportScene">
<children>
<MenuBar VBox.vgrow="NEVER">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="New" />
<MenuItem mnemonicParsing="false" text="Open…" />
<Menu mnemonicParsing="false" text="Open Recent" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Close" />
<MenuItem mnemonicParsing="false" text="Save" />
<MenuItem mnemonicParsing="false" text="Save As…" />
<MenuItem mnemonicParsing="false" text="Revert" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Preferences…" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Quit" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Edit">
<items>
<MenuItem mnemonicParsing="false" text="Undo" />
<MenuItem mnemonicParsing="false" text="Redo" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Cut" />
<MenuItem mnemonicParsing="false" text="Copy" />
<MenuItem mnemonicParsing="false" text="Paste" />
<MenuItem mnemonicParsing="false" text="Delete" />
<SeparatorMenuItem mnemonicParsing="false" />
<MenuItem mnemonicParsing="false" text="Select All" />
<MenuItem mnemonicParsing="false" text="Unselect All" />
</items>
</Menu>
<Menu mnemonicParsing="false" text="Help">
<items>
<MenuItem mnemonicParsing="false" text="About MyHelloApp" />
</items>
</Menu>
</menus>
</MenuBar>
<AnchorPane id="pane" maxHeight="-1.0" maxWidth="-1.0" prefHeight="-1.0" prefWidth="-1.0" VBox.vgrow="ALWAYS">
<children>
<Label alignment="CENTER" layoutX="384.0" layoutY="28.0" style=" " text="Sales Report" textAlignment="CENTER" textFill="#9f9f9f" wrapText="false">
<font>
<Font size="18.0" />
</font>
</Label>
<DatePicker layoutX="229.0" layoutY="91.0" />
<DatePicker layoutX="464.0" layoutY="91.0" />
<Label layoutX="229.0" layoutY="67.0" text="Start Date" />
<Label layoutX="464.0" layoutY="67.0" text="End Date" />
<Button fx:id="Run" layoutX="49.0" layoutY="496.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="49.0" text="Run" />
<ComboBox layoutX="43.0" layoutY="44.0" prefWidth="150.0" promptText="Select a Report" fx:id="reportSceneBox" editable="True" >
<items>
<FXCollections fx:factory="observableArrayList">
</FXCollections>
</items>
</ComboBox>
<!-- <Button fx:id="Home" layoutX="49.0" layoutY="41.0" mnemonicParsing="false" text="Home" /> -->
</children>
</AnchorPane>
</children>
</VBox>