For a JLabel with icon, if you setHorizontalTextPosition(SwingConstants.LEADING)
, the icon is painted right after text, no matter how wide the label is.
This is particularly bad for a list, as the icons would be all over the place depending on how long the text is for each item.
I traced the code and it seems to be that in SwingUtilities#layoutCompoundLabelImpl
, text width is simply set to SwingUtilities2.stringWidth(c, fm, text)
, and icon x is set to follow text without considering label width.
Here is the simplest case:
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);
}
});
}
}
You can see that label always fills the frame but icon stays put. You'll get the mirror problem if you set both arguments to TRAILING
.
I know I can override the UI, or use a JPanel, etc. I just wonder if I'm missing something simple in JLabel. If not, it seems like a Java bug.
FYI this is jdk1.6.0_06 on Windows XP.
-
Is this the desired effect?
Addendum: I think a panel is the way to go.
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; } }); } }
Geoffrey Zheng : Nop, I need to have text left justified and icon right justified.trashgod : Ah, I see what you mean.
0 comments:
Post a Comment