带有Timer的Java变色图形

我想画一张每秒两次变色的光盘。 磁盘在DrawPanel上绘制,它延伸了JPanel,在main方法中,DrawPanel被添加到框架中。 对于颜色变换,我使用一个计时器,当我试图改变主方法中的DrawPanel的背景时(我注释掉了)。

有人可以告诉我为什么它不适用于Graphics g对象或任何其他建议吗?

我只是从main方法复制代码并将其添加到paintComponent()方法中,但在这里它不起作用。

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.Timer; public class DrawPanel extends JPanel{ public GridBagLayout gbl; //position and dimension int x = 0, y = 0, width = 200, height = 200; public DrawPanel(){ repaint(); } public DrawPanel(GridBagLayout gridBagLayout) { this.gbl = gridBagLayout; } public void paintComponent(Graphics g){ //Overwriting of old picture super.paintComponent(g); ActionListener action = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Random gen = new Random(); Color color = new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)); //Draw color disk g.setColor(color); g.fillArc(x, y, width, height, 0, 360); } }; Timer t = new Timer(500, action); t.setRepeats(true); t.setInitialDelay(0); t.start(); //Draw boundary of circle g.setColor(Color.BLACK); g.drawArc(x, y, width, height, 0, 360); } public static void main(String[] args) { final JFrame frame = new JFrame(); frame.setSize(300, 300); final DrawPanel panel = new DrawPanel(); panel.setOpaque(true); frame.getContentPane().add(panel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); // ActionListener action = new ActionListener() { // @Override // public void actionPerformed(ActionEvent e) { // Random gen = new Random(); // Color color = new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)); // panel.setBackground(color); // } // }; // // Timer t = new Timer(500, action); // t.setRepeats(true); // t.setInitialDelay(0); // t.start(); } } 

Graphics对象是瞬态的,因此即使编译器允许,也不应该缓存它。 而是在类的构造函数中建立计时器,设置面板的BG,然后调用重绘。 例如

 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Random; public class DrawPanel extends JPanel { Random gen = new Random(); //position and dimension int x = 0, y = 0, width = 200, height = 200; Color drawColor = Color.BLACK; public DrawPanel() { repaint(); ActionListener action = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Color color = new Color(gen.nextInt(256), gen.nextInt(256), gen.nextInt(256)); //Draw color disk drawColor = color; DrawPanel.this.repaint(); } }; Timer t = new Timer(500, action); t.setRepeats(true); t.setInitialDelay(0); t.start(); } @Override public void paintComponent(Graphics g) { //Overwriting of old picture super.paintComponent(g); //Draw boundary of circle g.setColor(drawColor); g.drawArc(x, y, width, height, 0, 360); } public static void main(String[] args) { final JFrame frame = new JFrame(); frame.setSize(300, 300); final DrawPanel panel = new DrawPanel(); panel.setOpaque(true); frame.getContentPane().add(panel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } } 

图形对象仅对该一次绘制有效

最好是告诉JPanel更改它的当前颜色(带变量),然后告诉它重新绘制

  1. 将变量discColor添加到JPanel

  2. 更改您的绘图代码不使用计时器,而是简化,只需基于discColor绘制光盘

  3. 使用计时器,更新discColor变量,然后调用面板的repaint()方法