即使用户输入了值,getText方法也返回null?

时间:2014-02-23 09:27:12

标签: java javafx jtextfield gettext

首先,我有这个主要的FXML文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import binpacking.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.collections.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<AnchorPane id="AnchorPane" prefHeight="582.0" prefWidth="556.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="binpacking.FXMLDocumentController">
  <children>
    <Label id="TypeLabel" fx:id="typeLabel" layoutX="186.0" layoutY="77.0" text="Type:" />
    <ComboBox id="TypeOfAlgorithm" fx:id="typeOfAlgorithmCombo" layoutX="239.0" layoutY="77.0">
      <items>
        <FXCollections fx:factory="observableArrayList">
          <String fx:value="First-Fit" />
          <String fx:value="First-Fit Decreasing" />
          <String fx:value="Full-Bin Packing" />
        </FXCollections>
      </items>
    </ComboBox>
    <Label fx:id="numbersLabel" layoutX="242.0" layoutY="148.0" prefWidth="65.0" text="Numbers:" />
    <Group id="Group" layoutX="138.0" layoutY="173.0" scaleX="1.0" scaleY="1.0">
      <children>
        <TextField id="no1" fx:id="no1Field" layoutX="0.0" layoutY="0.0" prefHeight="21.0" prefWidth="34.999900000002526" />
        <TextField id="no2" fx:id="no2Field" layoutX="43.0" layoutY="0.0" prefHeight="21.0" prefWidth="34.999900000002526" />
        <TextField id="no3Field" fx:id="no3Field" layoutX="95.0" layoutY="0.0" prefHeight="21.0" prefWidth="34.9998779296875" />
        <TextField id="no4Field" fx:id="no4Field" layoutX="148.0" layoutY="0.0" prefHeight="21.0" prefWidth="34.9998779296875" />
        <TextField id="no5Field" fx:id="no5Field" layoutX="191.0" layoutY="0.0" prefHeight="21.0" prefWidth="34.9998779296875" />
        <TextField id="no6Field" fx:id="no6Field" layoutX="236.0" layoutY="0.0" prefHeight="21.0" prefWidth="34.9998779296875" />
      </children>
    </Group>
    <Label id="noOfBinsLabel" fx:id="noOfBinsLabel" layoutX="224.0" layoutY="291.0" text="Number of Bins:" />
    <Label id="ofSizeLabel" fx:id="ofSizeLabel" layoutX="228.0" layoutY="360.0" text="of Size:" />
    <TextField id="ofSizeField" fx:id="ofSizeField" layoutX="286.0" layoutY="360.0" prefHeight="21.0" prefWidth="34.9998779296875" />
    <Button fx:id="buildButton" layoutX="171.0" layoutY="507.0" mnemonicParsing="false" onAction="#onBuildClicked" text="Build Window" />
    <Button fx:id="resetButton" layoutX="300.0" layoutY="508.0" mnemonicParsing="false" onAction="#onResetClicked" text="Reset" />
    <Label alignment="CENTER" contentDisplay="CENTER" layoutX="136.0" layoutY="15.0" text="The Bin Packing Program" textOverrun="CENTER_ELLIPSIS">
      <font>
        <Font name="System Bold" size="22.0" />
      </font>
    </Label>
    <MenuBar fx:id="MenuBar" layoutX="0.0" layoutY="0.0" useSystemMenuBar="true">
      <menus>
        <Menu mnemonicParsing="false" text="File">
          <items>
            <MenuItem mnemonicParsing="false" text="Close" />
          </items>
        </Menu>
        <Menu mnemonicParsing="false" text="Edit">
          <items>
            <MenuItem mnemonicParsing="false" text="Delete" />
          </items>
        </Menu>
        <Menu mnemonicParsing="false" text="Help">
          <items>
            <MenuItem mnemonicParsing="false" text="About" />
          </items>
        </Menu>
      </menus>
    </MenuBar>
    <Slider fx:id="noOfBinsSlider" layoutX="203.0" layoutY="325.0" max="6.0" min="1.0" value="6.0" />
  </children>
</AnchorPane>

我有控制器类:

package binpacking;

import java.net.URL;
import java.util.ResourceBundle;
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.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.MenuBar;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

public class FXMLDocumentController implements Initializable {

    // Declaration of strings which hold user data input
    private String typeOfAlgorithmString;
    private String numberOfBins;
    private String binSize;
    private String[] numbers = new String[6];

