我有一个正在制作的JavaFX应用程序。我很难将组合框实例从一个屏幕传递到另一个屏幕。我的ComboBox变量称为reportBox。它在home.fxml中定义,并注入MyController.java中。当我尝试在MyController中切换屏幕时,我正在创建一个ReportScene对象(我制作的类),并将ComboBox传递给Report Scene的构造函数。报告场景也正在加载report.fxml。
在玩代码使之工作时,尝试设置reportScenebox的项目时我会得到一个错误,或者我不会收到任何错误,但Combobox将为空(因此似乎没有得到通过参考)。最终,如果我说reportSceneBox = MyController.SceneBox,则不必直接设置reportsene框的项目。我有时会根据代码的迭代而获得的错误是:ReportScene.reportBox = MyController.ReportBox,我得到“线程“ JavaFX Application Thread”中的异常“ java.lang.NullPointerException”。
我不明白为什么会发生此错误,或者为什么不能从Mycontroller.reportbox中正确填充/复制reportSceneBox。有人可以帮助您解释或帮助解决此问题吗?谢谢。
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>
答案 0 :(得分:0)
当您在newRoot
方法中创建generateScene()
时,传递给构造函数的组合框被“覆盖”。创建newRoot
,然后将其用作要显示的新场景的视图,这就是组合框为空的原因。