使用标题作为JCheckBox创建标题边框

时间:2011-11-10 08:38:45

标签: java swing

我想创建一个标题边框,标题为CheckBox。

this is a kind of border i am looking for

我该怎么做?

4 个答案:

答案 0 :(得分:9)

本教程正是您所需要的:CLICK

不幸的是,图片不再在线,但您可以启动Webstart应用程序。

答案 1 :(得分:2)

感谢JavaLobby和Stephan提供此答案的基础。

但是,这是一个简单的示例,它提供了TitledBorder的简单实现JCheckBox

public class CheckBoxTitledBorder extends AbstractBorder {

  private final TitledBorder _parent;
  private final JCheckBox _checkBox;

  public CheckBoxTitledBorder(String title, boolean selected) {
    _parent = BorderFactory.createTitledBorder(title);
    _checkBox = new JCheckBox(title, selected);
    _checkBox.setHorizontalTextPosition(SwingConstants.LEFT);
  }

  public boolean isSelected() {
    return _checkBox.isSelected();
  }

  public void addActionListener(ActionListener listener) {
    _checkBox.addActionListener(listener);
  }

  @Override
  public boolean isBorderOpaque() {
    return true;
  }

  @Override
  public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Insets borderInsets = _parent.getBorderInsets(c);
    Insets insets = getBorderInsets(c);
    int temp = (insets.top - borderInsets.top) / 2;
    _parent.paintBorder(c, g, x, y + temp, width, height - temp);
    Dimension size = _checkBox.getPreferredSize();
    final Rectangle rectangle = new Rectangle(5, 0, size.width, size.height);

    final Container container = (Container) c;
    container.addMouseListener(new MouseAdapter() {
      private void dispatchEvent(MouseEvent me) {
        if (rectangle.contains(me.getX(), me.getY())) {
          Point pt = me.getPoint();
          pt.translate(-5, 0);
          _checkBox.setBounds(rectangle);
          _checkBox.dispatchEvent(new MouseEvent(_checkBox, me.getID(),
            me.getWhen(), me.getModifiers(), pt.x, pt.y, me.getClickCount(), me.isPopupTrigger(), me.getButton()));
          if (!_checkBox.isValid()) {
            container.repaint();
          }
        }
      }

      public void mousePressed(MouseEvent me) {
        dispatchEvent(me);
      }

      public void mouseReleased(MouseEvent me) {
        dispatchEvent(me);
      }
    });
    SwingUtilities.paintComponent(g, _checkBox, container, rectangle);
  }

  @Override
  public Insets getBorderInsets(Component c) {
    Insets insets = _parent.getBorderInsets(c);
    insets.top = Math.max(insets.top, _checkBox.getPreferredSize().height);
    return insets;
  }
}

答案 2 :(得分:0)

我还找到了this example

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

/**
 * @version 1.0 08/12/99
 */
public class CompTitledPaneExample2 extends JFrame {

    public CompTitledPaneExample2() {
        super("CompTitledPaneExample2");
        JCheckBox title = new JCheckBox("Title");
        title.setSelected(true);
        final CompTitledPane p1 = new CompTitledPane(title);
        title.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                p1.setEnabled(e.getStateChange() == ItemEvent.SELECTED);
            }
        });
        APanel p2 = new APanel();
        p1.setTransmittingAllowed(true);
        p1.setTransmitter(p2);
        p1.getContentPane().add(p2);
        getContentPane().add(p1, BorderLayout.CENTER);
    }

    class APanel extends JPanel implements StateTransmitter {

        JButton button;

        JTextField textField;

        APanel() {
            button = new JButton("abc");
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Ouch!");
                }
            });
            textField = new JTextField(10);
            textField.setText("text");
            add(button, BorderLayout.NORTH);
            add(textField, BorderLayout.SOUTH);
        }

        public void setChildrenEnabled(boolean enable) {
            button.setEnabled(enable);
            textField.setEnabled(enable);
        }
    }

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (Exception evt) {
        }

        CompTitledPaneExample2 frame = new CompTitledPaneExample2();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.setSize(280, 110);
        frame.setVisible(true);
    }
}

