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

时间:2015-04-04 01:01:24

标签: java model-view-controller javafx singleton javafx-2

这是我在这里发表的第一篇文章,所以我希望这个问题不是重复的。我是一个爱好者,他正在尝试使用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);
}

}

这是Singleton类:

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类(忽略大部分,确切错误发生在默认构造函数中的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);
    }
}
}

1 个答案:

答案 0 :(得分:0)

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

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

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

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

这里说错误类型为NullPointerException,位于Tournament类的第24行。

这些提示足以确定问题。

<强>更新

根据您更新的问题,问题是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.
}