我有一个由 3'd Party 库创建的标签。
现在我想用文本(可变长度)和图标(可变宽度)填充标签,其中文本位于图标上方,并且两者都是左对齐的。但如果我这样做,我会让文本和图标彼此居中。如果文本宽度比图标宽度长,则图标将以文本为中心。在其他情况下,文本以图标为中心。但我想要两者都左对齐。当我将水平文本位置从 CENTER 更改为 LEFT 时,我将文本置于图标左侧,而不是按要求位于上方。
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);
}
}
作为一个完整的黑客,您可以将图标控制为与文本大小相同。
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);
}
}
此示例使用复合图标。
它还使用了 EmptyBorder 的技巧来使组件更小。