以图形方式连接/链接按钮?

时间:2016-01-14 05:21:08

标签: java swing jbutton

简单的问题是,有没有办法创建一种“按钮组”(不,不是this),其中两个或多个按钮连接在一起。例如,如果你看看JTabbedPanes,你可以在Mac系统上看到它:

tab buttons

这正是我想要的一组按钮。将两个或多个按钮推到一起(如this post中所示)不起作用,因为边框布局冲突并且也不均匀:

buttons pushed together

我一直在寻找这样的事情,但我找不到任何东西。现在,我明白我可以从头开始创建一个全新的组件,但我想知道是否有更好的方法来实现这一点。

我尝试使用JTabbedPanes,但这些“标签”不是传统意义上的按钮,可以为您提供全部功能。它们受到严格限制,此外整体JTabbedPane不是一个可行的跨平台工具,因为我只想要mac显示的外观。

这有什么解决方案吗?

1 个答案:

答案 0 :(得分:2)

正如@MadProgrammer所说,这是一个使用JPanelFlowLayout添加一堆关闭按钮的示例:

screenshot

import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;

public class StickButtonsTest {
  private JComponent makeUI() {
    JPanel p = new JPanel();
    p.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 5));
    p.add(makeToggleButtonBar());
    return p;
  }
  private static AbstractButton makeButton(String title) {
    AbstractButton b = new JToggleButton(title) {
      @Override protected void fireStateChanged() {
        ButtonModel model = getModel();
        if (model.isSelected()) {
          setForeground(Color.ORANGE.brighter());
        } else {
          setForeground(Color.WHITE);
        }
        super.fireStateChanged();
      }
    };
    b.setHorizontalTextPosition(SwingConstants.CENTER);
    b.setBorder(BorderFactory.createEmptyBorder());
    b.setContentAreaFilled(false);
    b.setFocusPainted(false);
    b.setForeground(Color.WHITE);
    b.setBackground(new Color(0x00AEF3));
    b.setIcon(new ToggleButtonBarCellIcon());
    return b;
  }
  private static JPanel makeToggleButtonBar() {
    ButtonGroup bg = new ButtonGroup();
    JPanel p = new JPanel(new GridLayout(1, 0, 0, 0));
    for (AbstractButton b: Arrays.asList(
        makeButton("left"), makeButton("c1"),
        makeButton("c2"), makeButton("right"))) {
      bg.add(b);
      p.add(b);
    }
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new StickButtonsTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
  public static void createAndShowGUI() {
  }
}

//http://ateraimemo.com/Swing/ToggleButtonBar.html
class ToggleButtonBarCellIcon implements Icon {
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    Container parent = c.getParent();
    if (!(parent instanceof JPanel)) {
      return;
    }
    int gap = 3;
    int r = 8;
    int w = c.getWidth();
    int h = c.getHeight() - 1;

    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    Path2D.Float p = new Path2D.Float();

    if (c == parent.getComponent(0)) {
      //:first-child
      p.moveTo(x, y + r);
      p.quadTo(x, y, x + r, y);
      p.lineTo(x + w, y);
      p.lineTo(x + w, y + h);
      p.lineTo(x + r, y + h);
      p.quadTo(x, y + h, x, y + h - r);
    } else if (c == parent.getComponent(parent.getComponentCount() - 1)) {
      //:last-child
      w--;
      p.moveTo(x, y);
      p.lineTo(x + w - r, y);
      p.quadTo(x + w, y, x + w, y + r);
      p.lineTo(x + w, y + h - r);
      p.quadTo(x + w, y + h, x + w - r, y + h);
      p.lineTo(x, y + h);
      p.moveTo(x, y + gap);
      p.lineTo(x, y + h - gap);
    } else {
      p.moveTo(x, y);
      p.lineTo(x + w, y);
      p.lineTo(x + w, y + h);
      p.lineTo(x, y + h);
      p.moveTo(x, y + gap);
      p.lineTo(x, y + h - gap);
    }
    p.closePath();

    Color ssc = new Color(1f, 1f, 1f, .2f);
    Color bgc = new Color(0f, 0f, 0f, .2f);
    if (c instanceof AbstractButton) {
      ButtonModel m = ((AbstractButton) c).getModel();
      if (m.isSelected() || m.isRollover()) {
        ssc = new Color(1f, 1f, 1f, .4f);
        bgc = new Color(1f, 1f, 1f, .1f);
      }
    }

    Area area = new Area(p);
    g2.setPaint(c.getBackground());
    g2.fill(area);
    g2.setPaint(new GradientPaint(x, y, ssc, x, y + h, bgc, true));
    g2.fill(area);
    g2.setPaint(new Color(0f, 0f, 0f, .5f));
    g2.draw(p);

    g2.dispose();
  }
  @Override public int getIconWidth() {
    return 60;
  }
  @Override public int getIconHeight() {
    return 24;
  }
}