1

我已经尝试了几个教程和搜索来弄清楚如何完成我想要做的事情。基本上我有一个 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);
        }
    }
}
}
4

2 回答 2

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默认情况下是透明的;)

于 2013-03-02T01:18:08.883 回答
0

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

尝试实现以下方法..

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

希望这会对您有所帮助...

于 2013-03-02T04:13:06.737 回答