无法绘制透明的组件背景

时间:2013-03-02 01:05:01

标签: java swing jpanel transparency graphics2d

我已经尝试了几个教程和搜索来弄清楚如何完成我想要做的事情。基本上我有一个JLayeredPane,里面有两个Jpanels。一个用于我的游戏绘图表面,另一个用于我的gui,如暂停菜单。我有一个透明胶片的png文件,我想成为我的gui面板的背景,当用户遇到逃生时弹出。无论我做什么,面板的背景(甚至尝试使它只是一个组件)总是灰色的,我的png文件被绘制在它上面。

我尝试过其他人推荐的内容,如下所示。

setBackground(new Color(0,0,0,0)); 

setOpaque(false);

这些似乎都没有帮助,也许我在这些之后没有做其他事情。我传统上在构造函数之后或在扩展jpanel的类的构造函数中完成它们。

我几乎到了我将拥有一个面板并自己绘制所有内容但我宁愿使用内置的java函数,如boxlayouts等。

编辑添加工作示例:

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;


public class Example {

private MyWindow gWindow;

public static void main(String argv[]) {
    Example g = new Example();

    g.gameLoop();
}

public Example() {
    gWindow = new MyWindow();

    // Initialize the keyboard listener
    gWindow.frame().addKeyListener(new KeyListener() {
        public void keyPressed(KeyEvent e) {
            if(e.getKeyCode() == KeyEvent.VK_ESCAPE) // escape key, show menu
            {
                System.exit(0);
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {           
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }
    });
}

public void gameLoop() {
    long lastLoopTime = System.currentTimeMillis();
    while(true) {
        // Used to calculate movement of sprites
        long delta = System.currentTimeMillis() - lastLoopTime;
        lastLoopTime = System.currentTimeMillis();

        // Clear the canvas
        Graphics2D g = (Graphics2D) gWindow.getBufferStrategy().getDrawGraphics();
        g.setColor(Color.black);
        g.fillRect(0,0,gWindow.frame().getWidth(), gWindow.frame().getHeight());

        // Clean up graphics and flip buffer
        g.dispose();
        gWindow.getBufferStrategy().show();

        // Small delay before next cycle
        try { Thread.sleep(10); } catch (Exception e) {}
    }
}

public class MyWindow {
    private JFrame frame;
    private JLayeredPane container;
    private MyPanel gui;
    private JPanel surface;

    private Canvas canvas;

    private GraphicsDevice vc;
    private Dimension dm;

    BufferedImage menuImg = null;
    BufferedImage menuImgHighlight = null;
    BufferedImage gSettings = null;
    Font font = null;

    public MyWindow() {
        frame = new JFrame("Jumper");

        vc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();

        DisplayMode display = vc.getDisplayMode();
        dm = new Dimension(display.getWidth(), display.getHeight());

        container = new JLayeredPane();     
        gui = new MyPanel();
        gui.setLayout(new BoxLayout(gui, BoxLayout.Y_AXIS));
        surface = new JPanel(new BorderLayout(0,0));

        frame.add(container, BorderLayout.CENTER);
        container.add(surface, new Integer(0), 0);
        container.add(gui, new Integer(1), 0);

        init_resources();

        canvas = new Canvas();
        surface.add(canvas);    

        gui.setBackground(new Color(0,0,0,0));
        gui.setVisible(true);
        gui.setOpaque(false);

        surface.setVisible(true);

        setFullScreen(display);

        frame.setResizable(false);
        frame.setVisible(true);
        frame.pack();
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        frame.addComponentListener(new ComponentAdapter() {

            @Override
            public void componentResized(ComponentEvent e) {
                setScreen(new Dimension(frame.getWidth(), frame.getHeight()));
                frame.repaint();
            }
        });

        canvas.setIgnoreRepaint(true);
        canvas.createBufferStrategy(2);
        canvas.setFocusable(false);
    }

    public JFrame frame() {
        return frame;
    }

    public BufferStrategy getBufferStrategy () {
        return canvas.getBufferStrategy();
    }

    public void setScreen(Dimension dim) {
        int width = (int) dim.getWidth();
        int height = (int) dim.getHeight();
        this.dm = dim;

        container.setPreferredSize(dm);
        gui.setPreferredSize(dm);
        surface.setPreferredSize(dm);

        canvas.setBounds(0,0,width,height);
        if(gSettings == null) {
            gui.setBounds((int) ((dm.getWidth() - 200) / 2),
                    (int) ((dm.getHeight() - 200) / 2),
                    200,
                    200);
        }
        else {
            gui.setBounds((int) ((dm.getWidth() - gSettings.getWidth()) / 2),
                    (int) ((dm.getHeight() - gSettings.getHeight()) / 2),
                    gSettings.getWidth(),
                    gSettings.getHeight());
        }
        gui.setBackground(gSettings);
        surface.setBounds(0,0,width,height);
        container.setBounds(0,0,width,height);
        frame.validate();
    }

    public void setFullScreen(DisplayMode display) {
        setScreen( Toolkit.getDefaultToolkit().getScreenSize());
        frame.setUndecorated(true);
        vc.setFullScreenWindow(frame);
        if(dm != null && vc.isDisplayChangeSupported()) {
            try {
                vc.setDisplayMode(display);
            }
            catch(Exception e) {}
        }   
        frame.validate();
    }

    private void init_resources() {
        try {
            gSettings = ImageIO.read(getClass().getResourceAsStream("/gui/settingsWindow.png"));
        }
        catch(Exception e)
        {
            System.out.print("Failed to load resources");
            System.out.println();
        }       
    }

}

public class MyPanel extends JPanel {

    BufferedImage img = null;
    public MyPanel() {
        super();
        setOpaque(false);
    }

    public void setBackground(BufferedImage img) {
        this.img = img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if(img != null) {
            Graphics2D g2d = (Graphics2D) g;
            g2d.drawImage(img, 0, 0, null);
        }
    }
}
}

2 个答案:

答案 0 :(得分:0)

我没有对此进行测试,但是,不是在绘制方法结束时调用super.paintComponent,而是尝试在开始时调用....

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    if(img != null) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(img, 0, 0, null);
    }
}

这样做的原因是,paintComponent的工作之一是清除图形上下文并准备好绘制。事件如果组件是透明的,它仍然必须清除/擦除之前在其上绘制的任何内容的图形上下文。图形上下文是一个共享资源,这意味着给定窗口中的所有组件可能共享相同的图形上下文,因此如果它没有首先被“擦除”,它会变得有点脏;)

您可能还会遇到混合重量轻和重量轻的组件的问题,但是当您将重量轻的组件添加到重量级组件时,这可能不是问题,但值得放在您的脑海中。 。;)

默认情况下,

JComponent是透明的;)

答案 1 :(得分:0)

尝试在这里应用一些物理... 可见白色是RGB最大值的组合...... 如果您将RGB值保持为最小值,它将为您提供深色(黑色)而不是透明色。

尝试实现以下方法..

(your component).setOpaque(false);
(your component).setContentAreaFilled(false);
(your component).setBorderPainted(false);

希望这对你有帮助......