我有一个javaFX的问题。我正在做计算器,我将我的应用程序划分为3个FXML文件(1是仅控制数字和操作符的控制器,2是文本字段的控制器,它是结果字段,并且最后一个应该让他们彼此沟通。)
我无法管理如何编写自己的方法,例如将数字" 3"当我在textfield中按3号时 - 在其他FXML中并且有自己的fxml文件。有一个nullpointer异常所以我想我没有初始化这个textfield。请帮我解决这个问题。有什么方法可以编写我自己的方法(在这个例子中我在MainController类中编写了showDigit()) - 这个方法应该在按下按钮后将Text设置为textfield - 例如按钮2将放置" 2"在textfield。
我已经粘贴了我的代码。
package pl.calculator.controller;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class MainPaneController implements Initializable {
@FXML
private TextPaneController textPaneController;
@FXML
private CalculatorPaneController calculatorPaneController;
@Override
public void initialize(URL location, ResourceBundle resources) {
/*calculatorPaneController.getButtonZero().setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
textPaneController.getTextFieldExpression().setText("example");
}
});*/ --- < THIS WORKS
}
}
FXML for MainController
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="pl.calculator.controller.MainPaneController">
<children>
<fx:include fx:id="textPane" source="TextPane.fxml" />
<fx:include fx:id="calculatorPane" source="CalculatorPane.fxml" />
</children>
</VBox>
号码和操作控制器:
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
public class CalculatorPaneController implements Initializable {
@FXML
private Button buttonFour;
@FXML
private Button buttonSix;
@FXML
private Button buttonDivide;
@FXML
private Button buttonOne;
@FXML
private Button buttonCloseBracket;
@FXML
private Button buttonDot;
@FXML
private Button buttonClear;
@FXML
private Button buttonTwo;
@FXML
private Button buttonSeven;
@FXML
private Button buttonOpenBracket;
@FXML
private Button buttonThree;
@FXML
private Button buttonMultiply;
@FXML
private Button buttonSubtract;
@FXML
private Button buttonEight;
@FXML
private Button buttonEqual;
@FXML
private Button buttonNine;
@FXML
private Button buttonZero;
@FXML
private Button buttonMemory;
@FXML
private Button buttonFive;
@FXML
private GridPane gridPane;
@FXML
private Button buttonAdd;
@FXML
private TextPaneController textPaneController;
@FXML
private CalculatorPaneController calculatorPaneController;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
@FXML
private void showDigit(ActionEvent event) {
textPaneController.getTextFieldExpression().setText("s");
} <---------THIS ONE DOESNT WORK
public Button getButtonFour() {
return buttonFour;
}
public void setButtonFour(Button buttonFour) {
this.buttonFour = buttonFour;
}
public Button getButtonSix() {
return buttonSix;
}
public void setButtonSix(Button buttonSix) {
this.buttonSix = buttonSix;
}
public Button getButtonDivide() {
return buttonDivide;
}
public void setButtonDivide(Button buttonDivide) {
this.buttonDivide = buttonDivide;
}
public Button getButtonOne() {
return buttonOne;
}
public void setButtonOne(Button buttonOne) {
this.buttonOne = buttonOne;
}
public Button getButtonCloseBracket() {
return buttonCloseBracket;
}
public void setButtonCloseBracket(Button buttonCloseBracket) {
this.buttonCloseBracket = buttonCloseBracket;
}
public Button getButtonDot() {
return buttonDot;
}
public void setButtonDot(Button buttonDot) {
this.buttonDot = buttonDot;
}
public Button getButtonClear() {
return buttonClear;
}
public void setButtonClear(Button buttonClear) {
this.buttonClear = buttonClear;
}
public Button getButtonTwo() {
return buttonTwo;
}
public void setButtonTwo(Button buttonTwo) {
this.buttonTwo = buttonTwo;
}
public Button getButtonSeven() {
return buttonSeven;
}
public void setButtonSeven(Button buttonSeven) {
this.buttonSeven = buttonSeven;
}
public Button getButtonOpenBracket() {
return buttonOpenBracket;
}
public void setButtonOpenBracket(Button buttonOpenBracket) {
this.buttonOpenBracket = buttonOpenBracket;
}
public Button getButtonThree() {
return buttonThree;
}
public void setButtonThree(Button buttonThree) {
this.buttonThree = buttonThree;
}
public Button getButtonMultiply() {
return buttonMultiply;
}
public void setButtonMultiply(Button buttonMultiply) {
this.buttonMultiply = buttonMultiply;
}
public Button getButtonSubtract() {
return buttonSubtract;
}
public void setButtonSubtract(Button buttonSubtract) {
this.buttonSubtract = buttonSubtract;
}
public Button getButtonEight() {
return buttonEight;
}
public void setButtonEight(Button buttonEight) {
this.buttonEight = buttonEight;
}
public Button getButtonEqual() {
return buttonEqual;
}
public void setButtonEqual(Button buttonEqual) {
this.buttonEqual = buttonEqual;
}
public Button getButtonNine() {
return buttonNine;
}
public void setButtonNine(Button buttonNine) {
this.buttonNine = buttonNine;
}
public Button getButtonZero() {
return buttonZero;
}
public void setButtonZero(Button buttonZero) {
this.buttonZero = buttonZero;
}
public Button getButtonMemory() {
return buttonMemory;
}
public void setButtonMemory(Button buttonMemory) {
this.buttonMemory = buttonMemory;
}
public Button getButtonFive() {
return buttonFive;
}
public void setButtonFive(Button buttonFive) {
this.buttonFive = buttonFive;
}
public GridPane getGridPane() {
return gridPane;
}
public void setGridPane(GridPane gridPane) {
this.gridPane = gridPane;
}
public Button getButtonAdd() {
return buttonAdd;
}
public void setButtonAdd(Button buttonAdd) {
this.buttonAdd = buttonAdd;
}
}
FXML用于操作和数字控制器:
<?import java.lang.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="gridPane" prefHeight="308.0" prefWidth="375.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="pl.calculator.controller.CalculatorPaneController">
<children>
<Button fx:id="buttonOne" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" onAction="#showDigit" text="1" />
<Button fx:id="buttonFour" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="4" GridPane.rowIndex="1" />
<Button fx:id="buttonTwo" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="2" GridPane.columnIndex="1" />
<Button fx:id="buttonSeven" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="7" GridPane.rowIndex="2" />
<Button fx:id="buttonFive" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="5" GridPane.columnIndex="1" GridPane.rowIndex="1" />
<Button fx:id="buttonEight" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="8" GridPane.columnIndex="1" GridPane.rowIndex="2" />
<Button fx:id="buttonThree" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="3" GridPane.columnIndex="2" />
<Button fx:id="buttonSix" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="6" GridPane.columnIndex="2" GridPane.rowIndex="1" />
<Button fx:id="buttonNine" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="9" GridPane.columnIndex="2" GridPane.rowIndex="2" />
<Button fx:id="buttonZero" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="0" GridPane.rowIndex="3" />
<Button fx:id="buttonDot" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="." GridPane.columnIndex="1" GridPane.rowIndex="3" />
<Button fx:id="buttonEqual" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="=" GridPane.columnIndex="2" GridPane.rowIndex="3" />
<Button fx:id="buttonDivide" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="/" GridPane.columnIndex="3" GridPane.rowIndex="2" />
<Button fx:id="buttonMultiply" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="*" GridPane.columnIndex="3" GridPane.rowIndex="3" />
<Button fx:id="buttonSubtract" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="-" GridPane.columnIndex="3" GridPane.rowIndex="1" />
<Button fx:id="buttonAdd" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="+" GridPane.columnIndex="3" />
<Button fx:id="buttonCloseBracket" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text=")" GridPane.columnIndex="4" GridPane.rowIndex="3" />
<Button fx:id="buttonOpenBracket" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="(" GridPane.columnIndex="4" GridPane.rowIndex="2" />
<Button fx:id="buttonMemory" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="M" GridPane.columnIndex="4" />
<Button fx:id="buttonClear" minHeight="40.0" minWidth="40.0" mnemonicParsing="false" text="C" GridPane.columnIndex="4" GridPane.rowIndex="1" />
</children>
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
</GridPane>
文本字段控制器(结果)
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class TextPaneController {
@FXML
private Label labelExpression;
@FXML
private TextField textFieldOnp;
@FXML
private Label labelOnp;
@FXML
private TextField textFieldExpression;
public Label getLabelExpression() {
return labelExpression;
}
public void setLableExpression(Label lableExpression) {
this.labelExpression = lableExpression;
}
public TextField getTextFieldOnp() {
return textFieldOnp;
}
public void setTextFieldOnp(TextField textFieldOnp) {
this.textFieldOnp = textFieldOnp;
}
public Label getLabelOnp() {
return labelOnp;
}
public void setLabelOnp(Label labelOnp) {
this.labelOnp = labelOnp;
}
public TextField getTextFieldExpression() {
return textFieldExpression;
}
public void setTextFieldExpression(TextField textFieldExpression) {
this.textFieldExpression = textFieldExpression;
}
}
TEXT的FXML文件:
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="89.0" prefWidth="349.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="pl.calculator.controller.TextPaneController">
<children>
<Label fx:id="lableExpression" layoutX="21.0" layoutY="14.0" text="Wprowadź wyrażenie:" />
<Label fx:id="labelOnp" layoutX="213.0" layoutY="14.0" text="Wyrażenie ONP" />
<TextField fx:id="textFieldExpression" layoutX="5.0" layoutY="45.0" />
<TextField fx:id="textFieldOnp" editable="false" layoutX="180.0" layoutY="45.0" />
</children>
</AnchorPane>
和堆栈跟踪:
TextField[id=textFieldExpression, styleClass=text-input text-field]
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Node.fireEvent(Unknown Source)
at javafx.scene.control.Button.fire(Unknown Source)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
at javafx.event.Event.fireEvent(Unknown Source)
at javafx.scene.Scene$MouseHandler.process(Unknown Source)
at javafx.scene.Scene$MouseHandler.access$1800(Unknown Source)
at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
at com.sun.glass.ui.View.notifyMouse(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(Unknown Source)
at com.sun.glass.ui.win.WinApplication$4$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.Trampoline.invoke(Unknown Source)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
... 48 more
Caused by: java.lang.NullPointerException
at pl.calculator.controller.CalculatorPaneController.showDigit(CalculatorPaneController.java:89)
... 57 more
答案 0 :(得分:0)
FXML文件CalculatorPane.fxml没有<fx:include fx:id="textPane" ... />
,因此关联的控制器没有注入textPaneController
。因此,textPaneController
中的CalculatorPaneController
为null
,您获得了NullPointerException
。
从CalculatorPaneController
更新值的方法是为两个控制器提供共享数据模型,并更新模型。所以你可以做类似
public class DataModel {
private final StringProperty text = new SimpleStringProperty();
public StringProperty textProperty() {
return text ;
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
// other properties as needed...
}
然后你可以做控制器
public class TextPaneController {
private DataModel model ;
@FXML
private TextField textFieldExpression ;
// etc ...
public void setModel(DataModel model) {
this.model = model ;
textFieldExpression.textProperty().bindBidirectional(model.textProperty());
}
}
和
public class CalculatorPaneController {
private DataModel model ;
public void setModel(DataModel model) {
this.model = model ;
}
// ...
@FXML
private void showDigit(ActionEvent event) {
model.setText("s");
}
}
最后,在主控制器的初始化方法中将所有内容绑定在一起:
public class MainPaneController implements Initializable {
@FXML
private TextPaneController textPaneController;
@FXML
private CalculatorPaneController calculatorPaneController;
@Override
public void initialize(URL location, ResourceBundle resources) {
DataModel model = new DataModel();
textPaneController.setModel(model);
calculatorPaneController.setModel(model);
}
}
您真的不需要(并且不应该)控制器中控件的所有get / set方法。这些应该保密,不要暴露在控制器外面。