我正在使用聊天客户端/服务器。在客户端中,我有一个名为ClientGui
的类和一个名为InputPane
的子类,该子类扩展了JPanel
。 ClientGui
处理与GUI相关的客户端事物的主要部分,但是InputPane
仅处理来自用户的输入。
尝试在NullPointerException
类的InputPane
对象中设置字体时,我总是收到奇怪的ClientGui
。这是我的一些代码:
public ClientGui() {
// configure JFrame
this.serverOutput = new JTextPane();
this.input = new InputPane();
// configure JScrollPane
// configure other objects
// various set up methods
frame.add(scrollPane, BorderLayout.CENTER);
frame.add(input, BorderLayout.PAGE_END);
}
如您所见,
input
对象正在初始化。这是它的构造函数:public InputPane() {
this.inputField = new JTextField();
this.send = new JButton("Send");
// set size
this.setFont(getFont());
// various methods
// add components
}
当我尝试设置字体时,它会抛出一个
NullPointerException
。通过各种println()
调用,我发现inputField
和send
为空。我尝试将println()
方法放入构造函数中,但没有一个被调用(和/或打印)。我对此感到非常困惑。如果有人可以给出解释,那将会有很大帮助。谢谢。
编辑:这是StackTrace:
Exception in thread "main" java.lang.NullPointerException
at net.dean.tcp.client.gui.ClientGui$InputPane.setFont(ClientGui.java:518)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at net.dean.tcp.client.gui.ClientGui$InputPane.<init>(ClientGui.java:496)
at net.dean.tcp.client.gui.ClientGui.<init>(ClientGui.java:138)
at net.dean.tcp.client.gui.ClientGui.main(ClientGui.java:44)
编辑2:这是
ClientGui$InputPane.setFont(Font)
方法:public void setFont(Font f) {
super.setFont(f);
inputField.setFont(f);
send.setFont(f);
Dimension size = getSizeFromFont();
// Dimension based on getFont()'s height
send.setPreferredSize(size);
inputField.setPreferredSize(size);
}
最佳答案
问题在于,Swing框架将setFont
作为JPanel
构造函数的一部分进行调用。由于此操作在构造函数的主体之前执行,因此在初始化InputPane.setFont
和send
成员变量之前先调用inputField
。我认为,这里唯一干净的解决方案是在InputPane.setFont
内进行显式的null检查:
public void setFont(Font f) {
super.setFont(f);
if (inputField != null) {
inputField.setFont(f);
}
if (send != null) {
send.setFont(f);
}
Dimension size = getSizeFromFont();
// Dimension based on getFont()'s height
if (send != null) {
send.setPreferredSize(size);
}
if (inputField != null) {
inputField.setPreferredSize(size);
}
}
(您可以重组呼叫以减少空检查的数量。)
顺便说一句,这是为什么it is bad practice to call an overridable method from a constructor的一个很好的例子。但是Swing就是它的本质,并且抱怨着没有任何好处,所以我就在这里停止。 :)
关于java - 关于构造函数的奇怪NullPointerException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12946841/