在控制器 class 中使用构造函数时出现 NullPointerException。 JavaFX

NullPointerException while using constructor in controller class. JavaFX

这是我第一次 post 在这里,所以我希望这个问题不会重复。我是一名爱好者,正在尝试使用 JavaFX 创建一个可以管理辩论赛的应用程序。

我想在 TournamentCreation 中创建一个 Singleton 对象,TournamentEditor 也可以访问和操作它。

似乎当我的 Singleton GlobalInstance 对象被创建时(其中包含一个可以从其他地方访问和编辑的锦标赛),一个 NullPointerException 被抛出。使用调试我设法弄清楚它是在 GlobalInstance 调用默认的 Tournament 构造函数时发生的。

代码时间。这是 TournamentCreationController,其中错误以行 GlobalInstance.getInstance().currentTournament().setRounds(roundsIn);

开头
import java.net.URL;
import java.util.ResourceBundle;
import BusinessLogic.GlobalInstance;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;

public class TournamentCreationController implements Initializable , ControlledScreen {

ScreensController myController;

@FXML
TextField nameChooser;

@FXML
ChoiceBox roundNumberChooser;

@FXML
ChoiceBox breakNumberChooser;

@FXML
ChoiceBox noviceBreakNumberChooser;

@FXML
ChoiceBox eslBreakNumberChooser;

@FXML
ChoiceBox proAmBreakNumberChooser;


/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb)
{
    roundNumberChooser.setItems(FXCollections.observableArrayList(1,2,3,4,5,6,7,8,9));
    roundNumberChooser.getSelectionModel().select(4);

    breakNumberChooser.setItems(FXCollections.observableArrayList(4,8,16,32,64));
    breakNumberChooser.getSelectionModel().selectFirst();

    noviceBreakNumberChooser.setItems(FXCollections.observableArrayList(0,4,8,16,32,64));
    noviceBreakNumberChooser.getSelectionModel().selectFirst();

    eslBreakNumberChooser.setItems(FXCollections.observableArrayList(0,4,8,16,32,64));
    eslBreakNumberChooser.getSelectionModel().selectFirst();

    proAmBreakNumberChooser.setItems(FXCollections.observableArrayList(0,4,8,16,32,64));
    proAmBreakNumberChooser.getSelectionModel().selectFirst();

}

public void setScreenParent(ScreensController screenParent)
{
    myController = screenParent;
}

@FXML
private void goToEditor(ActionEvent event)
{
    String nameIn = nameChooser.getText();
    int roundsIn = (int)roundNumberChooser.getSelectionModel().getSelectedItem();
    int openBreakTeamsIn = (int)breakNumberChooser.getSelectionModel().getSelectedItem();
    int eslBreakTeamsIn = (int)eslBreakNumberChooser.getSelectionModel().getSelectedItem();
    int noviceBreakTeamsIn = (int)noviceBreakNumberChooser.getSelectionModel().getSelectedItem();
    int proAmBreakTeamsIn = (int)proAmBreakNumberChooser.getSelectionModel().getSelectedItem();


    GlobalInstance.getInstance().currentTournament().setRounds(roundsIn);
    GlobalInstance.getInstance().currentTournament().setOpenBreakTeams(openBreakTeamsIn);
    GlobalInstance.getInstance().currentTournament().setESLBreakTeams(eslBreakTeamsIn);
    GlobalInstance.getInstance().currentTournament().setNoviceBreakTeams(noviceBreakTeamsIn);
    GlobalInstance.getInstance().currentTournament().setProAmBreakTeams(proAmBreakTeamsIn);

    myController.setScreen(ScreensFramework.screen4ID);
}

}

这是单例 class:

public class GlobalInstance
{
private final static GlobalInstance instance = new GlobalInstance();
private Tournament tournament = new Tournament();

public static GlobalInstance getInstance()
{
    return instance;
}

public Tournament currentTournament()
{
    return tournament;
}

}

最后是Tournament class(忽略大部分,确切的错误发生在默认构造函数中的name.set("name")):

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.StringProperty;

