java - 关于构造函数的奇怪 NullPointerException

标签 java swing constructor nullpointerexception

我正在开发聊天客户端/服务器。在客户端中,我有一个名为 ClientGui 的类,以及一个名为 InputPane 的子类,它扩展了 JPanelClientGui 处理 GUI 相关客户端事务的主要部分,但 InputPane 仅处理来自用户的输入。

当尝试在 ClientGui 类中的 InputPane 对象中设置字体时,我不断收到奇怪的 NullPointerException 错误。这是我的一些代码:

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() 调用,我发现 inputFieldsend 为空。我尝试将 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 构造函数的一部分。由于它在构造函数主体之前执行,因此在初始化 sendinputField 成员变量之前调用 InputPane.setFont。我认为,这里唯一干净的解决方案是在 InputPane.setFont 内进行显式空检查:

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/

相关文章:

java - 无法解析包 org.apache.commons.vfs 异常

java - 未找到 Java 对象名称中的类中的类

java - 使用数组创建 DeckOfCards 类

Java 闪烁图形

java - 与 @Builder 结合使用时,我无法让 @RequiredArgsConstructor 工作

java - 什么是NullPointerException,我该如何解决?

java - Java 中多个具有相同 ResultSet 的 jTable

java - 如何在swing中将面板保存为图像?

c++ - 如何在 C++ 中创建参数化对象数组?

C++ 从 C 类调用 A 类中的构造函数(继承)