Dom*_*lic 5 java swing timer paint
我Timer之前从未使用过s,所以我的问题可能真的很愚蠢.我的程序绘制一个红色的圆圈,随机秒后圆圈应将其颜色更改为绿色.我刚刚制作了一个摆动计时器,你可以在下面的代码中看到.它进入actionPerformed()方法,但它不会改变颜色.你能帮我改变一下颜色吗?
我的代码:
package igrica;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ChangingCircle implements ActionListener{
JFrame frame;
Timer timer;
Random r;
public static void main(String[] args) {
ChangingCircle gui = new ChangingCircle();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
class MyPanel extends JPanel {
public void paintComponent(Graphics g) {
g.setColor(Color.red);
g.fillOval(100, 100, 100, 100);
Random r = new Random();
Timer timer = new Timer(r.nextInt(5000) + 1000, new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.out.println("Timer out");
g.setColor(Color.green);
g.fillOval(100, 100, 100, 100);
}
});
timer.start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你的代码中有很多混乱.试试这个:
public class ChangingCircle {
Color color = Color.RED;
MyPanel panel = new MyPanel();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
ChangingCircle gui = new ChangingCircle();
gui.go();
});
}
public void go() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
Random r = new Random();
Timer timer = new Timer(r.nextInt(5000) + 1000, new ActionListener() {
public void actionPerformed(ActionEvent ev) {
System.out.println("Timer");
color = Color.GREEN;
panel.repaint();
}
});
timer.setRepeats(false);
timer.start();
}
class MyPanel extends JPanel {
private int size = 100, loc = 100;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(color);
g.fillOval(loc, loc, size, size);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(size + loc, size + loc);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个想法是计时器只改变要绘制的形状的属性,然后调用repaint()以反映更改.该paintComponent每当它是必要的,即使是在连续快速和应该很快返回被调用.
具体说明:
paintComponent因为它被多次调用,这将创建并启动许多计时器.super.paintComponent(g);是里面的第一件事paintComponent.ActionListener什么也没做.一般提示:
@Override适用时使用注释.pack()框架而不是手动设置其大小和您绘制的组件@Override的getPreferredSize方法.根据您绘制的内容返回有意义的大小.add(component, location)而不是相反(弃用).Random r例如)不要使用字段.Color.RED而不是Color.red).不要在paintComponent方法中启动Timer.此方法仅适用于绘画和绘画.而是在构造函数中启动Timer并在Timer的actionPerromed中调用repaint(),更改类的字段状态,并在paintComponent中使用该信息使用该字段来绘制任何新信息.
例如
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ChangingCircle {
JFrame frame;
public static void main(String[] args) {
ChangingCircle gui = new ChangingCircle();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.setSize(300, 300);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
class MyPanel extends JPanel {
private Random r = new Random();
private boolean draw = false;
public MyPanel() {
Timer timer = new Timer(r.nextInt(5000) + 1000, new ActionListener() {
public void actionPerformed(ActionEvent ev) {
draw = true;
repaint();
}
});
timer.setRepeats(false);
timer.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (draw) {
g.setColor(Color.red);
g.fillOval(100, 100, 100, 100);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
另外,不要忘记在覆盖中调用super的paintComponent方法.
如果你需要改变颜色,给JPanel一个Color字段,比如调用color并从Timer中改变它的值,然后调用repaint().同样在paintComponent中,使用该字段的值来绘制椭圆.同样在这种情况下,Timer 应该重复,所以摆脱timer.setRepeats(false)那种情况.