如何在JLabel中对图标进行右对齐?

Geo*_*eng 9 java swing jlabel jpanel layout-manager

对于带有图标的JLabel,如果setHorizontalTextPosition(SwingConstants.LEADING)是,则无论标签有多宽,都会在文本后面立即绘制图标.

这对于列表来说尤其糟糕,因为图标将遍布整个地方,具体取决于每个项目的文本长度.

我跟踪代码,似乎是SwingUtilities#layoutCompoundLabelImpl,文本宽度只是设置为SwingUtilities2.stringWidth(c, fm, text),而图标x设置为跟随文本而不考虑标签宽度.

这是最简单的情况:

import java.awt.*;
import javax.swing.*;

public class TestJLabelIcon
{
    public static void main(String args[])
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                JLabel c = new JLabel("abc");
                c.setHorizontalTextPosition(SwingConstants.LEADING);
                c.setHorizontalAlignment(SwingConstants.LEADING);
                c.setIcon(UIManager.getIcon("FileChooser.detailsViewIcon"));
                c.setBorder(BorderFactory.createLineBorder(Color.RED));

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                frame.getContentPane().add(c);    
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以看到标签始终填充框架但图标保持不变.如果将两个参数都设置为,则会出现镜像问题TRAILING.

我知道我可以覆盖UI,或使用JPanel等.我只是想知道我是否在JLabel中遗漏了一些简单的东西.如果没有,它似乎是一个Java bug.

仅供参考,这是Windows XP上的jdk1.6.0_06.

axe*_*rod 23

你应该使用:

label1.setHorizo​​ntalTextPosition(SwingConstants.LEFT);

(设置文本的位置,相对于图标)


tra*_*god 13

这是预期的效果吗?

附录:我认为专家组是要走的路.

图片

import java.awt.*;
import javax.swing.*;

public class TestJLabelIcon {

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setLayout(new GridLayout(0, 1));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(createPanel("abc"));
                frame.add(createPanel("defghij"));
                frame.add(createPanel("klmn"));
                frame.add(createPanel("opq"));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

            private JPanel createPanel(String s) {
                JPanel p = new JPanel(new BorderLayout());
                p.add(new JLabel(s, JLabel.LEFT), BorderLayout.WEST);
                Icon icon = UIManager.getIcon("FileChooser.detailsViewIcon");
                p.add(new JLabel(icon, JLabel.RIGHT), BorderLayout.EAST);
                p.setBorder(BorderFactory.createLineBorder(Color.blue));
                return p;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)


Fre*_*ews 6

我发现了一种更简单的方法.我需要在JTable中使用这种布局,并通过获取文本宽度然后手动设置文本和图标之间的宽度来进行正确的调整.我为我的JTable子类化了一个DefaultTableCellRenderer

public class FixedWidthRenderer extends DefaultTableCellRenderer 
{
    ...
    @Override
    public Component getTableCellRendererComponent(JTable table, Object value, 
        boolean isSelected, boolean hasFocus, int row, int column)
    {
        ...
        FontMetrics met = super.getFontMetrics(super.getFont());
        int width = met.stringWidth(super.getText());                
        super.setIconTextGap(DESIREDWIDTH - width); 
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

效果很好!
是的,对于真正的代码,应检查文本宽度是否大于DESIREDWIDTH.


对于没有固定宽度的自动右对齐,可以使用可变宽度的列:

    @Override
    public void setBounds(int x, int y, int width, int height) {
        super.setBounds(x, y, width, height);
        if (getIcon() != null) {
            int textWidth = getFontMetrics(getFont()).stringWidth(getText());
            Insets insets = getInsets();
            int iconTextGap = width - textWidth - getIcon().getIconWidth() - insets.left - insets.right - PADDING;
            setIconTextGap(iconTextGap);
        } else {
            setIconTextGap(0);
        }
    }
Run Code Online (Sandbox Code Playgroud)