Issue
I wanted to create button which would auto resize while the string
inside of it cannot be displayed (it is too big).
I got something like that:
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()));
}
}
I wanted to use that class:
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();
}
}
But I am getting null pointer exception in setText()
method? Why is that happening, and how can I repair it? getFont()
returns null and then getFontMetrics(null)
throws exception.
Stack trace:
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)
Solution
Long story short:
Change super(txt)
to
super();
setText(txt);
Short explanation
As the stack-trace indicates, calling super(txt)
(with a String argument) calls at some point AbstractButton
's init
method:
protected void init(String text, Icon icon) {
if (text != null) {
setText(text);
}
...
As you can see, IF the text
argument is not null
, method setText
is called. But your overriden setText
method requires the Font to be set (which at this point isn't).
So, calling the no-argument constructor first (super()
), causes the text
argument passed to init
to be null
, thus avoiding the problem. Only after super()
returns (at which point the Font has been properly set), is it safe to call setText(txt)
explicitely and everything works fine.
(Long story short plus happy ending !)
Answered By - gkalpak
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.