0

我正在开发一个聊天客户端/服务器。在客户端,我有一个名为 的类ClientGui和一个名为InputPaneextends的子类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()电话,我能够发现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);
    }
4

2 回答 2

4

问题是 Swing 框架setFont作为JPanel构造函数的一部分进行调用。由于 this 在构造函数的主体之前执行,因此在初始化和成员变量InputPane.setFont之前被调用。我认为,这里唯一干净的解决方案是在内部进行明确的空检查:sendinputFieldInputPane.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);
    }
}

(您可能可以重新组织您的调用以减少空检查的数量。)

顺便说一句,这是一个很好的例子,说明为什么从构造函数调用可覆盖的方法是不好的做法。但是 Swing 就是这样,抱怨它没有任何好处,所以我就到此为止。:)

于 2012-10-18T05:06:35.093 回答
0

当您使用设置字体setFont并从getFont方法中获取并设置它时。这更有可能getFont()返回 NULL,这可能就是原因。同样在我看来,除非您明确地将它们设为 NULL,否则对象中inputFieldsend对象都不能为 NULL 。inputPane

于 2012-10-18T04:25:49.683 回答