通过 JFrame 将播放器添加到数据库会出现空指针 - 找不到原因
Adding player to database through JFrame gives nullpointer - cannot find why
第一次在这里发帖提问。主要是因为经过无休止的搜索我仍然无法找到解决方案,我不会感到惊讶,因为它是一个非常简单的我只是忽略了。
(注意:变量名称等主要是荷兰语,因为那是我的语言,不过应该没什么大不了的。)
我一直在进行一个项目,在该项目中我将 JFrame 链接到数据库,并且就将播放器(见下文)添加到数据库而言,它完美地工作。我的问题在于刷新显示数据库中当前玩家的 JFrame。使用我当前的代码,无论我尝试什么,它 returns 我都是空指针异常。为了保存大量文本,我将确切的例外放在 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 table 数据被放入:
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;
我希望我没有忘记任何事情,而且有人可以看到我一定在某个地方犯了一个错误,这个错误给了我我得到的空指针异常。需要注意的几点:
- 玩家确实被添加到数据库中,但没有出现在显示所有玩家(名为 "SpelerFrame.java")的 JFrame 上(因为框架没有刷新)。
- 按下 "toevoegen"(翻译:添加)按钮时出现空指针异常。由于上面的说明是这种情况,我假设它发生在该按钮代码的最后几行 ("btnToevoegen")。
- 虽然SQL数据库有9个以上的值需要填写,但其他的都是默认值。 "speler_id" 在别处确定,但我 100% 确定这不是问题,因为当完全注释掉 "speler_id" 的行并在 [=50 中给它一个默认值时问题仍然出现=].
编辑:显然 pastebin 被忽略了,这里是抛出的 NPE:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Views.InschrijvenSpeler.btnToevoegenActionPerformed(InschrijvenSpeler.java:194)
at Views.InschrijvenSpeler.access0(InschrijvenSpeler.java:11)
at Views.InschrijvenSpeler.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.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:697)
at java.awt.EventQueue.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue.run(EventQueue.java:719)
at java.awt.EventQueue.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.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)
this.spelerFrame = spelerFrame;
这是对自己的调用。由于您没有通过构造函数传递框架,因此它将始终保持为空,从而导致 NPE
您可以试试下面的代码
this.spelerFrame = new SpelerFrame();
不过我怀疑这是您的预期行为。我建议您阅读有关向主 window/frame.
添加框架的内容
编辑:
为了解决这个特殊问题,InschrijvenSpeler
的构造函数应该更改为 public InschrijvenSpeler(SpelerFrame spelerFrame) {
并且应该像 new InschrijvenSpeler(this).setVisible(true);
一样访问它
第一次在这里发帖提问。主要是因为经过无休止的搜索我仍然无法找到解决方案,我不会感到惊讶,因为它是一个非常简单的我只是忽略了。
(注意:变量名称等主要是荷兰语,因为那是我的语言,不过应该没什么大不了的。)
我一直在进行一个项目,在该项目中我将 JFrame 链接到数据库,并且就将播放器(见下文)添加到数据库而言,它完美地工作。我的问题在于刷新显示数据库中当前玩家的 JFrame。使用我当前的代码,无论我尝试什么,它 returns 我都是空指针异常。为了保存大量文本,我将确切的例外放在 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 table 数据被放入:
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;
我希望我没有忘记任何事情,而且有人可以看到我一定在某个地方犯了一个错误,这个错误给了我我得到的空指针异常。需要注意的几点:
- 玩家确实被添加到数据库中,但没有出现在显示所有玩家(名为 "SpelerFrame.java")的 JFrame 上(因为框架没有刷新)。
- 按下 "toevoegen"(翻译:添加)按钮时出现空指针异常。由于上面的说明是这种情况,我假设它发生在该按钮代码的最后几行 ("btnToevoegen")。
- 虽然SQL数据库有9个以上的值需要填写,但其他的都是默认值。 "speler_id" 在别处确定,但我 100% 确定这不是问题,因为当完全注释掉 "speler_id" 的行并在 [=50 中给它一个默认值时问题仍然出现=].
编辑:显然 pastebin 被忽略了,这里是抛出的 NPE:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at Views.InschrijvenSpeler.btnToevoegenActionPerformed(InschrijvenSpeler.java:194)
at Views.InschrijvenSpeler.access0(InschrijvenSpeler.java:11)
at Views.InschrijvenSpeler.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.access0(EventQueue.java:97)
at java.awt.EventQueue.run(EventQueue.java:697)
at java.awt.EventQueue.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue.run(EventQueue.java:719)
at java.awt.EventQueue.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain.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)
this.spelerFrame = spelerFrame;
这是对自己的调用。由于您没有通过构造函数传递框架,因此它将始终保持为空,从而导致 NPE
您可以试试下面的代码
this.spelerFrame = new SpelerFrame();
不过我怀疑这是您的预期行为。我建议您阅读有关向主 window/frame.
添加框架的内容编辑:
为了解决这个特殊问题,InschrijvenSpeler
的构造函数应该更改为 public InschrijvenSpeler(SpelerFrame spelerFrame) {
并且应该像 new InschrijvenSpeler(this).setVisible(true);