I want to set text above and below a JButton‘s icon. At the moment, in order to achieve this, I override the layout manager and use three JLabel instances (i.e. 2 for text and 1 for the icon). But this seems like a dirty solution.
Is there a more direct way of doing this?
Note –
I’m not looking for a multi-line solution, I’m looking for a multi-label solution. Although this article refers to it as a multi-line solution, it actually seems to refer to a multi-label solution.
EXAMPLE
import java.awt.Component;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public final class JButtonDemo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI(){
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JMultiLabelButton());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static final class JMultiLabelButton extends JButton
{
private static final long serialVersionUID = 7650993517602360268L;
public JMultiLabelButton()
{
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
add(new JCenterLabel("Top Label"));
add(new JCenterLabel(UIManager.getIcon("OptionPane.informationIcon")));
add(new JCenterLabel("Bottom Label"));
}
}
private static final class JCenterLabel extends JLabel
{
private static final long serialVersionUID = 5502066664726732298L;
public JCenterLabel(final String s)
{
super(s);
setAlignmentX(Component.CENTER_ALIGNMENT);
}
public JCenterLabel(final Icon i)
{
super(i);
setAlignmentX(Component.CENTER_ALIGNMENT);
}
}
}

There is not way to split the text between the top/bottom of a JButton. This would involve custom painting.
Since I’m not sure of your exact requirement I’ll just through out a few random ideas:
You can use a JButton with text & icon. There are methods in the API that allow you to controal where text is positioned relative to the icon. Then you would need a second label for the other line of text. Basically the same as you current solution but you only need two labels.
You could use the Text Icon and Compound Icon classes to create 1 Icon out of 3 separate Icons. Then you can just add the icon to a button.
Use a JTextPane. Its supports an insertIcon() method. So you could add a line of text, add the icon and then add the other line of text. You can play with the paragraph attributes of the text pane to align the text horizontally within the space if you don’t want the text left justified. You can also play with the background color to make it look like a label.
Example using the CompoundIcon: