我正在使用聊天客户端/服务器。在客户端中,我有一个名为ClientGui的类和一个名为InputPane的子类,该子类扩展了JPanelClientGui处理与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()调用,我发现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构造函数的一部分进行调用。由于此操作在构造函数的主体之前执行,因此在初始化InputPane.setFontsend成员变量之前先调用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/

10-09 07:11