我可以将 JPanel 添加到已经带有图形的 JFrame 中吗?
Can i add JPanels to a JFrame with Graphics already on it?
所以我最近开始研究 java 图形,但遇到了一个问题。我已经将图像绘制到 JFrame 上,但没有了解到如果图像都在一个 JFrame 中,则图像的边界不能相互重叠(在另一个图像所在的位置设置边界会使图像消失)。我听说过使用多个 JPanel 来解决这个问题。我不知道如何执行此操作,因为我在我的程序中使用了 JFrame 而不是 JPanel,因此在此问题上提供一些帮助将不胜感激。谢谢,如果这个问题很愚蠢,我深表歉意。 (我的另一个问题,其他人似乎认为与这个问题相同,是设置界限的问题,这个问题是关于界限重叠和相互覆盖的问题)
这是我的 类:
WindowClass-
package game.thirdTry;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
private static Window instance;
public static Window getInstance() {
if(instance == null) {
instance = new Window("Game");
}
return instance;
}
private Window(String name) {
super(name);
setSize(1200, 700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(null);
//setUndecorated(true);
addKeyListener(new UserInput());
//this.getContentPane().getSize();
WindowStructure banner = new WindowStructure("Beatles Logo.jpg", 0, 0, getWidth(), 75);
//WindowStructure fball = new WindowStructure("fireball.100x100.png", 100, 100, 100, 100);
WindowStructure fball = WindowStructure.getInstanceF();
System.out.println("Fball.xSize: " + fball.xSize + ", Fball.ySize: " + fball.ySize);
System.out.println("Fball.xLoc: " + fball.xLoc + ", Fball.yLoc: " + fball.yLoc);
//banner.setBounds(banner.xLoc, banner.yLoc, banner.xSize, banner.ySize);
//fball.setBounds(fball.xLoc, fball.yLoc, fball.xLoc + fball.xSize, fball.ySize + fball.ySize);
banner.setBounds(0, 0, getWidth(), getHeight());
fball.setBounds(0, 75, getWidth(), getHeight());
add(fball, null);
add(banner, null);
setVisible(true);
while(true){
System.out.println("Fball.xLoc: " + fball.xLoc + ", Fball.yLoc: " + fball.yLoc);
repaint();
try{
Thread.sleep(10);
}catch (Exception e){
}
}
}
/*
public void paint(Graphics g) {
super.paintComponents(g);
}
*/
}
图片Class-
package game.thirdTry;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class WindowStructure extends JPanel {
private static WindowStructure fball;
public static WindowStructure getInstanceF(){
if(fball == null){
fball = new WindowStructure("fireball.100x100.png", 0, 75, 100, 100);
}
return fball;
}
ImageIcon imageIcon;
int xLoc, yLoc, xSize, ySize;
public WindowStructure(String bannerImg, int xLoc, int yLoc, int xSize, int ySize){
URL bannerImgURL = getClass().getResource(bannerImg);
imageIcon = new ImageIcon(bannerImgURL);
this.xLoc = xLoc;
this.yLoc = yLoc;
this.xSize = xSize;
this.ySize = ySize;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, xSize, ySize, null);
}
}
KeyListener/用户输入Class-
package game.thirdTry;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class UserInput implements KeyListener {
// Window window = Window.getInstance();
WindowStructure fball = WindowStructure.getInstanceF();
boolean goUp = false;
boolean goDown = false;
boolean goLeft = false;
boolean goRight = false;
public void moveUpDown() {
if (goUp && goDown) {
if (fball.yLoc > 0) {
fball.yLoc -= 10;
}
} else if (goUp) {
if (fball.yLoc > -5) {
fball.yLoc -= 10;
}
} else if (goDown) {
if (fball.yLoc < 480) {
fball.yLoc += 10;
}
}
System.out.println("moveUpDown() method called");
}
public void moveLeftRight() {
if (goLeft && goRight) {
if (fball.xLoc < 1100) {
fball.xLoc += 10;
}
} else if (goRight) {
if (fball.xLoc < 1110) {
fball.xLoc += 10;
}
} else if (goLeft) {
if (fball.xLoc > 0) {
fball.xLoc -= 10;
}
}
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
goUp = true;
goDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
goDown = true;
goUp = false;
}
if (e.getKeyCode() == KeyEvent.VK_A) {
goLeft = true;
goRight = false;
}
if (e.getKeyCode() == KeyEvent.VK_D) {
goRight = true;
goLeft = false;
}
moveUpDown();
moveLeftRight();
System.out.println("keyPressed() was called");
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
goUp = false;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
goDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_A) {
goLeft = false;
}
if (e.getKeyCode() == KeyEvent.VK_D) {
goRight = false;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
}
//g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, xSize, ySize, null);
问题是您在绘制图像时正在缩放图像。因此,图像占据了整个 window space,所以是的,它绘制在首先绘制的图像之上。
只需按实际大小绘制图像:
g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, this);
这是使用 JLabel 的另一个原因。您无需担心尺寸。您只需将标签放在特定位置,图像就会被绘制出来。代码要简单得多。使用这种方法,您无需担心使面板不透明。
您的代码现在的问题是您需要使面板变大,因为您正在绘制相对于 WindowStructure 面板的图像。所以如果你的图像是 (25 x 25) 并且你想要在 (100, 100) 绘制图像,你需要制作面板 (125, 125),这意味着面板需要是透明的,所以面板的一部分不包含图像未绘制。使用 JLable,标签的大小将始终为 (25, 25),因此您可以简单地设置标签的位置,并且只会绘制 (25, 25) 个像素。
I'll look more into JLabels later
现在看看。没有比现在更好的时间了!
此外,您的 WindowStructure class 的设计很糟糕。不需要静态方法和变量。每张图片应该相互独立。
所以我最近开始研究 java 图形,但遇到了一个问题。我已经将图像绘制到 JFrame 上,但没有了解到如果图像都在一个 JFrame 中,则图像的边界不能相互重叠(在另一个图像所在的位置设置边界会使图像消失)。我听说过使用多个 JPanel 来解决这个问题。我不知道如何执行此操作,因为我在我的程序中使用了 JFrame 而不是 JPanel,因此在此问题上提供一些帮助将不胜感激。谢谢,如果这个问题很愚蠢,我深表歉意。 (我的另一个问题,其他人似乎认为与这个问题相同,是设置界限的问题,这个问题是关于界限重叠和相互覆盖的问题) 这是我的 类:
WindowClass-
package game.thirdTry;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
private static Window instance;
public static Window getInstance() {
if(instance == null) {
instance = new Window("Game");
}
return instance;
}
private Window(String name) {
super(name);
setSize(1200, 700);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(null);
//setUndecorated(true);
addKeyListener(new UserInput());
//this.getContentPane().getSize();
WindowStructure banner = new WindowStructure("Beatles Logo.jpg", 0, 0, getWidth(), 75);
//WindowStructure fball = new WindowStructure("fireball.100x100.png", 100, 100, 100, 100);
WindowStructure fball = WindowStructure.getInstanceF();
System.out.println("Fball.xSize: " + fball.xSize + ", Fball.ySize: " + fball.ySize);
System.out.println("Fball.xLoc: " + fball.xLoc + ", Fball.yLoc: " + fball.yLoc);
//banner.setBounds(banner.xLoc, banner.yLoc, banner.xSize, banner.ySize);
//fball.setBounds(fball.xLoc, fball.yLoc, fball.xLoc + fball.xSize, fball.ySize + fball.ySize);
banner.setBounds(0, 0, getWidth(), getHeight());
fball.setBounds(0, 75, getWidth(), getHeight());
add(fball, null);
add(banner, null);
setVisible(true);
while(true){
System.out.println("Fball.xLoc: " + fball.xLoc + ", Fball.yLoc: " + fball.yLoc);
repaint();
try{
Thread.sleep(10);
}catch (Exception e){
}
}
}
/*
public void paint(Graphics g) {
super.paintComponents(g);
}
*/
}
图片Class-
package game.thirdTry;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class WindowStructure extends JPanel {
private static WindowStructure fball;
public static WindowStructure getInstanceF(){
if(fball == null){
fball = new WindowStructure("fireball.100x100.png", 0, 75, 100, 100);
}
return fball;
}
ImageIcon imageIcon;
int xLoc, yLoc, xSize, ySize;
public WindowStructure(String bannerImg, int xLoc, int yLoc, int xSize, int ySize){
URL bannerImgURL = getClass().getResource(bannerImg);
imageIcon = new ImageIcon(bannerImgURL);
this.xLoc = xLoc;
this.yLoc = yLoc;
this.xSize = xSize;
this.ySize = ySize;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, xSize, ySize, null);
}
}
KeyListener/用户输入Class-
package game.thirdTry;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class UserInput implements KeyListener {
// Window window = Window.getInstance();
WindowStructure fball = WindowStructure.getInstanceF();
boolean goUp = false;
boolean goDown = false;
boolean goLeft = false;
boolean goRight = false;
public void moveUpDown() {
if (goUp && goDown) {
if (fball.yLoc > 0) {
fball.yLoc -= 10;
}
} else if (goUp) {
if (fball.yLoc > -5) {
fball.yLoc -= 10;
}
} else if (goDown) {
if (fball.yLoc < 480) {
fball.yLoc += 10;
}
}
System.out.println("moveUpDown() method called");
}
public void moveLeftRight() {
if (goLeft && goRight) {
if (fball.xLoc < 1100) {
fball.xLoc += 10;
}
} else if (goRight) {
if (fball.xLoc < 1110) {
fball.xLoc += 10;
}
} else if (goLeft) {
if (fball.xLoc > 0) {
fball.xLoc -= 10;
}
}
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
goUp = true;
goDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
goDown = true;
goUp = false;
}
if (e.getKeyCode() == KeyEvent.VK_A) {
goLeft = true;
goRight = false;
}
if (e.getKeyCode() == KeyEvent.VK_D) {
goRight = true;
goLeft = false;
}
moveUpDown();
moveLeftRight();
System.out.println("keyPressed() was called");
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W) {
goUp = false;
}
if (e.getKeyCode() == KeyEvent.VK_S) {
goDown = false;
}
if (e.getKeyCode() == KeyEvent.VK_A) {
goLeft = false;
}
if (e.getKeyCode() == KeyEvent.VK_D) {
goRight = false;
}
}
@Override
public void keyTyped(KeyEvent e) {
}
}
//g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, xSize, ySize, null);
问题是您在绘制图像时正在缩放图像。因此,图像占据了整个 window space,所以是的,它绘制在首先绘制的图像之上。
只需按实际大小绘制图像:
g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, this);
这是使用 JLabel 的另一个原因。您无需担心尺寸。您只需将标签放在特定位置,图像就会被绘制出来。代码要简单得多。使用这种方法,您无需担心使面板不透明。
您的代码现在的问题是您需要使面板变大,因为您正在绘制相对于 WindowStructure 面板的图像。所以如果你的图像是 (25 x 25) 并且你想要在 (100, 100) 绘制图像,你需要制作面板 (125, 125),这意味着面板需要是透明的,所以面板的一部分不包含图像未绘制。使用 JLable,标签的大小将始终为 (25, 25),因此您可以简单地设置标签的位置,并且只会绘制 (25, 25) 个像素。
I'll look more into JLabels later
现在看看。没有比现在更好的时间了!
此外,您的 WindowStructure class 的设计很糟糕。不需要静态方法和变量。每张图片应该相互独立。