public class Tournament
{
private StringProperty name;
private IntegerProperty rounds;
private BooleanProperty eslBreak;
private BooleanProperty noviceBreak;
private BooleanProperty proAmBreak;
private IntegerProperty openBreakTeams;
private IntegerProperty eslBreakTeams;
private IntegerProperty noviceBreakTeams;
private IntegerProperty proAmBreakTeams;

public Tournament()
{
name.set("name");
rounds.set(0);
eslBreak.set(false);
noviceBreak.set(false);
proAmBreak.set(false);
openBreakTeams.set(4);
eslBreakTeams.set(0);
noviceBreakTeams.set(0);
proAmBreakTeams.set(0);
}

public Tournament(String nameIn, int roundsIn, int openBreakTeamsIn, int eslBreakTeamsIn, int noviceBreakTeamsIn, int proAmBreakTeamsIn)
{
name.set(nameIn);
rounds.set(roundsIn);
openBreakTeams.set(openBreakTeamsIn);

if(eslBreakTeamsIn==0)
{
    eslBreak.set(false);
    eslBreakTeams.set(0);
}
else
{
    eslBreak.set(true);
    eslBreakTeams.set(eslBreakTeamsIn);
}

if(noviceBreakTeamsIn==0)
{
    noviceBreak.set(false);
    noviceBreakTeams.set(0);
}
else
{
    noviceBreak.set(true);
    noviceBreakTeams.set(noviceBreakTeamsIn);
}

if(proAmBreakTeamsIn==0)
{
    proAmBreak.set(false);
    proAmBreakTeams.set(0);
}
else
{
    proAmBreak.set(true);
    proAmBreakTeams.set(noviceBreakTeamsIn);
}
}

public String getName()
{
    return name.get();
}

public void setName(String nameIn)
{
    name.set(nameIn);
}

public int getRounds()
{
    return rounds.get();
}

public void setRounds(int roundsIn)
{
    rounds.set(roundsIn);
}

public int getOpenBreakTeams()
{
    return openBreakTeams.get();
}

public void setOpenBreakTeams(int openBreakTeamsIn)
{
    openBreakTeams.set(openBreakTeamsIn);
}

public boolean getESLBreak()
{
    return eslBreak.get();
}

public int getESLBreakNumber()
{
    return eslBreakTeams.get();
}

public void setESLBreakTeams(int eslBreakTeamsIn)
{
    if (eslBreakTeamsIn==0)
    {
        eslBreak.set(false);
        eslBreakTeams.set(0);
    }
    else
    {
        eslBreak.set(true);
        eslBreakTeams.set(eslBreakTeamsIn);
    }
}

public boolean getNoviceBreak()
{
    return noviceBreak.get();
}

public int getNoviceBreakNumber()
{
    return noviceBreakTeams.get();
}

public void setNoviceBreakTeams(int noviceBreakTeamsIn)
{
    if (noviceBreakTeamsIn==0)
    {
        noviceBreak.set(false);
        noviceBreakTeams.set(0);
    }
    else
    {
        noviceBreak.set(true);
        noviceBreakTeams.set(noviceBreakTeamsIn);
    }
}

public boolean getProAmBreak()
{
    return proAmBreak.get();
}

public int getProAmBreakNumber()
{
    return proAmBreakTeams.get();
}

public void setProAmBreakTeams(int proAmBreakTeamsIn)
{
    if (proAmBreakTeamsIn==0)
    {
        proAmBreak.set(false);
        proAmBreakTeams.set(0);
    }
    else
    {
        proAmBreak.set(true);
        proAmBreakTeams.set(proAmBreakTeamsIn);
    }
}
}

编程时,错误信息是解决问题的最佳帮手。在Java中,异常的根本原因可以说明实际问题。因此,如果我们查看您的用例,

Caused by: java.lang.ExceptionInInitializerError
at TabIt.TournamentCreationController.goToEditor(TournamentCreationController.java:84)

告诉我们,错误发生在goToEditor()方法中TournamentCreationControllerclass的第84行。然后,如果我们继续阅读其余的异常跟踪消息,我们会看到它的实际根本错误(原因),

Caused by: java.lang.NullPointerException
at BusinessLogic.Tournament.<init>(Tournament.java:24)

这里是说错误类型是NullPointerException,在Tournament的第24行 class.

这些提示足以确定问题。

更新

根据您更新的问题,问题是 name 变量尚未初始化。尝试使用未初始化的对象会引发空指针异常。锦标赛的构造函数应该是:

public Tournament()
{
    name = new SimpleStringProperty("name");
    rounds = new SimpleIntegerProperty(0);
    eslBreak = new SimpleBooleanProperty(false);
    // etc.
}

public Tournament(String nameIn, int roundsIn, int openBreakTeamsIn, int eslBreakTeamsIn, int noviceBreakTeamsIn, int proAmBreakTeamsIn)
{
    name = new SimpleStringProperty(nameIn);
    rounds = new SimpleIntegerProperty(roundsIn);
    eslBreak = new SimpleBooleanProperty(openBreakTeamsIn);
     // etc.
}