将 JLabel 与 JCheckBox 的文本对齐

发布于 2024-09-19 13:19:58 字数 1743 浏览 5 评论 0原文

是否有一种独立于外观和感觉的方法来将组件(例如 JLabel)与 JCheckBox文本水平对齐?

我尝试使用 UIDefaults 中的值来预测文本相对于 JCheckBox 左上角的位置。我找到了一个可以为 Metal、Windows、Motif 和 A​​qua 外观和感觉提供正确结果的组合:
示例:金属(正确对齐)

但不在 Nimbus 中:
示例:Nimbus (不正确对齐)

是否有一个实用方法可以可靠地给出文本中的 X,Y 偏移量所有的外观和感觉?


代码(注意:为了避免任何布局副作用,我在此测试中使用了空布局):

import java.awt.Insets;

import javax.swing.JApplet;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.border.Border;

public class AlignCheckBoxText extends JApplet {

    public AlignCheckBoxText() {
        setLayout(null);
        checkBox = new JCheckBox("Hello, World!");
        label = new JLabel("Hello, World!");
        add(checkBox);
        add(label);
    }

    @Override
    protected void validateTree() {
        checkBox.setLocation(0, 0);
        checkBox.setSize(checkBox.getPreferredSize());
        int labelX = UIManager.getIcon("CheckBox.icon").getIconWidth();
        Insets cbInsets = UIManager.getInsets("CheckBox.margin");
        if (cbInsets != null) labelX += cbInsets.left + cbInsets.right;
        Border cbBorder = UIManager.getBorder("CheckBox.border");
        if (cbBorder != null) {
            Insets borderInsets = cbBorder.getBorderInsets(checkBox);
            if (borderInsets != null) {
                labelX += borderInsets.left; 
            }
        }
        label.setLocation(labelX, checkBox.getHeight());
        label.setSize(label.getPreferredSize());
        super.validateTree();
    }

    private JCheckBox checkBox;
    private JLabel label;

}

Is there a look-and-feel-independent way to align a component (e.g. a JLabel) horizontally with the text of a JCheckBox?

I am trying to use values from the UIDefaults to predict the location of the text relative to the top-left corner of the JCheckBox. I have found a combination that gives the right result for the Metal, Windows, Motif and Aqua Look-and-Feels:
Example: Metal (correctly-aligned)

But not in Nimbus:
Example: Nimbus (incorrectly-aligned)

Is there a utility method somewhere that will reliably give X,Y offsets for the text in all Look-and-Feels?


Code (note: to avoid any layout side-effects I used a null layout for this test):

import java.awt.Insets;

import javax.swing.JApplet;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.border.Border;

public class AlignCheckBoxText extends JApplet {

    public AlignCheckBoxText() {
        setLayout(null);
        checkBox = new JCheckBox("Hello, World!");
        label = new JLabel("Hello, World!");
        add(checkBox);
        add(label);
    }

    @Override
    protected void validateTree() {
        checkBox.setLocation(0, 0);
        checkBox.setSize(checkBox.getPreferredSize());
        int labelX = UIManager.getIcon("CheckBox.icon").getIconWidth();
        Insets cbInsets = UIManager.getInsets("CheckBox.margin");
        if (cbInsets != null) labelX += cbInsets.left + cbInsets.right;
        Border cbBorder = UIManager.getBorder("CheckBox.border");
        if (cbBorder != null) {
            Insets borderInsets = cbBorder.getBorderInsets(checkBox);
            if (borderInsets != null) {
                labelX += borderInsets.left; 
            }
        }
        label.setLocation(labelX, checkBox.getHeight());
        label.setSize(label.getPreferredSize());
        super.validateTree();
    }

    private JCheckBox checkBox;
    private JLabel label;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

独行侠 2024-09-26 13:19:58

(致OP:请不接受我之前的错误答案,我将删除它。抱歉!)

您可以使用不为标签绘制复选框的复选框。这适用于 Windows JDK6 中的所有 LAF,包括 Nimbus。我没有 Mac,所以无法测试 Aqua。

class CheckBoxLabel extends JCheckBox
{
    public CheckBoxLabel(String string)
    {
        super(string);
    }

