我试图为学校创建一个简单的javafx项目,让用户玩nim游戏。在我看来,这个概念很简单,因为我以前已经使用过java和javafx。当我试图通过传入一个可观察列表来设置tableview中的项时,出现了错误。我确信列表中包含我应该能够添加的对象。我不知道怎么了。
以下是我的全部代码:
主控制器类:
package controllers;
import format.FormatStringValueForTableView;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import java.io.IOException;
import java.util.Random;
public class MainController {
@FXML private TextField inputTextField;
private final FormatStringValueForTableView formatter = new FormatStringValueForTableView();
@FXML
private void continueToGame(ActionEvent event) throws IOException {
FXMLLoader parent = new FXMLLoader(getClass().getClassLoader().getResource("ui/nim_game.fxml"));
Parent root = parent.load();
NimGameController nimGameController = parent.getController();
nimGameController.setList(formatter.formatString(inputTextField.getText()));
Scene scene = new Scene(root);
Stage appStage = (Stage) ((Node) event.getSource()).getScene().getWindow();
appStage.setScene(scene);
appStage.show();
}
@FXML
private void generateRandomNumber(ActionEvent event){
Random random = new Random();
int generatedNumber = random.nextInt(999) + 22;
inputTextField.setText(Integer.toString(generatedNumber));
}
}
nimgamecontroller类:
package controllers;
import entities.Node;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
public class NimGameController implements Initializable {
private ObservableList<Node> textInTextFieldToList;
@FXML private TableView<Node> tableView;
public void setList(ObservableList<Node> textInTextFieldToList) {
this.textInTextFieldToList = textInTextFieldToList;
}
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
configureTable();
populateTable();
}
@FXML
private void showNumsForDebug(ActionEvent event) {
textInTextFieldToList.forEach(System.out::println);
}
@FXML
private void back(ActionEvent event) throws IOException {
Parent parent = FXMLLoader.load(getClass().getClassLoader().getResource("ui/main.fxml"));
Scene scene = new Scene(parent);
Stage appStage = (Stage) ((javafx.scene.Node) event.getSource()).getScene().getWindow();
appStage.setScene(scene);
appStage.show();
}
private void configureTable() {
TableColumn<Node, Integer> itemColumn = new TableColumn<>("Item");
itemColumn.prefWidthProperty().bind(tableView.widthProperty().multiply(0.3));
itemColumn.setCellValueFactory(new PropertyValueFactory<>("value"));
itemColumn.setResizable(false);
TableColumn<Node, Integer> levelColumn = new TableColumn<>("Level");
levelColumn.prefWidthProperty().bind(tableView.widthProperty().multiply(0.3));
levelColumn.setCellValueFactory(new PropertyValueFactory<>("level"));
levelColumn.setResizable(false);
TableColumn<Node, Integer> functionValColumn = new TableColumn<>("Func. Val.");
functionValColumn.prefWidthProperty().bind(tableView.widthProperty().multiply(0.4));
functionValColumn.setCellValueFactory(new PropertyValueFactory<>("functionValue"));
functionValColumn.setResizable(false);
tableView.getColumns().add(itemColumn);
tableView.getColumns().add(levelColumn);
tableView.getColumns().add(functionValColumn);
}
public void populateTable(){
if(!textInTextFieldToList.isEmpty()){
tableView.setItems(textInTextFieldToList);
} else {
System.out.println("List is empty");
}
}
}
formatstringvaluefortableview类:
package format;
import entities.Node;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class FormatStringValueForTableView {
public ObservableList<Node> formatString(String numberString) {
ObservableList<Node> list = FXCollections.observableArrayList();
for(int i = 0; i < numberString.length(); i++) {
if(Character.isDigit(numberString.charAt(i)))
list.add(new Node(getIntValueFromChar(numberString.charAt(i))));
}
return list;
}
public Integer getIntValueFromChar(char c) {
return Integer.parseInt(String.valueOf(c));
}
}
节点类:
package entities;
public class Node {
private Integer value;
private Integer level;
private Integer functionValue;
public Node(Integer value) {
this.value = value;
this.level = 0;
this.functionValue = 0;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
public Integer getLevel() {
return level;
}
public void setLevel(Integer level) {
this.level = level;
}
public Integer getFunctionValue() {
return functionValue;
}
public void setFunctionValue(Integer functionValue) {
this.functionValue = functionValue;
}
@Override
public String toString() {
return "Node{" +
"value=" + value +
", level=" + level +
", functionValue=" + functionValue +
'}';
}
}
main.fxml文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<GridPane alignment="center" hgap="10" maxHeight="300.0" maxWidth="500.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="431.0" vgap="10" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.MainController">
<children>
<AnchorPane maxHeight="300.0" maxWidth="500.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="400.0">
<children>
<SplitPane dividerPositions="0.17676767676767677" orientation="VERTICAL" prefHeight="200.0" prefWidth="400.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<Label alignment="CENTER" layoutX="80.0" layoutY="-2.0" prefHeight="40.0" prefWidth="238.0" text="Welcome to NIM game." underline="true">
<font>
<Font name="System Bold" size="18.0" />
</font>
</Label>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="341.0">
<children>
<Label layoutX="49.0" layoutY="14.0" prefHeight="30.0" prefWidth="300.0" text="Enter a string of numbers that will be split: ">
<font>
<Font size="15.0" />
</font></Label>
<TextField fx:id="inputTextField" layoutX="49.0" layoutY="54.0" prefHeight="25.0" prefWidth="300.0" />
<Button layoutX="47.0" layoutY="104.0" mnemonicParsing="false" onAction="#continueToGame" prefHeight="32.0" prefWidth="102.0" text="Continue" />
<Button layoutX="247.0" layoutY="104.0" mnemonicParsing="false" onAction="#generateRandomNumber" prefHeight="32.0" prefWidth="102.0" text="Random" />
</children></AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</children>
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
</GridPane>
nim\u game.fxml文件:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane prefHeight="400" prefWidth="900" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controllers.NimGameController">
<children>
<TableView fx:id="tableView" layoutX="681.0" layoutY="14.0" prefHeight="282.0" prefWidth="205.0">
<columns>
</columns>
</TableView>
<Button layoutX="787.0" layoutY="353.0" mnemonicParsing="false" onAction="#back" prefHeight="32.0" prefWidth="99.0" text="Back" />
<Button layoutX="787.0" layoutY="305.0" mnemonicParsing="false" onAction="#showNumsForDebug" prefHeight="32.0" prefWidth="99.0" text="Show" />
</children>
</AnchorPane>
以下是堆栈跟踪:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1787)
at javafx.fxml/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1670)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Node.fireEvent(Node.java:8879)
at javafx.controls/javafx.scene.control.Button.fire(Button.java:200)
at javafx.controls/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:206)
at javafx.controls/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274)
at javafx.base/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at javafx.base/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at javafx.base/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at javafx.base/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at javafx.base/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at javafx.base/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at javafx.base/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.base/javafx.event.Event.fireEvent(Event.java:198)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3851)
at javafx.graphics/javafx.scene.Scene$MouseHandler.access$1200(Scene.java:3579)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1849)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2588)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:390)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:76)
at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at javafx.base/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:273)
at javafx.fxml/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:83)
at javafx.fxml/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1782)
... 51 more
Caused by: javafx.fxml.LoadException:
/C:/Users/marci/IDEAPROJECTS/NimGameWithMINIMAX/target/classes/ui/nim_game.fxml
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at controllers.MainController.continueToGame(MainController.java:25)
... 62 more
Caused by: java.lang.NullPointerException
at controllers.NimGameController.populateTable(NimGameController.java:73)
at controllers.NimGameController.initialize(NimGameController.java:34)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2573)
... 65 more
1条答案
按热度按时间0ve6wy6x1#
initialize()
,因此populateTable()
,在调用FXMLLoader.load()
在你打电话之前setList(...)
.因此当
populateTable()
被调用,textInTextFieldToList
仍然为空并且textInTextFieldToList.isEmpty()
抛出NullPointerException
.只需将呼叫移动到
populateTable
至setList()
. 这是有意义的,因为在设置列表之前不能填充表,如果要调用setList()
另一次,你可能想重新填充表。