TITLE:JButtonを半透明にする
#navi(../)
RIGHT:Posted by &author(aterai); at 2012-12-31
*JButtonを半透明にする [#v7bccd63]
半透明な``JButton``を作成します。

-&jnlp;
-&jar;
-&zip;

//#screenshot
#ref(https://lh3.googleusercontent.com/-W5o-8ilpY6k/UOCzLo2oOeI/AAAAAAAABZ0/m1_AjYpKqiY/s800/TranslucentButton.png)

**サンプルコード [#r4eab624]
#code(link){{
class TranslucentButton extends JButton{
  private static final Color TL = new Color(1f,1f,1f,.2f);
  private static final Color BR = new Color(0f,0f,0f,.4f);
  private static final Color ST = new Color(1f,1f,1f,.2f);
  private static final Color SB = new Color(1f,1f,1f,.1f);
  private Color ssc;
  private Color bgc;
  private int r = 8;
  public TranslucentButton(String text) {
    super(text);
  }
  public TranslucentButton(String text, Icon icon) {
    super(text, icon);
  }
  @Override public void updateUI() {
    super.updateUI();
    setContentAreaFilled(false);
    setFocusPainted(false);
    setOpaque(false);
    setForeground(Color.WHITE);
  }
  @Override protected void paintComponent(Graphics g) {
    int x = 0;
    int y = 0;
    int w = getWidth();
    int h = getHeight();
    Graphics2D g2 = (Graphics2D)g.create();
    g2.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING,
      RenderingHints.VALUE_ANTIALIAS_ON);
    Shape area = new RoundRectangle2D.Float(x, y, w-1, h-1, r, r);
    ssc = TL;
    bgc = BR;
    ButtonModel m = getModel();
    if(m.isPressed()) {
      ssc = SB;
      bgc = ST;
    }else if(m.isRollover()) {
      ssc = ST;
      bgc = SB;
    }
    g2.setPaint(new GradientPaint(x, y, ssc, x, y+h, bgc, true));
    g2.fill(area);
    g2.setPaint(BR);
    g2.draw(area);
    g2.dispose();
    super.paintComponent(g);
  }
}
}}

**解説 [#kc10b7de]
- 透明な``JButton``、全体を半透明な``Icon``、タイトルの``Icon``と文字列は``align='middle'``などを指定して配置
-- 参考: [[JRadioButtonを使ってToggleButtonBarを作成>Swing/ToggleButtonBar]]
-- ``setOpaque(false);``, ``setContentAreaFilled(false);``などで、``JButton``自体は透明化
-- タイトル``Icon``と文字列の``align``が、``top``、``middle``、``bottom``のどれにしてもきれいに揃わない
-- サイズが固定
-- ``MetalLookAndFeel``に変更しても、余計なフチ?が表示されない
-- ``Html``を使っているので``GTKLookAndFeel``で、``Pressed``時の文字色変更に対応していない

#code{{
private static String makeTitleWithIcon(URL u, String t, String a) {
  return String.format(
    "<html><p align='%s'><img src='%s' align='%s' />&nbsp;%s", a, u, a, t);
}
private static AbstractButton makeButton(String title) {
  return new JButton(title) {
    @Override public void updateUI() {
      super.updateUI();
      setVerticalAlignment(SwingConstants.CENTER);
      setVerticalTextPosition(SwingConstants.CENTER);
      setHorizontalAlignment(SwingConstants.CENTER);
      setHorizontalTextPosition(SwingConstants.CENTER);
      setBorder(BorderFactory.createEmptyBorder());
      //setBorderPainted(false);
      setContentAreaFilled(false);
      setFocusPainted(false);
      setOpaque(false);
      setForeground(Color.WHITE);
      setIcon(new TranslucentButtonIcon());
    }
  };
}
}}

- 透明な``JButton``、全体を半透明な``Icon``、タイトルの``Icon``と文字列は``JLabel``を``OverlayLayout``で配置
-- ``Html``の``align``ではなく、``Baseline``の揃ったJLabelを半透明なJButtonに重ねて表示
-- ``JButton``のテキストは空なので、``GTKLookAndFeel``で、``Pressed``時の文字色変更に対応していない

#code{{
JLabel label = new JLabel("JLabel", icon, SwingConstants.CENTER);
label.setForeground(Color.WHITE);
label.setAlignmentX(.5f);
b = makeButton("");
b.setAlignmentX(.5f);
JPanel p = new JPanel();
p.setLayout(new OverlayLayout(p));
p.setOpaque(false);
p.add(label);
p.add(b);
add(p);
}}

- 半透明な``JButton``
-- ``setOpaque(false);``, ``setContentAreaFilled(false);``などを設定して``JButton``は透明にし、``JButton#paintComponent(...)``をオーバーライドして半透明の影などを描画
-- ``MetalLookAndFeel``で、余計なフチ?が表示される

**参考リンク [#b8a76b5c]
- [[JRadioButtonを使ってToggleButtonBarを作成>Swing/ToggleButtonBar]]
- [http://chrfb.deviantart.com/art/quot-ecqlipse-2-quot-PNG-59941546 "ecqlipse 2" PNG by ~chrfb on deviantART]

**コメント [#c2b45262]
#comment