JLabel,文本位于图标上方且左对齐

问题描述 投票:0回答:1

我有一个由 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);
    }
}
java swing jlabel
1个回答
0
投票

作为一个完整的黑客,您可以将图标控制为与文本大小相同。

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 的技巧来使组件更小。

© www.soinside.com 2019 - 2024. All rights reserved.