【问题标题】:Adding player to database through JFrame gives nullpointer - cannot find why通过 JFrame 将播放器添加到数据库会产生空指针 - 找不到原因
【发布时间】:2015-01-12 12:17:46
【问题描述】:

第一次在这里发布问题。主要是因为在无休止的搜索之后,我仍然无法找到解决方案,对于我只是忽略了一个非常简单的解决方案,我不会感到惊讶。

(注意:变量名称等主要是荷兰语,因为那是我的语言,不过应该没什么关系。)

我一直在做一个项目,在该项目中我将 JFrame 链接到数据库,并且就将播放器(见下文)添加到数据库而言,它非常有效。我的问题在于刷新显示当前在数据库中的玩家的 JFrame。使用我当前的代码,无论我尝试什么,它都会返回一个空指针异常。为了保存大量文本,我将确切的异常放在 pastebin 中。

在我在 JFrame 中添加播放器的代码上(我暂时省略了 NetBeans 自动生成的代码)

public class InschrijvenSpeler extends javax.swing.JFrame {

private InschrijvenSpeler inschrijvenSpeler;
private SpelerFrame spelerFrame;

public InschrijvenSpeler() {
    initComponents();
    setVisible(true);
    this.spelerFrame = spelerFrame;
    this.setDefaultCloseOperation(InschrijvenSpeler.DISPOSE_ON_CLOSE);
}

private void btnToevoegenActionPerformed(java.awt.event.ActionEvent evt) {                                             
    String Voornaam = this.txtVnaam.getText();
    String Achternaam = this.txtAnaam.getText();
    String Straat = this.txtStr.getText();
    String Huisnummer = this.txtHnr.getText();
    String Postcode = this.txtPcode.getText();
    String woonplaats = this.txtWplaats.getText();
    String Telefoonnummer = this.txtTelNr.getText();
    String Email = this.txtEmail.getText();

    try {
        Connection conn = DataBaseConnector.getConnection();
        Statement stat = conn.createStatement();

        String prepStatInsertSpeler = "INSERT INTO speler (speler_id, voornaam, achternaam, straat, huisnummer, postcode, woonplaats, telefoonnummer, email) "
                + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
        PreparedStatement prepStat = conn.prepareStatement(prepStatInsertSpeler);

        spelerID spelerID = new spelerID();
        spelerID.getIdVerhoging();

        prepStat.setString(1, spelerID.getReportVandaag() + spelerID.converteerId());
        prepStat.setString(2, Voornaam);
        prepStat.setString(3, Achternaam);
        prepStat.setString(4, Straat);
        prepStat.setString(5, Huisnummer);
        prepStat.setString(6, Postcode);
        prepStat.setString(7, woonplaats);
        prepStat.setString(8, Telefoonnummer);
        prepStat.setString(9, Email);

        prepStat.executeUpdate();

    } catch (SQLException exc) {
        JOptionPane.showMessageDialog(this, "Speler niet opgeslagen in de database" + exc.toString());
    }

    this.setVisible(false);
    spelerFrame.dispose();
    this.spelerFrame.vulSpelerTabel();
    spelerFrame.setVisible(true);

由于我在这里调用了另一个 JFrame 中的方法(该方法称为 vulSpelerTabel,翻译为“fillPlayerTable”),所以这里是该方法的代码:


public class SpelerFrame extends javax.swing.JFrame {

private ArrayList<Speler> spelers;

public SpelerFrame() {
    initComponents();
    this.setDefaultCloseOperation(SpelerFrame.DISPOSE_ON_CLOSE);
    spelers = new ArrayList();
    vulSpelerTabel();
}

public void vulSpelerTabel() {

    spelers.clear();

    //Definieren van de header kolommen.
    String[] kolommen = {"speler_id", "voornaam", "achternaam", "straat",
        "huisnummer", "postcode", "woonplaats",
        "telefoonnummer", "email", "rating", "aantal_geen_betalingen", "gewonnen_inleggeld"};

    DefaultTableModel model = new DefaultTableModel(kolommen, 0);

    //Clearing the table.
    DefaultTableModel clearModel = (DefaultTableModel) tblSpelers.getModel();
    clearModel.setRowCount(0);

    //Spelers ophalen uit database
    try {
        Connection conn = DataBaseConnector.getConnection();
        String selectSpelers = "SELECT * FROM speler";
        Statement statement = conn.createStatement();
        ResultSet result = statement.executeQuery(selectSpelers);

        //Resultaat doorlopen.
        while (result.next()) {
            String speler_id = result.getString("speler_id");
            String voornaam = result.getString("voornaam");
            String achternaam = result.getString("achternaam");
            String straat = result.getString("straat");
            String huisnummer = result.getString("huisnummer");
            String postcode = result.getString("postcode");
            String woonplaats = result.getString("woonplaats");
            String telefoonnummer = result.getString("telefoonnummer");
            String email = result.getString("email");
            double rating = result.getDouble("rating");
            int betalingen = result.getInt("aantal_geen_betalingen");
            double gewonnen_inleggeld = result.getDouble("gewonnen_inleggeld");

            Speler speler = new Speler(speler_id, voornaam, achternaam,
                    straat, huisnummer, postcode,
                    woonplaats, telefoonnummer, email, rating, betalingen,
                    gewonnen_inleggeld);
            spelers.add(speler);
        }
    } catch (SQLException exc) {
        JOptionPane.showMessageDialog(this, "Fout bij het ophalen van de "
                + "spelers uit de database"
                + exc.toString());
    }

    for (Speler speler : spelers) {
        model.addRow(speler.getInfo());;
    }

    //model koppelen aan JTable
    this.tblSpelers.setModel(model);
}

最后是要放入数据的 SQL 表:


CREATE TABLE `speler` (
`speler_id` varchar(45) NOT NULL,
`voornaam` varchar(45) NOT NULL,
`achternaam` varchar(45) NOT NULL,
`straat` varchar(45) NOT NULL,
`huisnummer` varchar(45) NOT NULL,
`postcode` varchar(45) NOT NULL,
`woonplaats` varchar(45) NOT NULL,
`telefoonnummer` varchar(45) NOT NULL,
`email` varchar(45) NOT NULL,
`rating` double NOT NULL DEFAULT '1000',
`aantal_geen_betalingen` int(11) DEFAULT '0',
`gewonnen_inleggeld` double DEFAULT '0',
PRIMARY KEY (`speler_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我希望我没有忘记任何事情,而且有人可以看到我一定在某个地方犯了一个错误,这给了我正在得到的空指针异常。需要注意的几点:

  • 玩家确实被添加到数据库中,但没有出现在显示所有玩家的 JFrame 上(名为“SpelerFrame.java”)(因为框架不刷新)。
  • 按下“toevoegen”(翻译:添加)按钮时会出现空指针异常。由于上述说明是这种情况,我假设它发生在此按钮(“btnToevoegen”)的最后几行代码中。
  • 虽然SQL数据库有9个以上的值需要填写,但其他的都有默认值。 “speler_id”在其他地方确定,但我 100% 确定这不是问题,因为当完全注释掉“speler_id”的行并在 SQL 中为其赋予默认值时,问题仍然存在。

编辑:因为显然 pastebin 被忽略了,这里是被抛出的 NPE:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

at Views.InschrijvenSpeler.btnToevoegenActionPerformed(InschrijvenSpeler.java:194)

at Views.InschrijvenSpeler.access$200(InschrijvenSpeler.java:11)

at Views.InschrijvenSpeler$3.actionPerformed(InschrijvenSpeler.java:115)

at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)

at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)

at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)

at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)

at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)

at java.awt.Component.processMouseEvent(Component.java:6525)

at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)

at java.awt.Component.processEvent(Component.java:6290)

at java.awt.Container.processEvent(Container.java:2234)

at java.awt.Component.dispatchEventImpl(Component.java:4881)

at java.awt.Container.dispatchEventImpl(Container.java:2292)

at java.awt.Component.dispatchEvent(Component.java:4703)

at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)

at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)

at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)

at java.awt.Container.dispatchEventImpl(Container.java:2278)

at java.awt.Window.dispatchEventImpl(Window.java:2739)

at java.awt.Component.dispatchEvent(Component.java:4703)

at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)

at java.awt.EventQueue.access$400(EventQueue.java:97)

at java.awt.EventQueue$3.run(EventQueue.java:697)

at java.awt.EventQueue$3.run(EventQueue.java:691)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)

at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)

at java.awt.EventQueue$4.run(EventQueue.java:719)

at java.awt.EventQueue$4.run(EventQueue.java:717)

at java.security.AccessController.doPrivileged(Native Method)

at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)

at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)

at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)

at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)

at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)

at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

【问题讨论】:

  • NPE 在你的代码中哪里被抛出?
  • 为您的问题添加例外
  • 异常在 pastebin 中。它会在按下添加按钮时抛出,如我的问题底部的第二个注释中所述。
  • 在哪一行?请添加堆栈跟踪。请记住,您已经遗漏了代码,这会影响堆栈跟踪结果(供我们阅读)
  • @Stultuske er.. 堆栈跟踪 >_

标签: java mysql sql nullpointerexception


【解决方案1】:
this.spelerFrame = spelerFrame;

这是对自身的调用。由于您没有通过构造函数传递帧,因此它将始终保持为空,从而导致 NPE

你可以试试下面的代码

this.spelerFrame = new SpelerFrame();

我怀疑这是您的预期行为。我建议您阅读有关向主窗口/框架添加框架的信息。

编辑:

为了解决这个特殊问题,InschrijvenSpeler 的构造函数应该更改为public InschrijvenSpeler(SpelerFrame spelerFrame) { 并且应该像new InschrijvenSpeler(this).setVisible(true); 一样访问它

【讨论】:

  • 嗯,是的,我认为不是。如果我随后处理旧的“SpelerFrame.java”窗口,这将是解决方案。必须调查一下。
  • 或者更确切地说,不是处理旧框架,而是将其作为参数传递给 InschrijvenSpeler 的构造函数,以便您可以在该类中重复使用它
  • 对 java 代码有一点倦怠:\ 需要详细说明吗?
  • 当前您使用的是空构造函数public InschrijvenSpeler() {。如果在创建 InschrijvenSpeler 框架之前存在 SpelerFrame 窗口,您可以使用类似 new InschrijvenSpeler(spelerFrame); 的内容,并将构造函数更改为 public InschrijvenSpeler(SpelerFrame spelerFrame) {。这样,如果构造函数执行,它实际上会分配一些东西给this.spelerFrame
  • 这并不顺利,哈哈。给我无限看DX。不得不重启笔记本电脑。在 SpelerFrame.java 中打开 InschrijvenSpeler.java 的按钮下,我现在有:new InschrijvenSpeler(this).setVisible(true); 在 InschrijvenSpeler.java 中现在是class open private InschrijvenSpeler inschrijvenSpeler; private SpelerFrame spelerFrame; public InschrijvenSpeler(SpelerFrame spelerFrame) { initComponents(); setVisible(true); new InschrijvenSpeler(spelerFrame); this.setDefaultCloseOperation(InschrijvenSpeler.DISPOSE_ON_CLOSE); } 字符限制:(
猜你喜欢
  • 2021-04-10
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 2019-09-03
  • 2018-09-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
相关资源
最近更新 更多