4

我有一个添加了 4 层的 JLayeredPane。1 个不透明的基础层和三个“透明”层 ( setOpaque(false))。

问题是,尽管面板被绘制到,但每次刷新都会显示灰色。如果没有刷新发生,也会发生同样的事情。换句话说,不是显示在基础层上绘制的任何内容,而是显示灰色,我假设这是来自上面的一层。这是一个 SSCCE - 我不确定这是否足够短,但它显示了我的问题。

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

}

这可能是我犯的一些基本错误。谢谢你的帮助!

4

1 回答 1

1

先前建议的答案之一实际上解决了我的问题,但由于某种原因,他们删除了答案。

设置面板的背景来setBackground(new Color(0,0,0,0));解决我的问题。

根据提出此建议的人的说法,其原因是如果没有明确指定,JComponent 可能会或可能不会绘制透明。再次感谢!

于 2017-09-22T09:09:41.147 回答