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

对于带有图标的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); } }); } } 

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

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

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

这是预期的效果吗?

附录:我认为小组是要走的路。

图片

 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; } }); } } 

你应该使用:

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

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

我发现了一种更简单的方法。 我需要在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); ... } } 

效果很好!
是的,对于真正的代码,应检查文本宽度是否大于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); } }