    @FXML
    private Label typeLabel;
    @FXML
    private ComboBox<?> typeOfAlgorithmCombo;
    @FXML
    private TextField no1Field;
    @FXML
    private TextField no2Field;
    @FXML
    private TextField no3Field;
    @FXML
    private TextField no4Field;
    @FXML
    private TextField no5Field;
    @FXML
    private TextField no6Field;
    @FXML
    private Label noOfBinsLabel;
    @FXML
    private Label ofSizeLabel;
    @FXML
    private TextField ofSizeField;
    @FXML
    private Label numbersLabel;
    @FXML
    private Button buildButton;
    @FXML
    private Button resetButton;
    @FXML
    private MenuBar menuBar;
    @FXML
    private Slider noOfBinsSlider;

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // Menu bar preparation code to be added here
    }   

    public void changeStage(String fxmlName) throws Exception {
        // Load FXML - based on the fxmlName parameter
        Parent root = FXMLLoader.load(getClass().getResource(fxmlName + ".fxml"));

        // Create objects of the stage and scene
        Stage stage = new Stage();
        Scene scene = new Scene(root);

        // Show the new stage/open new window
        stage.setScene(scene);

        // Detect title for the window
        if (fxmlName == "FirstFit")
        {
            stage.setTitle("First-Fit");
        } else if (fxmlName == "FirstFitDecreasing") {
            stage.setTitle("First-Fit Decreasing");
        } else {
            stage.setTitle("Full-Bin Packing");
        }

        stage.show();
    }

    @FXML
    private void onBuildClicked(ActionEvent event) {
        // Get Type Of Algorithm
        typeOfAlgorithmString = (String) typeOfAlgorithmCombo.getValue();

        // Get Numbers Input
        numbers[0] = no1Field.getText();
        numbers[1] = no2Field.getText();
        numbers[2] = no3Field.getText();
        numbers[3] = no4Field.getText();
        numbers[4] = no5Field.getText();
        numbers[5] = no6Field.getText();

        // Get Number Of Bins
        // numberOfBins = String.valueOf(noOfBinsSlider.getValue());

        // Get Bin Size
        binSize = ofSizeField.getText();

        // Create Objects of Each Algorithm's Class
        FirstFit firstFitClass = new FirstFit();
        FirstFitDecreasing firstFitDecreasingClass = new FirstFitDecreasing();
        FullBin fullBinClass = new FullBin();

        // Determine Type Of Algorithm To Run
        switch (typeOfAlgorithmString.toLowerCase()) {
            case "first-fit": 
                firstFitClass.runAlgorithm();
                break;

            case "first-fit decreasing": 
                firstFitDecreasingClass.runAlgorithm();
                break;

            case "full-bin packing": 
                fullBinClass.runAlgorithm();
                break;

            default: 
                System.out.println("Invalid algorithm type.");
                break;
        }
    }

    @FXML
    private void onResetClicked(ActionEvent event) {
        no1Field.setText(null);
        no2Field.setText(null);
        no3Field.setText(null);
        no4Field.setText(null);
        no5Field.setText(null);
        no6Field.setText(null);
        ofSizeField.setText(null);
    }

    public String getBinSize() {
        if (binSize == null) {
            binSize = "Bin size field is null.";
        }
        return binSize;
    }

}

最后,我有另一个控制器类FirstFitController,其初始化方法设置如下:

@Override
    public void initialize(URL url, ResourceBundle rb) {
        // Create object of main controller so we can access the fields
        FXMLDocumentController mainController = new FXMLDocumentController();

        // Get and print value of bin size label
        System.out.println(mainController.getBinSize());
        // binSizeBottomLabel.setText("Bin size: " + mainController.getBinSize());
    }  

基本上,用户从第一个窗口(我在最顶层发布了FXML文件)的下拉菜单中选择First-Fit,并在每个字段中输入值(特别针对此问题请注意“ofSizeField”) )。然后打开另一个窗口,它应该向控制台打印用户在“ofSizeField”中输入的值(使用getBinSize方法) - 但每次返回为null时即使我在其中输入内容。

我理解如果我在getBinSize方法中没有if语句来检查它是否等于null,我会得到NullPointerException错误但是我不明白我做错了因为在“单击“构建窗口”按钮,程序执行“onBuildClicked”方法,变量“binSize”设置如下: binSize = ofSizeField.getText();

然后调用方法getBinSize,返回null。

如果有人能帮助我,请告诉我我做错了什么,我会非常感激。 提前致谢

编辑 -

So my changeStage(String fxmlName) contains these lines of code:
public void changeStage(String fxmlName) throws Exception {

        FXMLLoader fxmlLoader = new FXMLLoader();
        Pane p = fxmlLoader.load(getClass().getResource(fxmlName + ".fxml"));
        FirstFitController ffc = (FirstFitController) fxmlLoader.getController();

        // Create objects of the stage and scene
        Stage stage = new Stage();
        Scene scene = new Scene(p);

        // Show the new stage/open new window
        stage.setScene(scene);

        // Detect title for the window
        if (fxmlName == "FirstFit")
        {
            stage.setTitle("First-Fit");
        } else if (fxmlName == "FirstFitDecreasing") {
            stage.setTitle("First-Fit Decreasing");
        } else {
            stage.setTitle("Full-Bin Packing");
        }

        stage.show();
    }

但首先,似乎FXMLLoader的加载方法是静态方法 - 为什么有必要创建一个对象? 其次,我不太明白我将如何使用“ffc”(FirstFitController的实例)?

谢谢

1 个答案:

答案 0 :(得分:0)

从我这边做一点猜测:

您从用户输入值的FXMLDocumentController实例开始。 那么FirstFitController被调用为另一个窗口(这是正确的吗?)。它在FXMLDocumentController方法中创建initialize的实例。现在该实例与用户输入值的第一个实例不同。因此binSizenull

解决方案是将第一个FXMLDocumentController的引用传递给FirstFitController,从中可以读取值(特别是不创建新实例)。 (或者创建一个单独的类,它保存实际值并传递它。)

编辑:

为FirstFitController加载FXML时,请执行以下操作:

FXMLLoader fxmlLoader = new FXMLLoader();
Pane p = fxmlLoader.load(getClass().getResource(fxmlName + ".fxml"));
FirstFitController ffc = (FirstFitController) fxmlLoader.getController();

然后,您可以访问FirstFitController的实际实例,并根据需要设置任何成员。 (您需要创建FxmlLoader的实例来检索控制器。)

相关问题