I have a label that is created by a 3'd Party lib.
Now I want to fill the label with a text (variable length) and icon (variable width), where the text is above the icon and both are left-aligned. But if I do it, I get the text and icon centered to each other. If the text width is longer than the icon width, the icon is centered to the text. In other case the text is centered to the icon. But I want both left-aligned. When I change the horizontal text position from CENTER to LEFT, I get the text left to icon and not above as required.
public class LabelTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(LabelTest::new);
}
public LabelTest() {
JFrame frm = new JFrame();
JLabel label = new JLabel("Hallo World");
label.setIcon(createIcon(100));
label.setVerticalTextPosition(SwingConstants.TOP);
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setHorizontalAlignment(SwingConstants.LEFT);
frm.add(label);
frm.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frm.setSize(300, 200);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
private Icon createIcon(int width) {
BufferedImage img = new BufferedImage(width, 20, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.setColor(Color.BLUE);
g.fillRect(0, 0, width, 20);
g.dispose();
return new ImageIcon(img);
}
}
As a complete hack you can manipulate the Icon to be the same size as the text.
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.border.*;
public class LabelIconTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(LabelIconTest::new);
}
public LabelIconTest() {
JFrame frm = new JFrame();
JLabel label = new JLabel("label icon with long text");
// JLabel label = new JLabel("short text");
label.setIcon(createIcon(100, Color.BLUE));
label.setVerticalTextPosition(SwingConstants.TOP);
label.setHorizontalTextPosition(SwingConstants.CENTER);
label.setHorizontalAlignment(SwingConstants.LEFT);
label = adjustLabelIcon( label );
frm.add(label);
frm.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
frm.setSize(300, 200);
frm.setLocationRelativeTo(null);
frm.setVisible(true);
}
public JLabel adjustLabelIcon(JLabel label)
{
System.out.println("before: " + label.getPreferredSize());
Icon original = label.getIcon();
label.setIcon( null );
int textWidth = label.getPreferredSize().width;
int iconWidth = original.getIconWidth();
int diff = textWidth - iconWidth;
if (diff == 0)
{
label.setIcon( original );
return label;
}
if (diff > 0)
{
Icon emptyIcon = createIcon(diff, new Color(0, 0, 0, 0));
Icon compound = new CompoundIcon(CompoundIcon.Axis.X_AXIS, 0, CompoundIcon.LEFT, CompoundIcon.CENTER, original, emptyIcon);
label.setIcon( compound );
}
else
{
Icon emptyIcon = createIcon(-diff, new Color(0, 0, 0, 0));
Icon compound = new CompoundIcon(CompoundIcon.Axis.X_AXIS, 0, CompoundIcon.LEFT, CompoundIcon.CENTER, emptyIcon, original);
label.setIcon( compound );
label.setBorder( new EmptyBorder(0, diff, 0, 0) );
}
System.out.println("after: " + label.getPreferredSize());
return label;
}
private Icon createIcon(int width, Color color) {
BufferedImage img = new BufferedImage(width, 20, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.setColor(color);
g.fillRect(0, 0, width, 20);
g.dispose();
return new ImageIcon(img);
}
}
This example uses the Compound Icon.
It also uses a trick of an EmptyBorder to make the component smaller.