class CompTitledPane extends JPanel {

    protected CompTitledBorder border;

    protected JComponent component;

    protected JPanel panel;

    protected boolean transmittingAllowed;

    protected StateTransmitter transmitter;

    public CompTitledPane() {
        this(new JLabel("Title"));
    // debug
        // JLabel label = (JLabel)getTitleComponent();
        // label.setOpaque(true);
        // label.setBackground(Color.yellow);
    }

    public CompTitledPane(JComponent component) {
        this.component = component;
        border = new CompTitledBorder(component);
        setBorder(border);
        panel = new JPanel();
        setLayout(null);
        add(component);
        add(panel);
        transmittingAllowed = false;
        transmitter = null;
    }

    public JComponent getTitleComponent() {
        return component;
    }

    public void setTitleComponent(JComponent newComponent) {
        remove(component);
        add(newComponent);
        border.setTitleComponent(newComponent);
        component = newComponent;
    }

    public JPanel getContentPane() {
        return panel;
    }

    public void doLayout() {
        Insets insets = getInsets();
        Rectangle rect = getBounds();
        rect.x = 0;
        rect.y = 0;

        Rectangle compR = border.getComponentRect(rect, insets);
        component.setBounds(compR);
        rect.x += insets.left;
        rect.y += insets.top;
        rect.width -= insets.left + insets.right;
        rect.height -= insets.top + insets.bottom;
        panel.setBounds(rect);
    }

    public void setTransmittingAllowed(boolean enable) {
        transmittingAllowed = enable;
    }

    public boolean getTransmittingAllowed() {
        return transmittingAllowed;
    }

    public void setTransmitter(StateTransmitter transmitter) {
        this.transmitter = transmitter;
    }

    public StateTransmitter getTransmitter() {
        return transmitter;
    }

    public void setEnabled(boolean enable) {
        super.setEnabled(enable);
        if (transmittingAllowed && transmitter != null) {
            transmitter.setChildrenEnabled(enable);
        }
    }

}

interface StateTransmitter {

    public void setChildrenEnabled(boolean enable);

}

class CompTitledBorder extends TitledBorder {

    protected JComponent component;

    public CompTitledBorder(JComponent component) {
        this(null, component, LEFT, TOP);
    }

    public CompTitledBorder(Border border) {
        this(border, null, LEFT, TOP);
    }

    public CompTitledBorder(Border border, JComponent component) {
        this(border, component, LEFT, TOP);
    }

    public CompTitledBorder(Border border, JComponent component,
            int titleJustification, int titlePosition) {
        super(border, null, titleJustification, titlePosition, null, null);
        this.component = component;
        if (border == null) {
            this.border = super.getBorder();
        }
    }

    public void paintBorder(Component c, Graphics g, int x, int y, int width,
            int height) {
        Rectangle borderR = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,
                width - (EDGE_SPACING * 2), height - (EDGE_SPACING * 2));
        Insets borderInsets;
        if (border != null) {
            borderInsets = border.getBorderInsets(c);
        } else {
            borderInsets = new Insets(0, 0, 0, 0);
        }

