AlphaComposite透明度与重绘重叠为黑色

所以我在另一个面板上有一个图像,该图像是透明的,因此您可以看到它下面的面板。 我要做的是使用repaint()淡化图像(使用java.awt.Graphics中的drawImage()方法绘制),直到它完全透明,这样你就可以清楚地看到它下面的面板。 截至目前,图像只是淡入黑色而不是透明纹理。

这是我现在的一些代码:

paintComponent方法:

public void paintComponent(Graphics g) { super.paintComponent(g); float alpha = 1f-(.01f*(float)opcounter); Graphics2D g2d = (Graphics2D)g; g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha); g2d.drawImage(img, 0, 0, null); } 

为定时器调用的actionPerformed方法

 public void actionPerformed(ActionEvent e) { opcouner++; panel.repaint(); } 

我的代码的更长(无凝聚)版本:(包括用于计时器的paintComponent和Mover类)

  public void paintComponent(Graphics g) { super.paintComponent(g); Dimension framesize = frame.getSize(); this.setBounds(0,0,framesize.width, framesize.height-61); if (buff) { //this.add(buffer); if (opcounter <= 255) { buffer.setForeground(new Color(250, 250, 250, 0+opcounter)); } else { opcounter = 0; buff = false; hand = true; } } if (hand) { this.add(handson); if (opcounter <= 255) { handson.setForeground(new Color(250, 250, 250, 0+opcounter)); } else { opcounter = 0; hand = false; log = true; } } if (log) { this.add(logic); if (opcounter <= 255) { logic.setForeground(new Color(250, 250, 250, 0+opcounter)); } else { opcounter = 0; log = false; pan = true; } } if (pan) { this.add(panic); if (opcounter <= 255) { panic.setForeground(new Color(250, 250, 250, 0+opcounter)); } else { opcounter = 0; pan = false; first = false; second = true; try { //Thread.sleep(2000); } catch(Exception e) { System.out.println("thread not slept"); } System.out.println("opcounter = " + opcounter); black.setVisible(false); handson.setVisible(false); logic.setVisible(false); panic.setVisible(false); tutpic = true; } } if (tutpic) { if (opcounter <= 200) { Graphics2D g2d = (Graphics2D)g.create(); float alpha = 1f-(.01f*(float)opcounter); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha)); g2d.drawImage(tut, 0, 0, null); g2d.dispose(); } else { opcounter = 0; tutpic = false; } } } class Mover implements ActionListener { public void actionPerformed(ActionEvent e) { if (!tutpic) opcounter+=4; else { opcounter++; } tutorial.repaint(); } } 

任何帮助,将不胜感激。 谢谢!

您需要在paintComponent方法存在之前恢复Graphics上下文的状态。 这非常重要,因为Graphics上下文是一个共享资源,所有需要更新的组件都将被赋予相同的Graphics ,所以现在组件绘制后的每个东西都将共享一些AlphaComposite ……

更好的解决方案是创建Graphics上下文的临时副本,应用您想要的任何设置并在完成后处理它。 这将确保在方法存在后不会对Graphics上下文所做的更改进行…

 public void paintComponent(Graphics g) { super.paintComponent(g); float alpha = 1f-(.01f*(float)opcounter); // Create your own copy... Graphics2D g2d = (Graphics2D)g.create(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha); g2d.drawImage(img, 0, 0, null); // Don't forget to dispose of it g2d.dispose(); } 

记住,你创造它,你处置它!

更新

尝试使用AlphaComposite.SRC_OVER代替……

在此处输入图像描述

 import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class TestFadeOut { public static void main(String[] args) { new TestFadeOut(); } public TestFadeOut() { EventQueue.invokeLater( new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); 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 float alpha = 1f; private float diff = -0.02f; private BufferedImage img; public TestPane() { try { img = ImageIO.read(new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\Ponies\\url.png")); Timer timer = new Timer(40, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { alpha += diff; if (alpha < 0) { diff *= -1; alpha = diff; } else if (alpha > 1f) { diff *= -1; alpha = 1f + diff; } repaint(); } }); timer.setRepeats(true); timer.setCoalesce(true); timer.start(); } catch (IOException ex) { ex.printStackTrace(); } } @Override public Dimension getPreferredSize() { return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (img != null) { Graphics2D g2d = (Graphics2D) g.create(); g2d.setComposite(AlphaComposite.SrcOver.derive(alpha)); int x = getWidth() - img.getWidth(); int y = getHeight() - img.getHeight(); g2d.drawImage(img, x, y, this); g2d.dispose(); } } } } 

有关详细信息,请查看堆肥图形 …