Совместите JLabel с текстом JCheckBox - PullRequest
7 голосов
/ 18 сентября 2010

Существует ли независимый от внешнего вида способ выравнивания компонента (например, JLabel) по горизонтали с текстом из JCheckBox?

Я пытаюсь использовать значения из UIDefaults, чтобы предсказать местоположение текста относительно верхнего левого угла JCheckBox. Я нашел комбинацию, которая дает правильный результат для Металла, Окна, Мотива и Аква Лук-энд-Феелс:
Example: Metal (correctly-aligned)

Но не в Нимбусе:
Example: Nimbus (incorrectly-aligned)

Есть ли где-нибудь служебный метод, который надежно даст смещения 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;

}

Ответы [ 4 ]

3 голосов
/ 20 сентября 2010

(К ОП: пожалуйста, примите мой ранее неправильный ответ, и я его удалю. Извините!)

Вы можете использовать флажок, который не отображает флажок для ваших ярлыков.Это работает для всех LAF в Windows JDK6, включая Nimbus.У меня нет Mac, поэтому я не могу проверить Аква.

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_;
}
2 голосов
/ 19 сентября 2010

Вы можете выровнять метку вправо и установить ее ширину, равную ширине флажка минус правая граница Это работает для всех LAF с Windows JDK1.6.0_21, включая 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;

}
1 голос
/ 18 сентября 2010

Если вы используете GroupLayout, построитель графического интерфейса Netbeans может выровнять текст флажка и метку на следующей строке .... вроде.

Кажется, это хорошо работает для Nimbus, но в другом LAF текст метки находится на один пиксель слишком далеко вправо. Глядя на сгенерированный код для GroupLayout в конструкторе GUI, он делает разрыв 22x22 перед меткой. Для Нимба 22 кажется правильным, но для других ЛАФ это, кажется, 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)
    )
);

Этот код будет добавлен в конструктор класса-образца после присваивания меток и checkBox. Также удалите setLayout (null);

С учетом всего сказанного, основываясь на том, что я видел с помощью GUI Builder, я бы порекомендовал следующее:

  1. удалить бит Border cbBorder из семпла
  2. добавить checkBox.getIconTextGap() к метке X.
  3. Если LAF - это нимб, добавьте 4 к метке X. :)
1 голос
/ 18 сентября 2010

Это не полный ответ, но он может помочь вам:

Если вы добавите checkBox.getIconTextGap() к значению labelX, выравнивание кажется нормальным с Nimbus, но не с металлом или GTK.

...