当前位置: 首页 > 知识库问答 >
问题:

JavaFX控制器不相互通信

呼延景同
2023-03-14

我对javaFX有问题。我正在做计算器,我将我的应用程序划分为3个FXML文件(1是只控制数字和运算符的控制器,2是文本字段的控制器,这是结果字段,最后一个应该让它们相互通信)。

我无法管理如何编写自己的方法,例如,当我在文本字段中按数字3时,在其他FXML中输入数字“3”,并且有自己的FXML文件。有一个空指针异常,所以我想我没有初始化这个文本字段。请帮我解决这个问题。有没有办法在MainController类中编写我自己的方法(在本例中,我编写了showDigit())——这个方法应该在按下按钮后将文本设置为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

<?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;
}
}

文本的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

共有1个答案

柯英奕
2023-03-14

FXML文件计算器Pane.fxml没有

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方法。这些应该是私有的,不要暴露在控制器之外。

 类似资料:
  • 我真的很难理解JavaFX控制器,我的目标是写一个TextArea来充当日志。 我的代码在下面,但我希望能够改变值等从另一个类,我可以调用时需要。我试图创建一个扩展初始化的控制器类,但我无法使它工作。有谁能指引我正确的方向吗?

  • 我正在学习使用SceneBuilder创建一个新的JavaFX应用程序的教程,并尝试向.fxml文件添加一个controller类。 我正在使用Eclipse和Gluon的Scene Builder V8.1.1版本。 在哪里可以将我的.fxml文件连接到我的控制器Java类?

  • 问题内容: 我对Controllers and Views(fxml)进行了结构化,以尽可能地分隔我的代码,我想知道如何在2个控制器之间进行通信。我的意思是,一个控制器必须调用另一个控制器的某些功能才能将其设置为最新状态。 我认为我当前结构的模式将更加明确: 控制器1 / \ fx:include fx:include / \ Controller2 Controller3 每个控制器都有自己的f

  • 我做了一个控制器和视图(fxml)的结构来尽可能地分离我的代码,我想知道如何在两个控制器之间进行通信。我的意思是,一个控制器必须调用另一个控制器的一些函数来设置它是最新的。 我认为我当前结构的一个图式会更明确: 精确度: 我在此基础上开发了我的应用程序:http://www.zenjava.com/2011/10/25/views-intern-views-controllers-intern-c

  • 问题内容: 我试图在JavaFX中获得TableView来动态显示内容。 当我运行程序时,出现此错误: 我的控制器名为“ UserInterfaceController.java”,它与FXML文件位于同一软件包下,我也已将该软件包导入了FXML中。为什么找不到控制器? FXML文件: 控制器: 主类: 问题答案: 使用FXML的全限定名来引用您的控制器: 后续问题的答案 对以下问题的回答解释了为

  • 我试图在JavaFX中获得一个TableView来动态显示内容。 当我运行程序时,出现以下错误: 我的控制器名为“UserInterfaceController.java”,它与FXML文件在同一个包下,我也在FXML中导入了包。为什么找不到控制器? FXML文件: 控制器: 主要类: