英文:
Swing_Frame_Unable to get output for the animation code
问题
代码:
public class SimpleAnimation {
int x = 70;
int y = 70;
public static void main(String[] args) {
SimpleAnimation gui = new SimpleAnimation();
gui.go();
}
public void go() {
System.out.println("go");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel mdp = new MyDrawPanel();
frame.getContentPane().add(mdp);
frame.setSize(300, 300);
frame.setVisible(true);
System.out.println("go");
for (int i = 0; i < 130; i++) {
x++;
y++;
mdp.repaint();
System.out.println("go");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) { // 这里应该是 paintComponent 而不是 painComponent
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}
查询:
输出应该是一个带有白色背景并且有一个小圆圈在一个圆里的框架。但实际输出只有一个空白的框架。是什么被遗漏了?我已经使用了继承了 JPanel 的内部类。有谁能帮忙得到期望的输出吗?
***************************************************************************************
英文:
Code :
public class SimpleAnimation {
int x=70;
int y=70;
public static void main(String[] args) {
SimpleAnimation gui = new SimpleAnimation();
gui.go();
}
public void go()
{
System.out.println("go");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel mdp = new MyDrawPanel();
frame.getContentPane().add(mdp);
frame.setSize(300,300);
frame.setVisible(true);
System.out.println("go");
for(int i=0;i<130;i++) {
x++;
y++;
mdp.repaint();
System.out.println("go");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
}
class MyDrawPanel extends JPanel{
public void painComponent(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}
Query :
The output should be frame filled with white background and round small circle rounds in the a circle. But output is only an empty frame. what would be the missed one? I have used the JPanel extended class as inner class. Could someone help on getting the desired output?
***************************************************************************************
答案1
得分: 2
Swing是单线程的,不是线程安全的。
这意味着你不应该阻塞事件分发线程,比如使用`Thread.sleep`,也不应该在事件分发线程之外更新UI或UI依赖的属性。
你应该阅读 [Swing中的并发性](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html) ,这会为你提供更多信息。
下一个问题是你拼写错误了`painComponent`,应该是 `paintComponent`。这里使用`@Override`标记你认为你在重写的方法非常重要,因为如果在父类中不存在该方法,它会生成编译错误。
```java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SimpleAnimation {
int x = 70;
int y = 70;
int tick = 0;
public static void main(String[] args) {
SimpleAnimation gui = new SimpleAnimation();
gui.go();
}
public void go() {
System.out.println("go");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel mdp = new MyDrawPanel();
frame.getContentPane().add(mdp);
frame.setSize(300, 300);
frame.setVisible(true);
System.out.println("go");
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tick++;
if (tick > 129) {
((Timer)e.getSource()).stop();
}
x++;
y++;
mdp.repaint();
}
});
timer.start();
}
class MyDrawPanel extends JPanel {
public MyDrawPanel() {
setBackground(Color.WHITE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}
英文:
Swing is single threaded and not thread safe.
This means that you should not block the event dispatching thread with things like Thread.sleep
and you should not update the UI or properties the UI relies on from outside of the event dispatching thread.
You should read through Concurrency in Swing which will provide you with more information.
The next issue is you've misspelt painComponent
, it should be paintComponent
. This is where using @Override
to mark methods you thinking you're overriding is important, as it will generate a compiler error if not method exists in the parent classes
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class SimpleAnimation {
int x = 70;
int y = 70;
int tick = 0;
public static void main(String[] args) {
SimpleAnimation gui = new SimpleAnimation();
gui.go();
}
public void go() {
System.out.println("go");
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel mdp = new MyDrawPanel();
frame.getContentPane().add(mdp);
frame.setSize(300, 300);
frame.setVisible(true);
System.out.println("go");
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tick++;
if (tick > 129) {
((Timer)e.getSource()).stop();
}
x++;
y++;
mdp.repaint();
}
});
timer.start();
}
class MyDrawPanel extends JPanel {
public MyDrawPanel() {
setBackground(Color.WHITE);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}
答案2
得分: 1
你的MyDrawPanel没有覆盖(override)paintComponent
方法(你漏掉了一个't'),应该是:
@Override
public void paintComponent(Graphics g) {
请注意,(可选的)@Override
注解会在你有拼写错误的情况下产生编译错误,所以加上它是个好习惯。
英文:
Your MyDrawPanel does not override the paintComponent
method (you missed a 't'), this should be:
@Override
public void paintComponent(Graphics g) {
Note that the (optional) @Override
annotation yields a compile error in case you have a typo, so it's good practice to add it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论