问题
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();
}
}
EDIT: 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.
回答1:
- 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
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
simply paints the current state.
For example:
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();
}
});
}
}
来源:https://stackoverflow.com/questions/32753169/how-to-use-a-swing-timer-with-jpanel