Java 我可以将JPanel添加到已经有图形的JFrame中吗?
所以我最近开始玩java图形,遇到了一个问题。我已经在JFrame上绘制了图像,但没有了解到如果图像的边界都在一个JFrame中,则它们的边界不能相互重叠(设置另一个图像所在位置的边界会使图像消失)。我听说了一些关于使用多个JPanel来修复此问题的信息。我不知道如何做到这一点,因为我在我的程序中使用了JFrame而不是JPanel,所以在这个问题上需要一些帮助。谢谢,如果这个问题是愚蠢的,我道歉。(其他人似乎认为我的另一个问题与这个问题相同,那就是设置边界的问题,这个问题涉及边界重叠和相互覆盖) 以下是我的课程: 窗口类-Java 我可以将JPanel添加到已经有图形的JFrame中吗?,java,swing,graphics,jframe,jpanel,Java,Swing,Graphics,Jframe,Jpanel,所以我最近开始玩java图形,遇到了一个问题。我已经在JFrame上绘制了图像,但没有了解到如果图像的边界都在一个JFrame中,则它们的边界不能相互重叠(设置另一个图像所在位置的边界会使图像消失)。我听说了一些关于使用多个JPanel来修复此问题的信息。我不知道如何做到这一点,因为我在我的程序中使用了JFrame而不是JPanel,所以在这个问题上需要一些帮助。谢谢,如果这个问题是愚蠢的,我道歉。(其他人似乎认为我的另一个问题与这个问题相同,那就是设置边界的问题,这个问题涉及边界重叠和相互覆盖
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);
}
*/
}
图像类-
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/用户输入类-
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) {
}
}
package game.thirdTry;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
公共类UserInput实现KeyListener{
//Window=Window.getInstance();
WindowStructure fball=WindowStructure.getInstanceF();
布尔goUp=false;
布尔仓库=假;
布尔goLeft=false;
布尔goRight=false;
公共void moveUpDown(){
如果(货物和仓库){
如果(fball.yLoc>0){
fball.yLoc-=10;
}
}否则,如果(goUp){
如果(fball.yLoc>-5){
fball.yLoc-=10;
}
}否则,如果(货仓){
如果(fball.yLoc<480){
fball.yLoc+=10;
}
}
println(“调用moveUpDown()方法”);
}
公共void moveLeftRight(){
if(高尔夫球场和高尔夫球场){
如果(fball.xLoc<1100){
fball.xLoc+=10;
}
}否则,如果(戈赖特){
如果(fball.xLoc<1110){
fball.xLoc+=10;
}
}否则如果(高尔夫){
如果(fball.xLoc>0){
fball.xLoc-=10;
}
}
}
@凌驾
按下公共无效键(按键事件e){
if(e.getKeyCode()==KeyEvent.VK_W){
goUp=真;
货仓=假;
}
如果(例如getKeyCode()==KeyEvent.VK_S){
货仓=真实;
goUp=假;
}
如果(例如getKeyCode()==KeyEvent.VK_A){
高尔夫=真;
戈赖特=假;
}
如果(例如getKeyCode()==KeyEvent.VK_D){
戈赖特=真;
高尔夫=假;
}
moveUpDown();
moveLeftRight();
System.out.println(“调用了keyPressed());
}
@凌驾
公共无效密钥已释放(密钥事件e){
if(e.getKeyCode()==KeyEvent.VK_W){
goUp=假;
}
如果(例如getKeyCode()==KeyEvent.VK_S){
货仓=假;
}
如果(例如getKeyCode()==KeyEvent.VK_A){
高尔夫=假;
}
如果(例如getKeyCode()==KeyEvent.VK_D){
戈赖特=假;
}
}
@凌驾
public void keyTyped(KeyEvent e){
}
}
问题是在绘制图像时正在缩放图像。因此,图像占据了整个窗口空间,因此是的,它在首先绘制的图像上方绘制
只需按实际大小绘制图像:
g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, this);
这是使用JLabel的另一个原因。你不必担心尺寸。您只需将标签放置在特定位置,即可绘制图像。代码要简单得多。使用这种方法,您无需担心面板是否不透明
现在代码的问题是,您需要将面板设置为大尺寸,因为您正在绘制相对于WindowsStructure面板的图像。因此,如果您的图像是(25 x 25),并且希望在(100100)处绘制图像,则需要制作面板(125125),这意味着面板需要透明,以便不绘制面板中不包含图像的部分。使用JLable,标签的大小将始终为(25,25),因此您可以简单地设置标签的位置,并且只绘制(25,25)个像素
稍后我将进一步研究JLabels 现在看看。没有比现在更好的时间了
另外,WindowsStructure类的设计也很糟糕。不需要静态方法和变量。每个图像都应该相互独立。
没有了解到,如果它们都在一个JFrame中,则图像的边界不能相互重叠(设置另一个图像所在位置的边界会使图像消失)。
-不正确,我在5天前提出的上一个问题中解释了如何做到这一点由于我在程序中使用了JFrame而不是JPanel
您的WindowsStructure类扩展了JPanel,所以您使用的是JPanel。为什么要使用自定义类?您可以使用JLabel来显示图像。通过扩展JPanel,我实际上并没有声明JPanel。那么我应该如何使用多个JPanel,或者我甚至不需要这样做,因为我将使用setOpaque()方法(我回头看了老问题,我仍然不完全清楚我需要做什么),我真的不喜欢使用JLabels sinc,我更了解我的自定义类,并且更喜欢这样做。感谢到目前为止通过扩展JPanel而提供的所有帮助,我实际上并没有声明JPanel。
-每个WindowsStructure对象都是一个
JPanel。您拥有面板的所有属性,并且使用WindowsStructure的方式与使用JPanel的方式完全相同我真的不喜欢使用JLabel
-使用JLabel所做的就是设置标签的位置。其他人似乎认为我的另一个问题与此相同,那就是设置边界的问题,这个问题涉及边界重叠和相互覆盖
——在另一个问题中,您在评论中提出了一个后续问题,并得到了一个回答:
g2d.drawImage(imageIcon.getImage(), xLoc, yLoc, this);