gpt4 book ai didi

java - 无法绘制透明组件背景

转载 作者:行者123 更新时间:2023-12-01 04:49:53 24 4
gpt4 key购买 nike

我尝试了几个教程和搜索来找出如何完成我想要做的事情。基本上我有一个 JLayeredPane,里面有两个 Jpanels。一个用于我的游戏的绘图表面,另一个用于我的 GUI,例如暂停菜单。我有一个带有透明度的 png 文件,我想将其作为 gui 面板的背景,当用户点击 escape 时会弹出该面板。无论我做什么,面板的背景(甚至尝试将其只是一个组件)始终是灰色的,并在其上绘制了我的 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);
}
}
}
}

最佳答案

我还没有对此进行测试,但是,不要在绘制方法的末尾调用 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 默认情况下是透明的;)

关于java - 无法绘制透明组件背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15169467/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com