【发布时间】:2019-04-23 10:17:55
【问题描述】:
我从 Java 开始,想制作一个简单的乒乓球游戏,以了解在 Java 中显示内容的方式。我创建了 2 个类,它们都扩展 JPanel 并每 16.6 毫秒调用一次 repaint() 函数。我将两者都添加到了我添加到框架中的 JPanel 中,但只有我首先添加的组件才会显示。
我在两个类中都尝试在repaint() 之后使用revalidate(),并确保 Timer 确实有效,并且实际上调用了 actionPerformed() 方法。
这是主要的方法:
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Pong");
//...
JPanel mainPanel = new JPanel();
mainPanel.add(new Player());
mainPanel.add(new Ball(frameWidth/2, frameHeight/2 -40));
frame.add(mainPanel);
}
}
这是类的重要代码(两者基本相同):
public class Player extends JPanel {
public Player(){
setPreferredSize(new Dimension(Main.frameWidth, Main.frameHeight));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
public void actionPerformed(ActionEvent e){
update();
repaint();
}
}).start();
}
//...
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
(当然,我留下了诸如 @Override 或不必要的函数之类的东西以缩短代码)
此代码仅绘制播放器,尽管我希望它显示mainPanel 的所有组件。
这是一个您可以(希望)运行的示例。我不得不把它分成 3 个文件,因为我很讨厌匿名类:
Main.java
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args){
JFrame frame = new JFrame("Pong");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 800);
JPanel mainPanel = new JPanel();
mainPanel.add(new Player());
mainPanel.add(new Ball());
frame.add(mainPanel);
frame.setVisible(true);
}
}
///////
Player.java
//////
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Player extends JPanel{
private int x = 20, y = 300, width = 20, height = 100;
public Player(){
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
repaint();
}
}).start();
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
//////
Ball.java
//////
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Ball extends JPanel{
private int x = 20, y = 300, width = 20, height = 100;
public Ball(){
setPreferredSize(new Dimension(800, 800));
setBackground(Color.BLACK);
new Timer(1000/60, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
repaint();
}
}).start();
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
g.fillRect(x, y, width, height);
}
}
【问题讨论】:
-
类
Player和Ball是否定义了首选尺寸?JPanel是一个容器,旨在根据其包含的 GUI 组件调整自身大小。看起来您的类Player和Ball不包含任何 GUI 组件,因此它们的大小可能为 0(零)。 -
确实如此。我这样设置它们;
setPreferredSize(new Dimension(800, 800)); -
那么我认为如果您发布 minimal reproducible example 会帮助人们帮助您。
-
好的,我会在收到问题后编辑问题。
-
好的,已经出来了。
标签: java swing graphics jpanel