        Rectangle rect = new Rectangle(x, y, width, height);
        Insets insets = getBorderInsets(c);
        Rectangle compR = getComponentRect(rect, insets);
        int diff;
        switch (titlePosition) {
            case ABOVE_TOP:
                diff = compR.height + TEXT_SPACING;
                borderR.y += diff;
                borderR.height -= diff;
                break;
            case TOP:
            case DEFAULT_POSITION:
                diff = insets.top / 2 - borderInsets.top - EDGE_SPACING;
                borderR.y += diff;
                borderR.height -= diff;
                break;
            case BELOW_TOP:
            case ABOVE_BOTTOM:
                break;
            case BOTTOM:
                diff = insets.bottom / 2 - borderInsets.bottom - EDGE_SPACING;
                borderR.height -= diff;
                break;
            case BELOW_BOTTOM:
                diff = compR.height + TEXT_SPACING;
                borderR.height -= diff;
                break;
        }
        border.paintBorder(c, g, borderR.x, borderR.y, borderR.width,
                borderR.height);
        Color col = g.getColor();
        g.setColor(c.getBackground());
        g.fillRect(compR.x, compR.y, compR.width, compR.height);
        g.setColor(col);
        component.repaint();
    }

    public Insets getBorderInsets(Component c, Insets insets) {
        Insets borderInsets;
        if (border != null) {
            borderInsets = border.getBorderInsets(c);
        } else {
            borderInsets = new Insets(0, 0, 0, 0);
        }
        insets.top = EDGE_SPACING + TEXT_SPACING + borderInsets.top;
        insets.right = EDGE_SPACING + TEXT_SPACING + borderInsets.right;
        insets.bottom = EDGE_SPACING + TEXT_SPACING + borderInsets.bottom;
        insets.left = EDGE_SPACING + TEXT_SPACING + borderInsets.left;

        if (c == null || component == null) {
            return insets;
        }

        int compHeight = 0;
        if (component != null) {
            compHeight = component.getPreferredSize().height;
        }

        switch (titlePosition) {
            case ABOVE_TOP:
                insets.top += compHeight + TEXT_SPACING;
                break;
            case TOP:
            case DEFAULT_POSITION:
                insets.top += Math.max(compHeight, borderInsets.top)
                        - borderInsets.top;
                break;
            case BELOW_TOP:
                insets.top += compHeight + TEXT_SPACING;
                break;
            case ABOVE_BOTTOM:
                insets.bottom += compHeight + TEXT_SPACING;
                break;
            case BOTTOM:
                insets.bottom += Math.max(compHeight, borderInsets.bottom)
                        - borderInsets.bottom;
                break;
            case BELOW_BOTTOM:
                insets.bottom += compHeight + TEXT_SPACING;
                break;
        }
        return insets;
    }

    public JComponent getTitleComponent() {
        return component;
    }

    public void setTitleComponent(JComponent component) {
        this.component = component;
    }

    public Rectangle getComponentRect(Rectangle rect, Insets borderInsets) {
        Dimension compD = component.getPreferredSize();
        Rectangle compR = new Rectangle(0, 0, compD.width, compD.height);
        switch (titlePosition) {
            case ABOVE_TOP:
                compR.y = EDGE_SPACING;
                break;
            case TOP:
            case DEFAULT_POSITION:
                compR.y = EDGE_SPACING
                        + (borderInsets.top - EDGE_SPACING - TEXT_SPACING - compD.height)
                        / 2;
                break;
            case BELOW_TOP:
                compR.y = borderInsets.top - compD.height - TEXT_SPACING;
                break;
            case ABOVE_BOTTOM:
                compR.y = rect.height - borderInsets.bottom + TEXT_SPACING;
                break;
            case BOTTOM:
                compR.y = rect.height
                        - borderInsets.bottom
                        + TEXT_SPACING
                        + (borderInsets.bottom - EDGE_SPACING - TEXT_SPACING - compD.height)
                        / 2;
                break;
            case BELOW_BOTTOM:
                compR.y = rect.height - compD.height - EDGE_SPACING;
                break;
        }
        switch (titleJustification) {
            case LEFT:
            case DEFAULT_JUSTIFICATION:
                compR.x = TEXT_INSET_H + borderInsets.left;
                break;
            case RIGHT:
                compR.x = rect.width - borderInsets.right - TEXT_INSET_H
                        - compR.width;
                break;
            case CENTER:
                compR.x = (rect.width - compR.width) / 2;
                break;
        }
        return compR;
    }

}

答案 3 :(得分:0)

一个简单的解决方案就是让你的复选框与标题边框重叠在另一个面板上,标题文字只是“”。

例如,您可以通过将边界JPanel和JCheckBox放在同一个GridBagLayout单元格中来实现此目的。只需确保首先添加复选框,并为其提供与边界JPanel不同的GridBagConstraints Insets,以便它排成一行。

我将标题文字设置为“”,以便它自动调整内容和内容以便为标题腾出空间,但您可以轻松地使用不同的边框并自行调整大小。