从我的JButton获取字体时出现NullPointerException

时间:2013-05-24 15:39:41

标签: java swing nullpointerexception jbutton

我想创建一个自动调整大小的按钮,而它内部的string无法显示(它太大了)

我是这样的:

public class ResizingButton extends JButton {
    public ResizingButton(String txt) {
        super(txt);
        addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                setText(JOptionPane.showInputDialog("Text"));
            }
        });
    }

    @Override
    public void setText(String arg0) {
        super.setText(arg0);
        FontMetrics metrics = getFontMetrics(getFont());//nullPointerException !!!
        int width = metrics.stringWidth(getText());
        int height = metrics.getHeight();
        Dimension newDimension = new Dimension(width + 40, height + 10);
        setPreferredSize(newDimension);
        setBounds(new Rectangle(getLocation(), getPreferredSize()));
    }
}

我想使用那个类:

public class Zadanie2 extends JFrame {
    public Zadanie2() {
        createGUI();
    }

    private void createGUI() {
        setSize(200, 80);
        //setLayout(new GridLayout());
        add(new ResizingButton("tekst"));
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
    new Zadanie2();
    }
}

但我在setText()方法中得到空指针异常?为什么要修理它? getFont()returns null and then getFontMetrics(null)`抛出异常。

堆栈追踪:

Exception in thread "main" java.lang.NullPointerException
    at java.util.concurrent.ConcurrentHashMap.hash(Unknown Source)
    at java.util.concurrent.ConcurrentHashMap.get(Unknown Source)
    at sun.font.FontDesignMetrics.getMetrics(Unknown Source)
    at sun.swing.SwingUtilities2.getFontMetrics(Unknown Source)
    at javax.swing.JComponent.getFontMetrics(Unknown Source)
    at ResizingButton.setText(ResizingButton.java:26)
    at javax.swing.AbstractButton.init(Unknown Source)
    at javax.swing.JButton.<init>(Unknown Source)
    at javax.swing.JButton.<init>(Unknown Source)
    at ResizingButton.<init>(ResizingButton.java:13)
    at Zadanie2.createGUI(Zadanie2.java:14)
    at Zadanie2.<init>(Zadanie2.java:8)
    at Zadanie2.main(Zadanie2.java:20)

2 个答案:

答案 0 :(得分:2)

长话短说:
super(txt)更改为

super();
setText(txt);

简短说明
正如堆栈跟踪所指示的那样,调用super(txt)(带有String参数)会在某个时间调用AbstractButton&#39; init方法:

protected void init(String text, Icon icon) {
    if (text != null) {
        setText(text);
    }
    ...

如您所见, IF text参数不是null,方法setText被调用。但是,您的覆盖setText方法需要设置Font(此时此字段不是。)

因此,首先调用无参数构造函数(super())会导致传递给text的{​​{1}}参数为init,从而避免了问题。只有 null后返回(此时Font已正确设置),是否可以安全地明确调用super()并且一切正常。

(长话短说快乐的结局!)

答案 1 :(得分:0)

问题是setText()是从JButton的构造函数调用的,显然是在font字段初始化之前。这是Swing人员的错误编码练习,但你可以通过getFont() == null无所事事来解决它。