问题
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 thepaintComponentmethod, 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.sleepin 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