javaFX控制器之间没有相互通信

时间:2015-07-18 06:56:47

标签: javafx

我有一个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

1 个答案:

答案 0 :(得分:0)

FXML文件CalculatorPane.fxml没有<fx:include fx:id="textPane" ... />,因此关联的控制器没有注入textPaneController。因此,textPaneController中的CalculatorPaneControllernull,您获得了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方法。这些应该保密,不要暴露在控制器外面。