8

コンポーネント(例:)をaのテキストJLabel水平方向に揃えるルックアンドフィールに依存しない方法はありますか?JCheckBox

の値を使用してUIDefaults、の左上隅を基準にしたテキストの位置を予測しようとしていますJCheckBox。Metal、Windows、Motif、AquaLook-and-Feelsに適切な結果をもたらす組み合わせを見つけました。
例:金属(正しく位置合わせされている)

しかし、ニンバスではありません:
例:ニンバス(正しく位置合わせされていない)

すべてのルックアンドフィールのテキストにX、Yオフセットを確実に与えるユーティリティメソッドはどこかにありますか?


コード(注:レイアウトの副作用を回避するために、このテストではnullレイアウトを使用しました):

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

4 に答える 4

3

(OPへ:私の以前の間違った答えを受け入れないでください、そして私はそれを削除します。ごめんなさい!)

ラベルのチェックボックスを描画しないチェックボックスを使用できます。これは、Nimbusを含むWindowsJDK6のすべてのLAFで機能します。私はマックを持っていないので、アクアをテストできません。

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_;
}
于 2010-09-20T16:24:22.510 に答える
2

ラベルを右揃えにして、その幅をチェックボックスの幅から右の境界線を引いたものに設定できます。これは、Nimbusを含むWindowsJDK1.6.0_21を使用するすべてのLAFで機能します。私は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;

}
于 2010-09-18T21:49:50.067 に答える
1

これは完全な応答ではありませんが、役立つ場合があります。

labelXの値に追加checkBox.getIconTextGap()すると、Nimbusでは位置合わせは問題ないように見えますが、metalやGTKでは問題ありません。

于 2010-09-18T16:25:39.443 に答える
1

GroupLayoutを使用する場合、Netbeans GUIビルダーは、チェックボックスのテキストとラベルを次の行に揃えることができます。

ニンバスではうまく機能しているように見えますが、他のLAFでは、ラベルテキストが1ピクセル右にありすぎています。GUIビルダーでGroupLayout用に生成されたコードを見ると、ラベルの前に22x22のギャップがあります。ニンバスの場合、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がニンバスの場合は、labelXに4を追加します。:)
于 2010-09-18T19:30:40.340 に答える