简体   繁体   中英

How to implement color change for a Graphic2D object in Java?

I am trying to understand if it is possible to change the color of existing graphics while my application runs, (something of a flicker between multiple different colors).

I have a start shape that is drawn out using the GeneralPath class and I also have my a random RGB color code selector working properly. Is it possible to change the color maybe with using repaint(); to have the color of my star change between the 3 selected colors which were randomly selected from my createRandomColor() method?

Code

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import static java.lang.Math.random;
import java.util.Vector;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Sandbox extends JApplet {
    DrawingStar canvas;

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        Sandbox path = new Sandbox();
        path.init();
        frame.getContentPane().add(path);
        frame.setSize(250, 250);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public void init() {
        Container container = getContentPane();
        canvas = new DrawingStar();
        container.add(canvas);
    }

}

class DrawingStar extends Canvas {
    Vector generalPaths;
    private List<Color> colors;

    public DrawingStar() {
        colors = new ArrayList<Color>();

        for (int i = 0; i < 3; i++) {
            colors.add(createRandomColor());
        }

        setBackground(Color.white);
        setSize(400, 400);
        generalPaths = new Vector();

        GeneralPath gp1;

        gp1 = new GeneralPath();
        gp1.moveTo(50, 120);
        gp1.lineTo(70, 180);
        gp1.lineTo(20, 140);
        gp1.lineTo(80, 140);
        gp1.lineTo(30, 180);
        gp1.closePath();
        generalPaths.addElement(gp1);
    }

    public void paint(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        g2D.translate(70.0f, -85.0f);
        g2D.draw((GeneralPath) generalPaths.elementAt(0));

        for (int i = 0; i < 3; i++) {
            Color color = colors.get(i);
            g2D.setColor(color);
            g2D.fill((GeneralPath) generalPaths.elementAt(0));
        }

        System.out.println("Is this working");
        repaint();
    }


    private Color createRandomColor(){
        int r = (int) (Math.random() * 256);
        int g = (int) (Math.random() * 256);
        int b = (int) (Math.random() * 256);
        Color color = new Color(r,g,b);

        return color;
    }

}

Applets are dead, long live HTML5

Time to move on...also, applet lifecycles are a lot more complicated then you've implemented.

An "alternative"

Canvas is a low level component which is probably not well suited to your needs. It's also not double buffered, so you're going to get flickering when it's repainted.

Don't call repaint from within any paint method, you won't like the results. Instead, schedule an update to occur at some point in the future.

This example simply makes use of a Swing Timer to act as a pseudo loop, which increments a counter and gets the next color and call's repaint, every second.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Sandbox {

    DrawingStar canvas;

    public static void main(String[] args) {
        new Sandbox();
    }

    public Sandbox() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                canvas = new DrawingStar();
                frame.getContentPane().add(canvas);
                frame.setSize(250, 250);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }

    class DrawingStar extends JPanel {

        Vector generalPaths;
        private List<Color> colors;
        private int colorIndex = 0;
        private Color color;

        public DrawingStar() {

            colors = new ArrayList<Color>();

            for (int i = 0; i < 3; i++) {
                colors.add(createRandomColor());
            }

            color = colors.get(0);

            setBackground(Color.white);
            generalPaths = new Vector();

            GeneralPath gp1;

            gp1 = new GeneralPath();
            gp1.moveTo(50, 120);
            gp1.lineTo(70, 180);
            gp1.lineTo(20, 140);
            gp1.lineTo(80, 140);
            gp1.lineTo(30, 180);
            gp1.closePath();
            generalPaths.addElement(gp1);

            Timer timer = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    colorIndex++;
                    if (colorIndex >= colors.size()) {
                        colorIndex = 0;
                    }

                    color = colors.get(colorIndex);
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
            Graphics2D g2D = (Graphics2D) g;
            g2D.translate(70.0f, -85.0f);
            g2D.draw((GeneralPath) generalPaths.elementAt(0));

            g2D.setColor(color);
            g2D.fill((GeneralPath) generalPaths.elementAt(0));
        }

        private Color createRandomColor() {
            int r = (int) (Math.random() * 256);
            int g = (int) (Math.random() * 256);
            int b = (int) (Math.random() * 256);
            Color color = new Color(r, g, b);

            return color;
        }

    }
}

Swing is NOT thread safe and is single threaded, hence the reason for using a Swing Timer

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM