【问题标题】:Having a Left and Right Aligned Label inside a JCheckBox在 JCheckBox 中有一个左右对齐的标签
【发布时间】:2012-12-07 17:54:15
【问题描述】:

我会从我想要的开始,然后从那里开始:

+------------------------------------------+
|[] jCheckBox                       jLabel |
+------------------------------------------+

基本上我想要一个JCheckBox,其中包含 2 个文本段,1 个左对齐和 1 个右对齐。我希望整个框都是可点击的,并且完全像JCheckBox(就像我按下鼠标一样,它会突出显示框等)。

现在我已经试过了:

  • 在文本框内使用 HTML,表格如下:<html><table width=100%><tr width=100%><td>Left Text</td><td align=right>Right Text</td></tr></table>。这会产生 [] Left TextRightText 没有任何视觉对齐。

  • JCheckBoxJLabel 添加到面板中,但这需要我实现所有鼠标事件并在JCheckBox 上调用正确的相应方法。我把它放在一边 - 但是我愿意重新考虑这是否是唯一的选择

  • 将 JLabel 添加到 JCheckBox

    • 首先,这导致 JCheckBox 决定更改字体,因此必须“调整”
    • 其次,基线偏离了 1 或 2 个像素,此问题已通过实施将 JLabel 放置在基线上的 LayoutManager 得到解决。
    • 第三,JLabelJCheckBox 文本重叠,所以我调整我的布局管理器,但是 JCheckBox 没有从 getPreferedSize()[1,1])给出正确的结果。

所以,基本上我的问题是:我应该如何实现这个?

【问题讨论】:

  • 那么,如果我理解正确的话,您希望这个复合面板的行为与里面的复选框完全一样,对吧?
  • 是的,基本上是这样

标签: java swing jcheckbox


【解决方案1】:
  • 创建父JLabelJLabel还没有实现任何LayoutManager,然后设置正确的LayoutManager,我认为GridLayout(with 2 segments of text, 1 left aligned and 1 right aligned

  • 添加两个 JLabels 并正确对齐 (JLabel.setHorizontalAlignment(javax.swing.SwingConstants.XXX);)

  • JCheckBox 与父 JLabel (JLabel.setLabelFor(JCheckBox);) 放在一起

  • MultiIcon in the JLabel 的方式相同

【讨论】:

    【解决方案2】:
    public class LeesCheckbox extends JPanel 
    {
        private JCheckBox checkbox;
    
        public LeesCheckbox(String leftText, String rightText){
            super(new BorderLayout());
            checkbox = new JCheckBox(leftText);
            add(checkbox, BorderLayout.WEST);
            add(new JLabel(rightText), BorderLayout.EAST);
            setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    checkbox.setSelected(!checkbox.isSelected());
                }
            });
        }
    
        public JCheckBox getCheckbox() {
            return checkbox;
        }
    
        public static void main(String[] args) {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            Box content = new Box(BoxLayout.Y_AXIS);
            content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            LeesCheckbox box = new LeesCheckbox("Left text", "Right text");
            box.setMaximumSize(new Dimension(Integer.MAX_VALUE, 25));
            content.add(box);
            content.add(Box.createVerticalGlue());
    
            frame.setContentPane(content);
            frame.setSize(300, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      这就是我设法使用 JCheckBox 作为父类来实现它的方法。这是缺少设置标签文本和颜色的方法。

      package mock.dlect;
      
      import java.awt.Component;
      import java.awt.Container;
      import java.awt.Dimension;
      import java.awt.Font;
      import java.awt.LayoutManager;
      import javax.swing.Icon;
      import javax.swing.JCheckBox;
      import javax.swing.JLabel;
      
      public class LeftRightCheck extends JCheckBox {
      
          private final static JCheckBox DEFAULT_CHECK_BOX = new JCheckBox();
          private final JLabel rightLabel;
      
          public LeftRightCheck(String leftText, String rightText, Icon icon,
                  boolean selected) {
              super(leftText, icon, selected);
              rightLabel = new JLabel(rightText, TRAILING);
              // TODO figure out how to make the font work right on OSX
              this.setLayout(new BaseLineSingleElementLayoutManager(10));
              this.add(rightLabel);
          }
      
          @Override
          public final void setFont(Font font) {
              font = font.deriveFont(DEFAULT_CHECK_BOX.getFont().getSize2D());
              super.setFont(font);
              if (rightLabel != null) {
                  rightLabel.setFont(font);
              }
          }
      
          private class BaseLineSingleElementLayoutManager implements LayoutManager {
      
              private int hgap;
              private Component component;
      
              public BaseLineSingleElementLayoutManager(int hgap) {
                  this.hgap = hgap;
              }
      
              @Override
              public void addLayoutComponent(String name, Component comp) {
                  // Do Nothing
              }
      
              @Override
              public void removeLayoutComponent(Component comp) {
                  // Do Nothing
              }
      
              @Override
              public Dimension preferredLayoutSize(Container parent) {
                  if (parent != null && parent instanceof JCheckBox) {
                      JCheckBox cc = (JCheckBox) parent;
                      // These 2 lines will add the size of the checkbox to the
                      // preferred size
                      Dimension parentSize = DEFAULT_CHECK_BOX.getPreferredSize();
                      parentSize.width += cc.getFontMetrics(cc.getFont()).
                              stringWidth(cc.getText()) + hgap;
                      if (checkComponent(cc)) {
                          Dimension childSize = this.component.getPreferredSize();
                          parentSize.height = Math.max(parentSize.height,
                                  childSize.height);
                          parentSize.width += childSize.width;
                      }
                      return parentSize;
                  }
                  return new Dimension();
              }
      
              @Override
              public Dimension minimumLayoutSize(Container parent) {
                  return preferredLayoutSize(parent);
              }
      
              @Override
              public void layoutContainer(Container parent) {
                  if (!checkComponent(parent)) {
                      return;
                  }
                  this.component.setSize(parent.getSize());
                  this.component.setLocation(0, getBaseline(parent)
                          - getBaseline(this.component));
              }
      
              private int getBaseline(Component c) {
                  return c.getBaseline(c.getWidth(), c.getHeight());
              }
      
              protected boolean checkComponent(Container parent) {
                  if (parent == null) {
                      return false;
                  } else if (parent.getComponentCount() >= 1
                          && parent.getComponent(0).isVisible()) {
                      this.component = parent.getComponent(0);
                      return true;
                  } else {
                      return false;
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-15
        • 1970-01-01
        • 1970-01-01
        • 2011-11-09
        • 2010-10-18
        • 1970-01-01
        • 2021-08-25
        相关资源
        最近更新 更多