0

我想创建一个按钮,它会在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()返回 null 然后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)
4

2 回答 2

3

长话短说:
更改super(txt)

super();
setText(txt);

简短说明
正如堆栈跟踪所示,调用super(txt)(使用 String 参数)在某个点AbstractButtoninit方法调用:

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

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

因此,首先调用无参数构造函数 ( super()) 会导致text传递init给 be的参数null,从而避免了该问题。只有 super()返回后(此时字体已正确设置),setText(txt)显式调用是安全的并且一切正常。

(长话短说加上幸福的结局!)

于 2013-05-24T15:54:31.603 回答
1

问题是setText()JButton的构造函数调用,显然是在font字段初始化之前。对于 Swing 人员来说,这是一种糟糕的编码习惯,但是如果getFont() == null.

于 2013-05-24T15:54:29.913 回答