如何在JPanel中制作半透明的内容?

关于JPanel中组件的显示我很困惑。

假设我创建了一个半透明度为0.8f的自定义JPanel,如下所示: –

JPanel panel=new JPanel(){ @Override public void paint(Graphics g) { super.paint(g); BufferedImage img=(BufferedImage)createImage(getWidth(),getHeight()); Graphics2D g2=(Graphics2D) g.create(); g2.setComposite(AlphaComposite.SrcOver.derive(0.8f)); g2.drawImage(img,0,0,null); } @Override public Dimension getPreferredSize() { return new Dimension(300,300); } }; 

现在我将其设置为框架的contentPane。

 frame.setContentPane(panel); 

现在我添加一些按钮。

  frame.add(new JButton("Click Here")); frame.add(new JButton("Click Here")); frame.add(new JButton("Click Here")); frame.add(new JButton("Click Here")); 

1)然后在输出中我为什么会得到半透明按钮?由于JPanel是单层的,当我覆盖它的paint方法然后添加按钮时我首先绘制半透明图像,按钮不能是半透明的,因为它们应该越过它。

2)同样在这4个按钮中只有2个是半透明的。为什么会有这样的偏袒?

3)如果我在添加这4个按钮之前还添加了一个表,那么一切都变得半透明。为什么?

 Object[] names = new Object[] { "Title", "Artist", "Album" }; String[][] data = new String[][] { { "Los Angeles", "Sugarcult", "Lights Out" }, { "Do It Alone", "Sugarcult", "Lights Out" }, { "Made a Mistake", "Sugarcult", "Lights Out" }, { "Kiss You Better", "Maximo Park", "A Certain Trigger" }, { "All Over the Shop", "Maximo Park", "A Certain Trigger" }, { "Going Missing", "Maximo Park", "A Certain Trigger" } }; JTable table = new JTable(data, names); frame.add(table); 

4)如果我对JPanel使用paintComponent(Graphics g) ,那么没有什么是半透明的,无论我是否添加表格或添加了多少个按钮。为什么?

(我在询问应用程序运行时的立即输出。我知道当鼠标滚过这些按钮或者如果单击表中的任何行时,它将变为不透明,这是由于Swing的绘制机制。)

1)然后在输出中为什么我得到半透明按钮? 由于JPanel是单层的,当我覆盖其绘制方法然后添加按钮时,我首先绘制半透明图像,按钮不能是半透明的,因为它们应该越过它。

实际上,你在按钮上绘制了半透明效果。 paint电话

  • paintComponent
  • paintBorder
  • paintChildren

然后你在已经画过的画面(孩子们)的顶部涂上半透明效果。 添加组件时没有任何区别,Swing会在多种情况下绘制组件,第一次是在组件首次实现时(在屏幕上显示)并响应脏区域的更改(和批次)其他人)…不要欺骗自己,你无法控制自己……

将涂料工艺视为分层方法。 首先你绘制背景,然后你画中间地面,然后最后,前面的地面,然后你去了,泼了…

在此处输入图像描述

 public class TestTranslucentControls { public static void main(String[] args) { new TestTranslucentControls(); } public TestTranslucentControls() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private BufferedImage background; public TestPane() { setLayout(new GridBagLayout()); try { background = ImageIO.read(new File("C:/Users/shane/Dropbox/MegaTokyo/poster.jpg")); } catch (IOException ex) { ex.printStackTrace(); } add(new JButton("1")); add(new JButton("2")); add(new JButton("3")); add(new JButton("4")); add(new JButton("5")); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (background != null) { Graphics2D g2 = (Graphics2D) g.create(); g2.setComposite(AlphaComposite.SrcOver.derive(0.25f)); int x = (getWidth() - background.getWidth()) / 2; int y = (getHeight() - background.getHeight()) / 2; g2.drawImage(background, x, y, this); g2.dispose(); } } @Override public Dimension getPreferredSize() { return background == null ? new Dimension(300, 300) : new Dimension(background.getWidth(), background.getHeight()); } } } 

我想你可能会发现……

  • 执行自定义绘画
  • 在AWT和Swing中绘画

有用;)

通常,您希望覆盖paintComponent()而不是paint() 。 这可能是导致透明度问题的原因。 其次,您可能想要更改布局。 默认情况下,面板使用FlowLayout。 您可能想要使用BorderLayout或GridBagLayout或两者的混合。