Swing_Frame_无法获取动画代码的输出

huangapple go评论104阅读模式
英文:

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(&quot;go&quot;);
        		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(&quot;go&quot;);        	
        		for(int i=0;i&lt;130;i++) {        			
        			x++;
        			y++;
              			mdp.repaint();        			
        			System.out.println(&quot;go&quot;);        			
        			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(&quot;go&quot;);
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(&quot;go&quot;);
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
tick++;
if (tick &gt; 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.

huangapple
  • 本文由 发表于 2020年9月10日 14:58:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/63824319.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定