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()しかし、メソッドで null ポインター例外が発生していますか? なぜそれが起こっているのですか、どうすれば修復できますか? 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されたメソッドでは、Font を設定する必要があります (現時点では設定されていません)。

super()したがって、最初に引数なしのコンストラクター ( )を呼び出すと、text渡される引数が にinitなりnull、問題が回避されます。復帰後 super()(フォントが適切に設定されている時点) にのみ、setText(txt)明示的に呼び出しても安全であり、すべて正常に動作します。

(ロングストーリーハッピーエンド!)

于 2013-05-24T15:54:31.603 に答える
1

問題は、明らかにフィールドが初期化される前に、 のコンストラクターsetText()から呼び出されることです。これは Swing 関係者の悪いコーディング方法ですが、何もしないことで回避できます。JButtonfontgetFont() == null

于 2013-05-24T15:54:29.913 に答える