2013-03-11 69 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如果没有明确指定,可能绘制或不绘制透明。 再次感谢!