Question

I have a JLayeredPane with 4 layers added to it. 1 base layer, which is opaque and three 'transparent' layers (setOpaque(false)).

The problem is that although the panels are drawn onto, with every refresh a gray color is shown. The same thing happens if there is no refresh happening. In other words, instead of showing whatever was drawn onto the base layer, a gray color is shown, I assume this is from one of the layers above. Here is a SSCCE - I'm not sure if this is short enough but it shows my problem.

    public class SSCCE extends JLayeredPane{

public static void main(String[] args){
    JFrame frame = new JFrame();
    frame.setSize(950, 600);
    frame.add(new SSCCE());
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

// private fields
private boolean drawInitial = true;
private boolean drawn = false;

private JPanel overlay, base, iconPanel, middle;
private BufferedImage baseBuffer, midBuffer, overlayBuffer, iconBuffer;
private boolean updateInit = true;
private Rectangle2D stored = new Rectangle2D.Double(60, 60, 40, 100);

public SSCCE() {

    setBorder(new LineBorder(Color.BLACK));
    setDoubleBuffered(false);
    setOpaque(true);
    setSize(new Dimension(950, 600));
    setPreferredSize(new Dimension(950, 600));

    base = new JPanel();
    base.setBackground(new Color(0,0,0,0));
    base.setSize(new Dimension(getWidth(), getHeight()));
    this.add(base, new Integer(0));


    middle = new JPanel();
    middle.setSize(new Dimension(getWidth(), getHeight()));
    middle.setBackground(new Color(0,0,0,0));
    middle.setOpaque(false);
    this.add(middle, new Integer(1));

    overlay = new JPanel();
    overlay.setBackground(new Color(0,0,0,0));
    overlay.setOpaque(false);
    overlay.setSize(new Dimension(getWidth(), getHeight()));
    this.add(overlay, new Integer(2));
    iconPanel = new JPanel();
    iconPanel.setBackground(new Color(0,0,0,0));
    iconPanel.setSize(getWidth(), getHeight());
    iconPanel.setOpaque(false);
    this.add(iconPanel, new Integer(3));

}

public void update() {
    if(updateInit){
        checkBuffer();
        updateInit = false;
    }
    drawInfoRect();
    drawIcon();
    highlightPath(stored);
}

public void render() {
    if (drawInitial) {
        Graphics2D baseGraphics = (Graphics2D) base.getGraphics();
        baseGraphics.drawImage(baseBuffer, 0, 0, null);
    }
    setResistanceColor((Graphics2D)baseBuffer.getGraphics());
    middle.getGraphics().drawImage(midBuffer, 0, 0, null);
    iconPanel.getGraphics().drawImage(iconBuffer, 0, 0, null);
    drawInfoRect();
    base.getGraphics().drawImage(baseBuffer, 0, 0, null);
    if (drawn) {
        overlay.getGraphics().drawImage(overlayBuffer, 0, 0, null);
    }
    repaint();
}

// /**
// * draws the appropriate colour
// */
@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    update();
    render();
}

/**
 * sets the appropriate colours according to the resistance
 * @param g2
 */
private void setResistanceColor(Graphics2D g2) {
        Rectangle2D sp = new Rectangle2D.Double(50,50, 50, 50);
        g2.setColor(Color.GREEN);
        g2.fill(sp);
        g2.setColor(Color.BLACK);
}

/**
 * checks if there already exists an image to buffer with
 */
private void checkBuffer() {
    if (baseBuffer == null) {
        baseBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));

        // background color
        Graphics2D g2 = (Graphics2D) baseBuffer.getGraphics();
        g2.setColor(Color.decode("#729fcf"));
        Rectangle2D rect = new Rectangle2D.Double(0, 0, baseBuffer.getWidth(), baseBuffer.getHeight());
        g2.fill(rect);
    }
    if (midBuffer == null) {
        midBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
        // background color
        Graphics2D g2 = (Graphics2D) midBuffer.getGraphics();
        g2.setColor(Color.RED);
        Rectangle2D rect = new Rectangle2D.Double(0, 0, midBuffer.getWidth(), midBuffer.getHeight());
        g2.fill(rect);
    }
    if (overlayBuffer == null) {
        overlayBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
    }
    if (iconBuffer == null) {
        iconBuffer = (new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB));
    }
}

public void highlightPath(Shape enlighten) {
    Area area = new Area();
    area.add(new Area(enlighten));
    // clearing image before drawing
    Graphics2D midBufferG = (Graphics2D) midBuffer.getGraphics();
    clearImage(midBufferG);

    midBufferG.setColor(Color.white);

    // adds a transparent overlay
    midBufferG.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f));
    midBufferG.fill(area);
}

public void drawIcon() {
    Graphics2D iconG = (Graphics2D) iconBuffer.getGraphics();
    clearImage(iconG);
}

public void drawInfoRect() {
    Graphics2D graph = (Graphics2D) overlayBuffer.getGraphics();

    Rectangle2D visible = getVisibleRect();
    int boxX = (int) (visible.getX() + 50);
    int boxY = (int) (visible.getY() + 450);

    RoundRectangle2D rect = new RoundRectangle2D.Double(boxX, boxY, 200, 150, 25, 25);

    graph.setColor(Color.decode("#729fcf").darker());
    graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f));
    graph.fill(rect);

    graph.setColor(Color.BLACK);
    drawn = true;
}


private void clearImage(Graphics2D graph){
    graph.setComposite(AlphaComposite.Clear);
    graph.fillRect(0, 0, overlayBuffer.getWidth(), overlayBuffer.getHeight());
    graph.setComposite(AlphaComposite.SrcOver);
}

}

It might be some basic mistake I made. Thanks for your help!

Was it helpful?

Solution

One of the previously suggested answers actually solved my question, but for some reason they deleted their answer.

Setting the Background of my panels to setBackground(new Color(0,0,0,0)); solved my problems.

According to the person that suggested this, the cause of that is the fact that JComponent may or may not draw transparent if not explicitly specified. Thanks again!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top