Graphics2D not clearing transparent image
java, repaint, transparency
Solution
Turned out I had to set the correct composite value before painting. Adding
((Graphics2D)g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
to the start of the `paintComponent()` method, then using `fillRect()`, did the trick!
Problem
I have the following snippet of code which should increment a counter on a transparent background on the first monitor. When the image shows 0 it renders fine, but after that (as soon as 1 is hit) the window redraws with an opaque background. Silly example in practice I know, just broken a real use case down to a simpler piece of code. It seems the key might be in the paintComponent method of TestCanvas: ``` g.setColor(new Color(0, 0, 0, 0)); g.clearRect(0, 0, getWidth(), getHeight()); ``` From what I can work out, those two lines should set the drawing colour to completely transparent, then clear the given area with that colour - but this doesn't seem to be holding for beyond the first repaint. EDIT: Using fillRect instead of clearRect doesn't work because it just paints the transparent rectangle on top of the existing image, so it never gets cleared. 1 is overlayed on 0, then 2 overlayed on 1, etc. ``` import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import javax.swing.JPanel; import javax.swing.JWindow; import javax.swing.SwingUtilities; public class LyricWindow extends JWindow { private final TestCanvas canvas; public LyricWindow(Rectangle area, boolean stageView) { setBackground(new Color(0, 0, 0, 0)); setArea(area); canvas = new TestCanvas(); canvas.setPreferredSize(new Dimension((int) (area.getMaxX() - area.getMinX()), (int) (area.getMaxY() - area.getMinY()))); add(canvas); new Thread() { public void run() { for(int i = 0; true; i++) { final int ii = i; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { canvas.setText(Integer.toString(ii)); } }); try { Thread.currentThread().sleep(200); } catch(InterruptedException ex) {} System.out.println(ii); } } }.start(); } public final void setArea(final Rectangle area) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { if(canvas != null) { canvas.setPreferredSize(new Dimension((int) (area.getMaxX() - area.getMinX()), (int) (area.getMaxY() - area.getMinY()))); } setSize((int) (area.getMaxX() - area.getMinX()), (int) (area.getMaxY() - area.getMinY())); setLocation((int) area.getMinX(), (int) area.getMinY()); } }); } public static void main(String[] args) { LyricWindow w = new LyricWindow(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getConfigurations()[0].getBounds(), false); w.setVisible(true); } } class TestCanvas extends JPanel { private String text; @Override public void paintComponent(Graphics g) { g.setColor(new Color(0, 0, 0, 0)); g.clearRect(0, 0, getWidth(), getHeight()); g.setColor(Color.RED); g.drawString(text, 100, 100); } public void setText(String s) { text = s; repaint(); } } ```