简体   繁体   English

当Icon为Null时,JLabel出现意外的Text-Alignment行为

[英]JLabel unexpected Text-Alignment behaviour when Icon is Null

How do I get around the apparent limitation of JLabel ignoring placement directives if the icon is null ? 如果图标为null,如何解决JLabel忽略放置指令的明显限制?

I have an app that uses a JLabel to show an Icon with explanatory text but sometimes the JLabel contains text-only and no corresponding Icon. 我有一个使用JLabel来显示带有解释性文本的图标的应用程序,但有时JLabel仅包含文本,而没有对应的Icon。

I have the alignment on the JLabel set as follows : 我对JLabel设置了对齐方式,如下所示:

label5.setHorizontalAlignment(JLabel.CENTER);
label5.setVerticalAlignment(JLabel.TOP);
label5.setHorizontalTextPosition(JLabel.CENTER);
label5.setVerticalTextPosition(JLabel.BOTTOM);
label5.setIconTextGap(-3);

This all works perfectly when there is an Icon present. 当存在图标时,所有这些都可以完美工作。 Icon above, text below. 上方的图标,下方的文字。

However, if the Icon is null (because the icon source file (gif/jpg etc) is missing from the nominated location or because the icon is set deliberately to null) then the text does NOT show at the bottom, but rather resets to the TOP of the Label. 但是,如果Icon为null(由于指定位置缺少图标源文件(gif / jpg等),或者因为故意将图标设置为null),则文本不会显示在底部,而是重置为标签的顶部。

I thought it might be something peculiar to do with my negative IconTextGap but I have been able to demonstrate the same behaviour on a standard Java JLabel example program (from www.java2s.com/Code/Java/Swing-JFC/LabelTextPosition.htm ) 我认为这可能与我的否定IconTextGap有关,但是我已经能够在标准Java JLabel示例程序中演示相同的行为(来自www.java2s.com/Code/Java/Swing-JFC/LabelTextPosition.htm

import java.awt.Container;
import java.awt.GridLayout;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

public class LabelTextPos {

  public static void main(String args[]) {
    JFrame frame = new JFrame("Label Text Pos");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    Container content = frame.getContentPane();
    content.setLayout(new GridLayout(2, 2));

    Border border = LineBorder.createGrayLineBorder();
    Icon warnIcon = new ImageIcon("Warning.gif");

    JLabel label1 = new JLabel(warnIcon);
    label1.setText("Left-Bottom");
    label1.setHorizontalTextPosition(JLabel.LEFT);
    label1.setVerticalTextPosition(JLabel.BOTTOM);
    label1.setBorder(border);
    content.add(label1);

    JLabel label2 = new JLabel(warnIcon);
    label2.setText("Right-TOP");
    label2.setHorizontalTextPosition(JLabel.RIGHT);
    label2.setVerticalTextPosition(JLabel.TOP);
    label2.setBorder(border);
    content.add(label2);

    JLabel label3 = new JLabel(warnIcon);
    label3.setText("Center-Center");
    label3.setHorizontalTextPosition(JLabel.CENTER);
    label3.setVerticalTextPosition(JLabel.CENTER);
    label3.setBorder(border);
    content.add(label3);

    JLabel label4 = new JLabel(warnIcon);
    label4.setText("Center-Bottom");
    label4.setHorizontalTextPosition(JLabel.CENTER);
    label4.setVerticalTextPosition(JLabel.BOTTOM);
    label4.setBorder(border);
    content.add(label4);

    frame.setSize(300, 200);
    frame.setVisible(true);
  }
}

When the ICON source file is present, you get the desired result : 存在ICON源文件时,您将获得所需的结果:

JLabel显示预期的行为

But if the ICONS are Null, the JLabel pays no attention to the Text Placement parameters : 但是,如果ICONS为N​​ull,则JLabel不会关注Text Placement参数:

JLable显示意外行为

I see that the JLabel Documentation says of setVerticalTextAlignment : 我看到JLabel文档说了setVerticalTextAlignment:

Sets the vertical position of the label's text, relative to its image . 设置标签文本相对于其图像的垂直位置。

But as you can see from the screensnaps above, where the Icon is actually null, it seems to bypass the JLabel location calculation code altogether. 但是,从上面的屏幕快照中可以看到,Icon实际上为空,它似乎完全绕开了JLabel位置计算代码。

I searched a lot before posting this but couldn't find anywhere that this specific issue is discussed. 在发布此消息之前,我进行了很多搜索,但找不到任何讨论此特定问题的地方。

So, is there a known or easy solution to this problem ? 那么,是否存在已知或简单的解决方案? I am fairly sure that I could create a new JLabel when I want to display the Text only, instead of setting the icon on the existing JLabel to Null, and the new JLabel without ever having had an icon would probably show the text in the desired location, but I would prefer not to go creating new Objects when the old ones are essentially doing what I need 95% of the time. 我相当确定我可以只显示文本时创建一个新的 JLabel,而不是将现有JLabel上的图标设置为Null,而没有图标的新JLabel可能会在所需的文本中显示文本位置,但是当旧对象本质上在95%的时间内都在做我需要的工作时,我不希望创建新对象。

I could also create a see-through icon of the appropriate size to keep my text at the bottom, but again that seems like a bit of a hack. 我还可以创建一个适当大小的透明图标,以将文本保留在底部,但是同样,这似乎有点不合常规。 Suggestions ? 建议?

Yes, 是,

JLabel s text position is relative to the icon. JLabel的文本位置是相对于图标的。 So, if it's icon is null definitely it will be aligned to the center. 因此,如果其图标为null ,则它将与中心对齐。 If you want to get rid of the problem, you will have to set an empty icon to the JLabel with required size. 如果要解决此问题,则必须为JLabel设置一个具有所需大小的空图标。

You can use following methods to create an empty Icon and set Icon to the JLabel 您可以使用以下方法创建一个空的Icon并将Icon设置为JLabel

//use this method to set icon to the label
private void setIcon(JLabel label, Icon icon) {
    if (icon == null) {
        icon = getEmptyIcon();
    }

    label.setIcon(icon);
}

//crete an empty icon
private Icon getEmptyIcon() {
    BufferedImage bufferedImage = new BufferedImage(24, 24, BufferedImage.TYPE_INT_ARGB);
    return new ImageIcon(bufferedImage);
}

How do I get around the apparent limitation of JLabel ignoring placement directives if the icon is null ? 如果图标为null,如何解决JLabel忽略放置指令的明显限制?

You have set the properties to control how the text/icon are relative to one another. 您已设置属性以控制文本/图标相对于彼此的方式。

However, you haven't set the properties to control how the text/icon are relative to the total space of the JLabel itself. 但是,您尚未设置属性来控制文本/图标相对于JLabel本身的总空间的方式。

You need to set the horizontal/vertical alignment of the text. 您需要设置文本的水平/垂直对齐方式。

The default values are CENTER , which means the text/icon are centered within the space of the label. 默认值为CENTER ,这意味着文本/图标在标签空间内居中。

For example: 例如:

label1.setVerticalAlignment(JLabel.BOTTOM);
label1.setHorizontalAlignment(JLabel.LEFT);

Try resizing the frame and see how both the text/icon remain displayed at the bottom/left. 尝试调整框架的大小,然后查看文本/图标如何同时显示在底部/左侧。

So you have two alignments to consider: 因此,您需要考虑两个方面:

  1. text/icon relative to the size of the JLabel 相对于JLabel大小的文本/图标
  2. text/icon relative to each other. 相对于彼此的文本/图标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM