如何使用透明背景和常规文本制作JButton?

时间:2014-05-10 13:11:28

标签: java swing jbutton transparency

有没有办法让JButton具有透明填充(30%透明)和不透明的文字?

现在我发现了以下选项:

  1. 使按钮和文本都透明。
  2. 使两者都不透明。
  3. 中间是否有选项?

1 个答案:

答案 0 :(得分:4)

以下是使用JButton#setIcon(Icon_30%_transparent)

的一种可能的实现方式

enter image description here

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

public final class TranslucentButtonIconTest {
  private static final TexturePaint TEXTURE = makeCheckerTexture();
  public JComponent makeUI() {
    JPanel p = new JPanel() {
      @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setPaint(TEXTURE);
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.dispose();
      }
    };
    p.add(makeButton("aaa"));
    p.add(makeButton("bbbbbbb"));
    p.add(makeButton("ccccccccccc"));
    p.add(makeButton("ddddddddddddddddddddddddddddd"));
    return p;
  }
  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(2, 8, 2, 8));
        setMargin(new Insets(2, 8, 2, 8));
        setContentAreaFilled(false);
        setFocusPainted(false);
        setOpaque(false);
        setForeground(Color.WHITE);
        setIcon(new TranslucentButtonIcon());
      }
    };
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new TranslucentButtonIconTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
  private static TexturePaint makeCheckerTexture() {
    int cs = 6;
    int sz = cs * cs;
    BufferedImage img = new BufferedImage(sz, sz, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2 = img.createGraphics();
    g2.setPaint(new Color(120, 120, 220));
    g2.fillRect(0, 0, sz, sz);
    g2.setPaint(new Color(200, 200, 200, 20));
    for (int i = 0; i * cs < sz; i++) {
      for (int j = 0; j * cs < sz; j++) {
        if ((i + j) % 2 == 0) {
          g2.fillRect(i * cs, j * cs, cs, cs);
        }
      }
    }
    g2.dispose();
    return new TexturePaint(img, new Rectangle(0, 0, sz, sz));
  }
}

class TranslucentButtonIcon implements Icon {
  private static final int R = 8;
  private int width;
  private int height;
  @Override public void paintIcon(Component c, Graphics g, int x, int y) {
    if (c instanceof AbstractButton) {
      AbstractButton b = (AbstractButton) c;
      Insets i = b.getMargin();
      int w = c.getWidth();
      int h = c.getHeight();
      width  = w - i.left - i.right;
      height = h - i.top - i.bottom;
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);
      Shape area = new RoundRectangle2D.Float(x - i.left, y - i.top, w - 1, h - 1, R, R);
      Color color = new Color(0f, 0f, 0f, .3f);
      ButtonModel m = b.getModel();
      if (m.isPressed()) {
        color = new Color(0f, 0f, 0f, .3f);
      } else if (m.isRollover()) {
        color = new Color(1f, 1f, 1f, .3f);
      }
      g2.setPaint(color);
      g2.fill(area);
      g2.setPaint(Color.WHITE);
      g2.draw(area);
      g2.dispose();
    }
  }
  @Override public int getIconWidth()  {
    return Math.max(width, 100);
  }
  @Override public int getIconHeight() {
    return Math.max(height, 24);
  }
}