    public void updateUI()
    {
        setUI(new CheckBoxLabelUI());
    }
}

class CheckBoxLabelUI extends BasicCheckBoxUI
{
    public void installUI(JComponent c)
    {
        super.installUI(c);
        Icon i = super.getDefaultIcon();
        icon_ = new EmptyIcon(i.getIconWidth(), i.getIconHeight());
    }

    public Icon getDefaultIcon()
    {
        return icon_;
    }

    private Icon icon_;
}

class EmptyIcon implements Icon
{
    public EmptyIcon()
    {
        this(0, 0);
    }

    public EmptyIcon(int width, int height)
    {
        width_ = width;
        height_ = height;
    }

    public int getIconHeight()
    {
        return height_;
    }

    public int getIconWidth()
    {
        return width_;
    }

    public void paintIcon(Component c, Graphics g, int x, int y)
    {
    }

    private int width_;
    private int height_;
}

(To OP: please unaccept my earlier wrong answer, and I'll delete it. Sorry!)

You can use a checkbox that doesn't paint the checkbox for your labels. This works for all LAFs in Windows JDK6, including Nimbus. I don't have a mac so can't test Aqua.

class CheckBoxLabel extends JCheckBox
{
    public CheckBoxLabel(String string)
    {
        super(string);
    }

    public void updateUI()
    {
        setUI(new CheckBoxLabelUI());
    }
}

class CheckBoxLabelUI extends BasicCheckBoxUI
{
    public void installUI(JComponent c)
    {
        super.installUI(c);
        Icon i = super.getDefaultIcon();
        icon_ = new EmptyIcon(i.getIconWidth(), i.getIconHeight());
    }

    public Icon getDefaultIcon()
    {
        return icon_;
    }

    private Icon icon_;
}

class EmptyIcon implements Icon
{
    public EmptyIcon()
    {
        this(0, 0);
    }

    public EmptyIcon(int width, int height)
    {
        width_ = width;
        height_ = height;
    }

    public int getIconHeight()
    {
        return height_;
    }

    public int getIconWidth()
    {
        return width_;
    }

    public void paintIcon(Component c, Graphics g, int x, int y)
    {
    }

    private int width_;
    private int height_;
}
酸甜透明夹心 2024-09-26 13:19:58

您可以右对齐标签并将其宽度设置为复选框的宽度减去右边框。它适用于所有使用 Windows JDK1.6.0_21 的 LAF,包括 Nimbus。我没有 Mac,所以无法测试 Aqua。

这是您的代码,稍作修改:

class AlignCheckBoxText extends JApplet {

    public AlignCheckBoxText() {
        setLayout(null);
        checkBox = new JCheckBox("Hello, World!");
        label = new JLabel("Hello, World!");
        add(checkBox);
        add(label);        
        label.setHorizontalAlignment(JLabel.TRAILING);
    }

    @Override
    protected void validateTree() {
        checkBox.setLocation(0, 0);
        checkBox.setSize(checkBox.getPreferredSize());
        int x = 0;
        Border cbBorder = UIManager.getBorder("CheckBox.border");
        if (cbBorder != null) {
            Insets borderInsets = cbBorder.getBorderInsets(checkBox);
            if (borderInsets != null) {
                x += borderInsets.right;
            }
        }
        label.setLocation(0, checkBox.getHeight());
        label.setSize(new Dimension(checkBox.getPreferredSize().width - x, label.getPreferredSize().height));
        super.validateTree();
    }

    private JCheckBox checkBox;
    private JLabel label;

}

You can right-align the label and set its width to be checkbox's width minus right border. It works for all LAFs with Windows JDK1.6.0_21, including Nimbus. I don't have a Mac so can't test Aqua.

Here's your code very slightly modified:

class AlignCheckBoxText extends JApplet {

    public AlignCheckBoxText() {
        setLayout(null);
        checkBox = new JCheckBox("Hello, World!");
        label = new JLabel("Hello, World!");
        add(checkBox);
        add(label);        
        label.setHorizontalAlignment(JLabel.TRAILING);
    }

    @Override
    protected void validateTree() {
        checkBox.setLocation(0, 0);
        checkBox.setSize(checkBox.getPreferredSize());
        int x = 0;
        Border cbBorder = UIManager.getBorder("CheckBox.border");
        if (cbBorder != null) {
            Insets borderInsets = cbBorder.getBorderInsets(checkBox);
            if (borderInsets != null) {
                x += borderInsets.right;
            }
        }
        label.setLocation(0, checkBox.getHeight());
        label.setSize(new Dimension(checkBox.getPreferredSize().width - x, label.getPreferredSize().height));
        super.validateTree();
    }

    private JCheckBox checkBox;
    private JLabel label;

}
我早已燃尽 2024-09-26 13:19:58

这不是一个完整的回复,但它可能会对您有所帮助:

如果将 checkBox.getIconTextGap() 添加到 labelX 的值,则对齐方式对于 Nimbus 似乎可以,但对于 Metal 或 GTK 则不行。

This is not a complete response, but it might help you :

If you add checkBox.getIconTextGap() to the value of labelX, the alignment seems to be OK with Nimbus, but not OK with metal or GTK.

沩ん囻菔务 2024-09-26 13:19:58

如果您使用 GroupLayout,Netbeans GUI 构建器可以将复选框的文本和下一行的标签对齐......有点像。

它似乎适用于 Nimbus,但在另一个 LAF 中,标签文本离右侧太远了一个像素。查看 GUI 构建器中为 GroupLayout 生成的代码,它在标签前面留出了 22x22 的间隙。对于 Nimbus,22 似乎是正确的,但对于其他 LAF,它似乎是 21。

生成的代码如下所示。

GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHortizontalGroup(
  layout.createParallelGroup(Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addGroup(layout.createParallelGroup(Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
          .addGap(22,22,22)
          .addComponent(label)
        )
        .addComponent(checkBox)
      )
    )
);

layout.setVerticalGroup(
  layout.createParallelGroup(Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addComponent(checkBox)
      .addPreferredGap(ComponentPlacement.RELATED)
      .addComponent(label)
    )
);

该代码将在分配 label 和 checkBox 之后进入示例类的构造函数。另外,删除 setLayout(null);

综上所述,根据我使用 GUI 构建器所看到的情况,我建议实际执行以下操作:

  1. 从示例中删除 Border cbBorder 位,
  2. 添加 checkBox.getIconTextGap () 到 labelX。
  3. 如果 LAF 是 nimbus,则将 4 添加到 labelX。 :)

If you use GroupLayout, the Netbeans GUI builder can align the text of a check box and a label on the next line.... sort of.

It appears to work well for Nimbus, but in the other LAF the label text is one pixel too far to the right. Looking at the generated code for the GroupLayout in the GUI builder, it makes a gap of 22x22 in front of the label. For Nimbus, 22 seems right, but for the other LAFs it appears to be 21.

The generated code looks like this.

GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHortizontalGroup(
  layout.createParallelGroup(Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addGroup(layout.createParallelGroup(Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
          .addGap(22,22,22)
          .addComponent(label)
        )
        .addComponent(checkBox)
      )
    )
);

layout.setVerticalGroup(
  layout.createParallelGroup(Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
      .addContainerGap()
      .addComponent(checkBox)
      .addPreferredGap(ComponentPlacement.RELATED)
      .addComponent(label)
    )
);

This code would go in the constructor of the sample class after the assignments of label and checkBox. Also, remove the setLayout(null);

All of this being said, based on what I've seen using the GUI builder, I'd recommend the following for real:

  1. remove the Border cbBorder bit from the sample
  2. add the checkBox.getIconTextGap() to the labelX.
  3. If the LAF is nimbus, then add 4 to labelX. :)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文