JComponents 没有出现在 JPanel 上
JComponents are not showing up on JPanel
出于某种原因,我的 JComponents 没有出现在我的 JPanel 上。
这是我的代码:
主要CLASS
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
// Main Class - executes the game
public class Main extends JFrame
{
public static int WIDTH = 800, HEIGHT = 800;
private JPanel jp;
private Dimension d;
private Snake s;
private Food f;
public Main()
{
setTitle("Snake");
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
d = new Dimension(WIDTH, HEIGHT);
jp = new JPanel();
jp.setBackground(Color.GRAY);
jp.setPreferredSize(d);
getContentPane().add(jp);
// adds the snake
s = new Snake();
jp.add(s);
// adds food
f = new Food();
jp.add(f);
}
@Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
}
public static void main(String args[])
{
new Main();
}
}
蛇CLASS
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JComponent;
// Snake Class - creates the Snake object
public class Snake extends JComponent implements KeyListener
{
public ArrayList snakeList = new ArrayList();
public int snakeX, snakeY, snakeWidth, snakeHeight;
public Snake()
{
snakeX = 100;
snakeY = 100;
snakeWidth = 20;
snakeHeight = 20;
snakeList.add(1);
addKeyListener(this);
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
g2.fillRect(snakeX, snakeY, snakeWidth, snakeHeight);
}
@Override
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP)
{
snakeX += 10;
System.out.println("Up");
}
if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN)
{
snakeX -= 10;
System.out.println("Down");
}
if(e.getKeyCode() == KeyEvent.VK_D || e.getKeyCode() == KeyEvent.VK_RIGHT)
{
snakeY += 10;
System.out.println("Right");
}
if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_LEFT)
{
snakeY -= 10;
System.out.println("Left");
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{}
}
食物CLASS
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JPanel;
// Food Class - the class that adds more Snake objects when collided with Snake
public class Food extends JComponent
{
private Random r = new Random();
public int foodX, foodY, foodWidth = 20, foodHeight = 20;
public Food()
{
foodX = 400;
foodY = 400;
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.YELLOW);
g2.fillRect(foodX, foodY, foodWidth, foodHeight);
}
}
如您所见,我有 3 个 classes:2 个 JComponents 和 1 个 JFrame(我的主要 class)。
Main Class 中有一个 JPanel,它被添加到 JFrame,然后 JPanel 添加了这两个 JComponents,但由于某种原因,JComponents 在我执行时没有显示,即使我'我很确定我已正确完成所有操作。
如果有人知道为什么这不起作用,那就太好了。谢谢!
您的 Food JComponent 的首选大小将为 0,0,这是它优先采用的大小。一个简单的解决方案是设置其首选大小或覆盖其 getPreferredSize()
方法,但我认为即使您这样做,您的程序也可能会暴露出更大的问题。我假设您想在同一个屏幕上同时显示您的蛇和食物 space。如果是这样,那么你的程序结构是错误的——食物和蛇 classes 不应该是组件 classes(例如,不应该扩展 JPanel 或 JComponent)而应该是合乎逻辑的 classes。您应该只有一个 JPanel 用于绘图,它的 paintComponent 被覆盖,并且在该方法中它绘制您的蛇和食物。
附带一点:您正在覆盖 JFrame 的绘制方法,这是一件危险的事情。幸运的是,你目前正在对它造成任何伤害,但它的存在可能会诱使你稍后在其中画画。不。我建议您删除此方法和诱惑。我自己的偏好是几乎从不扩展 JFrame,因为很少有理由这样做,而且这样做有风险。
关于您的意见:
To make clear, you're saying to only have one paintComponent() in my Main
我不知道你的 "Main" 是什么。正如我在上面提到的,我将创建一个 JPanel 用于绘画,覆盖其 protected void paintComponent(Graphics g)
方法,然后在此方法中绘制 Snake 和 Food。
and not in either my Snake or Food class?
正确。 Snake 和 Food 不应扩展 Swing 组件,因此不应覆盖 paintComponent。我会给他们一个 public void draw(Graphics g)
方法,该方法在上面 class 的 paintComponent 方法中调用,并传入 JVM 提供的 Graphics 或 Graphics2D 对象。
And also, I'll make my Main extend JPanel instead of JFrame. If that's the case, where do I create the Snake and Food Objects in my Main class?
这些细节将取决于您的实际代码。我相信你会解决这个问题的。
And also, can I keep the keyListener in the Snake class or should I put it in the Main class?
我几乎从不使用 KeyListeners,而是喜欢 Key Bindings. Look at my many posts on this subject,其中许多带有示例代码以获取更多信息。
出于某种原因,我的 JComponents 没有出现在我的 JPanel 上。
这是我的代码:
主要CLASS
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
// Main Class - executes the game
public class Main extends JFrame
{
public static int WIDTH = 800, HEIGHT = 800;
private JPanel jp;
private Dimension d;
private Snake s;
private Food f;
public Main()
{
setTitle("Snake");
setSize(WIDTH, HEIGHT);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
d = new Dimension(WIDTH, HEIGHT);
jp = new JPanel();
jp.setBackground(Color.GRAY);
jp.setPreferredSize(d);
getContentPane().add(jp);
// adds the snake
s = new Snake();
jp.add(s);
// adds food
f = new Food();
jp.add(f);
}
@Override
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
}
public static void main(String args[])
{
new Main();
}
}
蛇CLASS
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JComponent;
// Snake Class - creates the Snake object
public class Snake extends JComponent implements KeyListener
{
public ArrayList snakeList = new ArrayList();
public int snakeX, snakeY, snakeWidth, snakeHeight;
public Snake()
{
snakeX = 100;
snakeY = 100;
snakeWidth = 20;
snakeHeight = 20;
snakeList.add(1);
addKeyListener(this);
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
g2.fillRect(snakeX, snakeY, snakeWidth, snakeHeight);
}
@Override
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_W || e.getKeyCode() == KeyEvent.VK_UP)
{
snakeX += 10;
System.out.println("Up");
}
if(e.getKeyCode() == KeyEvent.VK_S || e.getKeyCode() == KeyEvent.VK_DOWN)
{
snakeX -= 10;
System.out.println("Down");
}
if(e.getKeyCode() == KeyEvent.VK_D || e.getKeyCode() == KeyEvent.VK_RIGHT)
{
snakeY += 10;
System.out.println("Right");
}
if(e.getKeyCode() == KeyEvent.VK_A || e.getKeyCode() == KeyEvent.VK_LEFT)
{
snakeY -= 10;
System.out.println("Left");
}
}
@Override
public void keyReleased(KeyEvent e)
{
}
@Override
public void keyTyped(KeyEvent e)
{}
}
食物CLASS
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Random;
import javax.swing.JComponent;
import javax.swing.JPanel;
// Food Class - the class that adds more Snake objects when collided with Snake
public class Food extends JComponent
{
private Random r = new Random();
public int foodX, foodY, foodWidth = 20, foodHeight = 20;
public Food()
{
foodX = 400;
foodY = 400;
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.YELLOW);
g2.fillRect(foodX, foodY, foodWidth, foodHeight);
}
}
如您所见,我有 3 个 classes:2 个 JComponents 和 1 个 JFrame(我的主要 class)。
Main Class 中有一个 JPanel,它被添加到 JFrame,然后 JPanel 添加了这两个 JComponents,但由于某种原因,JComponents 在我执行时没有显示,即使我'我很确定我已正确完成所有操作。
如果有人知道为什么这不起作用,那就太好了。谢谢!
您的 Food JComponent 的首选大小将为 0,0,这是它优先采用的大小。一个简单的解决方案是设置其首选大小或覆盖其 getPreferredSize()
方法,但我认为即使您这样做,您的程序也可能会暴露出更大的问题。我假设您想在同一个屏幕上同时显示您的蛇和食物 space。如果是这样,那么你的程序结构是错误的——食物和蛇 classes 不应该是组件 classes(例如,不应该扩展 JPanel 或 JComponent)而应该是合乎逻辑的 classes。您应该只有一个 JPanel 用于绘图,它的 paintComponent 被覆盖,并且在该方法中它绘制您的蛇和食物。
附带一点:您正在覆盖 JFrame 的绘制方法,这是一件危险的事情。幸运的是,你目前正在对它造成任何伤害,但它的存在可能会诱使你稍后在其中画画。不。我建议您删除此方法和诱惑。我自己的偏好是几乎从不扩展 JFrame,因为很少有理由这样做,而且这样做有风险。
关于您的意见:
To make clear, you're saying to only have one paintComponent() in my Main
我不知道你的 "Main" 是什么。正如我在上面提到的,我将创建一个 JPanel 用于绘画,覆盖其 protected void paintComponent(Graphics g)
方法,然后在此方法中绘制 Snake 和 Food。
and not in either my Snake or Food class?
正确。 Snake 和 Food 不应扩展 Swing 组件,因此不应覆盖 paintComponent。我会给他们一个 public void draw(Graphics g)
方法,该方法在上面 class 的 paintComponent 方法中调用,并传入 JVM 提供的 Graphics 或 Graphics2D 对象。
And also, I'll make my Main extend JPanel instead of JFrame. If that's the case, where do I create the Snake and Food Objects in my Main class?
这些细节将取决于您的实际代码。我相信你会解决这个问题的。
And also, can I keep the keyListener in the Snake class or should I put it in the Main class?
我几乎从不使用 KeyListeners,而是喜欢 Key Bindings. Look at my many posts on this subject,其中许多带有示例代码以获取更多信息。