带定时器的Java变色图形
我想画一张每秒改变两次颜色的光盘。磁盘在DrawPanel上绘制,DrawPanel扩展了JPanel,在主方法中,DrawPanel被添加到一个框架中。 对于颜色更改,我使用了一个计时器,当我试图在main方法中更改DrawPanel的背景时,它会起作用(我注释掉了它) 有人能告诉我为什么它不适用于图形g对象或任何其他建议吗 我只是从main方法复制了代码并将其添加到paintComponent()方法中,但在这里它不起作用带定时器的Java变色图形,java,swing,graphics,timer,Java,Swing,Graphics,Timer,我想画一张每秒改变两次颜色的光盘。磁盘在DrawPanel上绘制,DrawPanel扩展了JPanel,在主方法中,DrawPanel被添加到一个框架中。 对于颜色更改,我使用了一个计时器,当我试图在main方法中更改DrawPanel的背景时,它会起作用(我注释掉了它) 有人能告诉我为什么它不适用于图形g对象或任何其他建议吗 我只是从main方法复制了代码并将其添加到paintComponent()方法中,但在这里它不起作用 import java.awt.*; import java.awt
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();
}
}
图形对象仅对该绘图有效 最好是告诉JPanel更改它的当前颜色(使用一个变量),然后告诉它重新绘制
discColor
添加到JPaneldiscColor
discColor
变量,然后调用面板的repaint()
方法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);
}
}
paint方法不在我们的直接控制范围内,当JVM感觉需要重新绘制UI时,可能会调用它,这可能是由于许多不同的条件造成的。这不是建立新计时器的时候!我认为你误解了其中的一部分,背景没有改变,光盘的颜色也没有改变。另外,我认为
setBackground
可能会自动重新绘制面板以进行更新,我在电脑前必须检查一下。为了让事情清楚,我只想更改光盘的颜色,而不想更改背景的颜色。背景颜色应保持其默认颜色。我只是在后台试用了一下,看看是否正确使用了计时器。@mabu,您应该为类创建一个属性,如setDiscColor(…)
。然后,当计时器触发时,调用此方法将属性设置为随机颜色。然后setDiscColor(…)方法将调用repaint()。然后在绘制方法中,使用“光盘颜色”属性绘制光盘。绘制方法不应随机设置颜色,因为您无法控制何时调用绘制方法。@AndrewThompson,谢谢,将g.drawArc(x,y,width,height,0,360)更改为g.fillArc(..)会按我的要求运行它,至少在主方法的给定帧中是这样。不幸的是,在GUI中使用这个drawPanel只能在使用GridbagLayout时起到一半的作用。说到一半,我的意思是,只有一部分的光盘改变颜色,但两个“角落”没有。调整窗口大小会改变整个圆圈的颜色,但当下一次颜色改变时,我也会遇到同样的问题。有什么建议说明这两件事为什么不一致吗?“有什么建议…”我建议你(在新的消息线程上)问一个新问题。