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

有没有办法制作一个具有透明填充(30%透明)和不透明文本的JButton

现在我发现了以下选项:

  1. 使按钮和文本都透明。
  2. 使它们都不透明。

两者之间有选择吗?

这是使用JButton#setIcon(Icon_30%_transparent)一种可能的实现:

在此处输入图像描述

 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); } }