4

4 つのレイヤーが追加された JLayeredPane があります。不透明な 1 つのベース レイヤーと 3 つの「透明な」レイヤー ( setOpaque(false))。

問題は、パネルが描画されているにもかかわらず、リフレッシュするたびに灰色が表示されることです。更新が行われていない場合も同じことが起こります。つまり、ベースレイヤーに描画されたものを表示する代わりに、灰色が表示されます。これは、上のレイヤーの1つからのものであると思います. ここに 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

以前に提案された回答の 1 つが実際に私の質問を解決しましたが、何らかの理由で回答が削除されました。

パネルの背景を設定しsetBackground(new Color(0,0,0,0));て問題を解決しました。

これを示唆した人によると、その原因は、明示的に指定されていない場合、JComponent が透明に描画される場合とされない場合があるという事実です。再度、感謝します!

于 2017-09-22T09:09:41.147 に答える