2013-03-11 90 views
3

我有一個添加了4層的JLayeredPane。 1個不透明基層和三個「透明」層(setOpaque(false))。如何使JLayeredPane上的面板透明?

問題是,雖然面板被繪製到,每刷新一次灰色顯示。如果沒有刷新發生,同樣的事情發生。換句話說,不是顯示繪製到底層上的任何內容,而是顯示灰色,我假設這是來自上面的一個層。 這是一個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); 
} 

}

這可能是一些基本的錯誤,我做了。謝謝你的幫助!

+0

不應該有所作爲,但我不確定你爲什麼使用「PALETTE_LAYER」,「DRAG_LAYER」等。這些是特定的目的層。通常你爲每個附加圖層使用一個整數值。無論如何,我沒有多個透明圖層的問題。發佈你的[SSCCE](http://sscce.org/)來證明問題。 – camickr 2013-03-11 15:56:09

+0

感謝您的評論!我按照你的要求添加了一個SSCCE。 – chibi03 2013-03-11 16:53:48

+0

渲染不應該調用repaint。 – 2013-03-11 17:39:50

回答

1

以前建議的答案之一實際上解決了我的問題,但由於某種原因,他們刪除了他們的答案。

將我的面板背景設置爲setBackground(new Color(0,0,0,0));解決了我的問題。

根據提示這個的人,其原因是JComponent如果沒有明確指定,可能繪製或不繪製透明。 再次感謝!