Q: Suppose I want to create the button with a label as shown below:
"Name" will be on the second line.
I tried to create it with:
new JButton("Your \\n Name")
Unfortunately, that doesn't work. Do you have any suggestions?
A: The short answer: you can't do it without a bit of work on your part. The
JButton does not intrinsically have the ability to wrap long lines or start a new line when the text contains a
All JFC components are rendered through a corresponding
ComponentUI. Instead of putting all of the rendering code in the
JButton's paint method, the
JButton delegates its display to a
ButtonUI (an extension of
ComponentUI allows us to change the look and feel of a Java Swing GUI on the fly by simply swapping in new
ComponentUI renderers into our
One implementation of
ButtonUI that a
JButton may use is the
BasicButtonUI. If you're brave enough to look at the
BasicButtonUI's code, you'll notice the method:
protected void paintText(Graphics g, JComponent c, Rectangle textRect, String text)
paintText() does all the string drawing dirty work. If we dig a little further, you'll see that this method further delegates the actual drawing to the
drawString() method in
public static void drawString(Graphics g,String text,int underlinedChar,int x,int y)
drawString() does a little processing and then simply calls the
drawString() method. We had to dig a bit, but now it's fairly obvious why
JButton won't wrap text around a new line.
So, to do what you want to do, you have a few choices:
- You can create your own custom
JButtonand overriding its paint method. In that method, you would tokenize your string based on
\n, do a few spacing calculations, draw your button, and then draw your broken text. However, if you do it that way, your button will lose its pluggable look and feel. You will also lose many of the other Swing display tricks.
- You can create a new
ButtonUIthat formats your text properly.
You can forget about getting that functionality directly from the
JButton. Instead, a combination of
JButtonwill give you what you need. Try the following:
JButton b = new JButton(); b.setLayout(new BorderLayout()); JLabel label1 = new JLabel("Your"); JLabel label2 = new JLabel("Name"); b.add(BorderLayout.NORTH,label1); b.add(BorderLayout.SOUTH,label2);
If you find that a multiline button is something you use a lot, you can wrap the above solution into a convenience class, say
MultiLineButton. That class would extend
JButton, encapsulate two
JLabel instances, and have
void setLabel1Text(String text) and
void setLabel2Text(String text) methods.
|HTML rendering in Swing is possible!|