我目前正在从事一个小型编码项目,但遇到了一个问题。我查看了过去的工作,但似乎无法弄清楚为什么该程序不会调用paint方法。目前,我只是想在框架上画一个圆。
下面为我要绘制的简单圆创建窗口和对象类。
public class Main {
public static void main(String[] args) {
final int WIDTH = 700, HEIGHT = 900;
JFrame frame = new JFrame("Physics Demo");
JPanel content = new JPanel();
content.setLayout(new GridLayout(1, 0, 0, 0));
Character ball = new Character(WIDTH, HEIGHT);
Timer changeFrame = new Timer (100, ball);
frameSetup(frame, content, WIDTH, HEIGHT, ball, changeFrame);
}
public static void frameSetup(JFrame frame, JPanel content, int WIDTH, int HEIGHT, Character ball, Timer changeFrame){
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(content);
content.add(ball);
frame.addKeyListener(ball);
frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
changeFrame.start();
}
}
下面的类是对象类,当我运行程序时,会从控制台得到响应。字符触发一次(应触发),并且actionPreformed方法与计时器循环运行。由于某种原因,它不会运行paint类。
public class Character extends JPanel implements ActionListener, KeyListener{
/* Identify the Objects values and physics,
* Characters weight, size and properties are below.
*
*/
private static final long serialVersionUID = 1L;
final int characterRadius = 30;
final double characterWeight = 0.5;
int characterY, characterX;
boolean bouncy;
public Character(int WIDTH, int HEIGHT){
System.out.println("Character called upon... " + WIDTH);
}
public void characterObject(Graphics g, int WIDTH, int HEIGHT){
super.paint(g);
System.out.println("characterObject graphics called upon... " + WIDTH);
g.setColor(Color.BLUE);
g.fillOval(350, 450, characterRadius, characterRadius);
}
/*
* Ball does not have any player interactions
*/
@Override
public void keyPressed(KeyEvent buttonPressed) {
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
//******************************************
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("actionPreformed called upon...");
repaint();
}
}
我已经进行了一段时间的反复试验,但似乎无法弄清楚,因此我将其作为最后的手段。
如果需要,我可以提供更多信息。
最佳答案
为什么从super.paint
呼叫characterObject
?这不是定制绘画的工作方式。您无需控制绘画过程,API可以控制
您需要重写API想要重绘组件时调用的方法之一。通常建议使用paintComponent
方法,例如
public class Character extends JPanel implements ActionListener, KeyListener {
/* Identify the Objects values and physics,
* Characters weight, size and properties are below.
*
*/
private static final long serialVersionUID = 1L;
final int characterRadius = 30;
final double characterWeight = 0.5;
int characterY, characterX;
boolean bouncy;
public Character(int WIDTH, int HEIGHT) {
System.out.println("Character called upon... " + WIDTH);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
System.out.println("characterObject graphics called upon... " + WIDTH);
g.setColor(Color.BLUE);
g.fillOval(350, 450, characterRadius, characterRadius);
}
/*
* Ball does not have any player interactions
*/
@Override
public void keyPressed(KeyEvent buttonPressed) {
}
@Override
public void keyReleased(KeyEvent arg0) {
}
@Override
public void keyTyped(KeyEvent arg0) {
}
//******************************************
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("actionPreformed called upon...");
repaint();
}
}
我建议阅读Performing Custom Painting和Painting in Swing以获取有关绘画在Swing中实际工作方式的更多详细信息。
我还建议您查看How to use Key Bindings作为
KeyListener
的替代品,这将解决您的下一个明显问题您可能还希望阅读Java Coding Conventions,这将使其他人更容易阅读您的代码,也使您更容易阅读其他人。
您正在将
width
和height
传递给Character
构造函数,但忽略它们,我建议您将需要将这些值分配给实例字段并在paintComponent
方法中使用它们