如何在JPanel中使用Swing计时器 [英] How to use a swing Timer with JPanel
问题描述
我非常确定我了解摆动计时器的工作原理,只是无法弄清楚如何在代码中应用它.在我的代码中应用它的方式不允许它绘制,因为Graphics g不在其范围内.
I'm fairly sure I understand how a swing timer works, I just cannot figure out how to apply it in my code. The way I apply it in my code doesn't allow it to draw because Graphics g is outside of its scope.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class JayFrame extends JFrame
{
public JayFrame()
{
super("My Frame");
setContentPane(new DrawPane());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1200, 675);
setResizable(false);
setVisible(true);
}
class DrawPane extends JPanel
{
Timer timer = new Timer(1000, new MyTimer());
public void paintComponent(Graphics g)
{
//Paint stuff
super.paintComponent(g);
timer.start();
for(int i = 0; i < 1000; i += 110)
{
g.fillRect(i, 10, 100, 100);
try{Thread.sleep(100);}
catch(InterruptedException ie){}
}
timer.stop();
}
}
class MyTimer implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//Loop stuff
repaint();
}
}
public static void main(String[] args)
{
new JayFrame();
}
}
我已经更新了代码以显示我认为应该起作用的代码,但是没有.因此,我可能对摆动计时器的理解确实有误.
I have updated the code to show what I think should work, but does not. So I probably do have a flawed understanding of swing timers.
推荐答案
- 不要在
paintComponent
方法中调用timer.start();
和/或timer.stop()
,这毫无意义,绘画可能出于多种原因发生,而您却无法控制. /li> - 不要在您的
paintComponent
中调用Thread.sleep
,这就是拥有Timer
的关键所在.您只是在阻止Swing更新屏幕或处理任何新事件 - Don't call
timer.start();
and/ortimer.stop()
in thepaintComponent
method, this makes no sense what so ever, painting may occur for any number of reasons, my of which you have no control over. - Don't call
Thread.sleep
in yourpaintComponent
, that's the point of have theTimer
. You're just preventing Swing from updating the screen or process any new events
Timer
充当伪循环,在Timer
的每次迭代中,您都会更新一些状态,检查一些退出条件,然后对应该发生的事情做出决定.
Timer
acts as a psudo loop, on each iteration of the Timer
, you update some state, check some exit condition and make your decisions about what should happen.
paintComponent
仅绘制当前状态.
例如:
import java.awt.EventQueue;
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;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class JayFrame extends JFrame {
public JayFrame() {
super("My Frame");
setContentPane(new DrawPane());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(1200, 675);
setResizable(false);
setVisible(true);
}
class DrawPane extends JPanel {
private int x = 0;
public DrawPane() {
Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
x += 110;
if (x >= 1000) {
x = 1000;
((Timer)e.getSource()).stop();
}
repaint();
}
});
timer.start();
}
public void paintComponent(Graphics g) {
//Paint stuff
super.paintComponent(g);
g.fillRect(x, 10, 100, 100);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
new JayFrame();
}
});
}
}
这篇关于如何在JPanel中使用Swing计时器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!