带有Timer的Java变色图形

时间:2015-10-28 13:31:16

标签: java swing graphics timer

我想画一张每秒两次改变颜色的光盘。磁盘在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();

    }

}

2 个答案:

答案 0 :(得分:2)

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

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

  1. 将变量discColor添加到您的JPanel

  2. 将您的绘图代码更改为不使用计时器,而是简化,只需根据discColor

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

答案 1 :(得分:2)

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

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);
    }
}