Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 20 of 20

Thread: How to animate a circle changing color

  1. #1
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default How to animate a circle changing color

    Hi, this is simple but I can't get it it to work. I want an initially yellow circle to then alternate b/t colors of green and blue. And also why can's I use the parameterized repaint method, it doesn't compile if I use it. Any help please.

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
     
    @SuppressWarnings("serial")
    public class Circle_Practice extends JFrame {
     
    	private int node_height = 30;//imaginary rectangle's ht to draw the circle
    	private int node_width = 30;//imaginary rectangle's width to draw the circle 
    	private int canvas_width = 360;//width of JFrame
    	private int canvas_height = 360;//height of JFrame
    	private int start_x = (canvas_width/2) - node_width/2;
    	private int start_y = 10;
    	private int delay = 200;
    	private int count = 0;
     
    	public Circle_Practice(int[] arr )
    	{
    		this.add( new Canvas() );
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.setVisible(true);
    		this.pack();
     
    		Timer t = new Timer(delay, new ActionListener() {//Timer is the listener
     
    			public void actionPerformed(ActionEvent e)
    			{
    				while ( count < 20_000 )
    				{
    					if ( count % 2 == 0 )
    					{
    						dummy_change_to_green();//why doesn't the red circle change color?
    						repaint(/**ball_x, ball_y, ball_width, ball_height*/);//how do I only redraw necessary updates and not entire screen, so just the updated circle and not the background too?
    						count++;
    					}
    					else
    					{
    						dummy_change_to_blue();
    						repaint();
    						count++;
    					}
    				}
    			}
     
    		});
     
    		t.start();
    	}
     
    	//dummy method to practice Swing timer
    	//change border to red...doesn't work...
    	private void dummy_change_to_green()//(Graphics2D g2d)
    	{
    		g2d.setColor(Color.GREEN);
    		g2d.drawOval(start_x, start_y, node_width, node_height);		
    	}
     
    	private void dummy_change_to_blue()//(Graphics2D g2d)
    	{
    		g2d.setColor(Color.BLUE);
    		g2d.drawOval(start_x, start_y, node_width, node_height);		
    	}
     
    	//draw the initial binary heap here only
    	private class Canvas extends JPanel
    	{
    		public Canvas() {
    	        setBorder(BorderFactory.createLineBorder(Color.black));
    	    }
     
    	    public Dimension getPreferredSize() {//overridden method (to draw inside Canvas, NOT JFrame)
    	        return new Dimension(360,360);
    	    }
     
    		public void paintComponent(Graphics g)//NB: paintComponent is a method that I override from JPanel class (which I extend)
    		{
    			super.paintComponent(g);//Q:why do I need this again? A:
    			//	 Most of the standard Swing components have their look & feel
    			//	implemented by separate "UI Delegate" objs. The invocation of super.paintComponent(g) passes the graphics context off to the component's 
    			//	UI delegate, which paints the panel's background (src: http://docs.oracle.com/javase/tutorial/uiswing/painting/step2.html)
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    			//draw first node centered to canvas
    			g2d.setColor(Color.YELLOW);
     
    			g2d.fillOval(start_x, start_y, node_width, node_height);
     
    			g2d.setColor(Color.BLACK);
    			g2d.drawOval(start_x, start_y, node_width, node_height);
     
    			g2d.drawString("80", start_x + 5, start_y + 15);
     
    			//gist: draw all the nodes and wait for some delay before beginning heap sort (to call update_nodes method)
     
    		}
    	}
    }


  2. #2
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: How to animate a circle changing color

    What are you doing in your dummy methods? Specifically, what are you actually setting the color of? Does this even compile?

    Recommended reading: Lesson: Performing Custom Painting (The Java™ Tutorials > Creating a GUI With JFC/Swing)
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  3. #3
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    I want to change the color of the circle. I passed as param a Graphics obj in order to work with the same object, but it's not animating the colors to alternate between green and blue, starting initially with color of yellow. It doesn't compile because I don't know if I should put the Timer which is the listener and so it implements the actionPerformed method is in constructor, but my dummy methods for changing colors need a reference to the Graphics object to draw it or does the Timer doesn't have to be inside constructor? *It doesn't compile** Appreciate how to get this going.

    *I want to draw in JPanel, and I want to build a Swing animation application so I want to not use applet

  4. #4
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    I want an initially yellow circle to then alternate b/t colors of green and blue.
    Use a couple of binary variables: firstTime and doGreen and some if statements to catch the firstTime for the yellow and then toggle the doGreen to control green and blue.
    If you don't understand my answer, don't ignore it, ask a question.

  5. #5
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    Quote Originally Posted by Norm View Post
    Use a couple of binary variables: firstTime and doGreen and some if statements to catch the firstTime for the yellow and then toggle the doGreen to control green and blue.
    So I shouldn't be using thread and timer? Currently I just alternate by checking the remainding of the count so if a number has no remainder by using mod operation, then change to this color else change to that color but that's not my concern. I'm trying to build a simple selection sort so I want to eventually draw more circles and I want the circles that are currently being swapped to flash a color. But at the moment I just need help to figure out how to use timer to show alternating colors and I am also stuck with how to pass the same Graphics object in the dummy_methods that change the circle to green or blue where I have parameter in order to reference the same Graphics object? Any help appreciated.

  6. #6
    Super Moderator curmudgeon's Avatar
    Join Date
    Aug 2012
    Posts
    1,130
    My Mood
    Cynical
    Thanks
    64
    Thanked 140 Times in 135 Posts

    Default Re: How to animate a circle changing color

    Myself, I'd simply create an array of Color, say, Color colorArray = {Color.RED, Color.BLUE, Color.Green, Color.ORANGE}; and would give the class an int variable, say called colorIndex, and then using a Swing Timer, increment the colorIndex, mod it by the size of the colorArray, get the Color in the array for the new index, and fill the circle with it:

    // in the timer's ActionListener's actionPerformed method:
     
    colorIndex++;
    colorIndex %= colorArray.length;  // colorIndex is a class int field
    color = colorArray[colorIndex];  // color is a class Color field
    repaint();

  7. #7
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    Yes, much better. An array of colors and modulus to pick one.
    If you don't understand my answer, don't ignore it, ask a question.

  8. #8
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    I'll try that but also which way is preferred or does it not matter, so I mean should I create instance of ActionListener object and separate instance of Timer obj or should I just do former with Timer object with parameter of inner class of ActionListener?
    public void paintComponent(Graphics g)
    {
            super.paintComponent(g);
     
            final Graphics2D g2d = (Graphics2D)g;
     
    			//draw first node centered to canvas
    			g2d.setColor(Color.YELLOW);
     
    			g2d.fillOval(start_x, start_y, node_width, node_height);
     
    			g2d.setColor(Color.BLACK);
    			g2d.drawOval(start_x, start_y, node_width, node_height);
     
    			g2d.drawString("80", start_x + 5, start_y + 15);
    /**Should below be a new Timer or should it be an ActionListener in the other code snippet??*/
    			Timer t = new Timer(delay, new ActionListener() {//Timer is the listener
     
    				public void actionPerformed(ActionEvent e)
    				{
    						dummy_change_color(g2d);
    						repaint(/**ball_x, ball_y, ball_width, ball_height*/);//how do I only redraw necessary updates and not entire graphics for the yellow circle?
     
    				}
    t.start();
     
    	});

    VERSUS

    public void paintComponent(Graphics g)
    {
      super.paintComponent(g);
      /**
       etc as same as first code snippet in this current reply
      **/
    			ActionListener listener = new ActionListener(){
    				  public void actionPerformed(ActionEvent event){
    					  dummy_change_color(g2d);
    					  repaint(/**ball_x, ball_y, ball_width, ball_height*/);
    				  }
    				};
    				Timer displayTimer = new Timer(1000, listener);
    				displayTimer.start();
     
     
    		displayTimer.start();


    --- Update ---

    appreciate everyone's input, but I just tried with an array of Color object, but to no luck, this is what I have so far:

    main[
    import java.util.*;
    import java.awt.*;
    import javax.swing.*;
     
    //NB: invokeLater places the Runnable you pass to it into the EDT event queue and waits until the EDT has
    //	executed it. This should be used when a non-GUI thread needs to do something that affects the GUI, but 
    //	also needs to wait until it is actually done before it can continue.
    public class Heap_sort_Runner
    {
    	public static void main(String[] args)
    	{
    		SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     new Circle_Change_Color(); 
                }
            });		
    }

    JFrame that holds a JPanel (which in turn does all the actual drawing)
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
     
    @SuppressWarnings("serial")
    public class Circle_Change_Color extends JFrame {
     
    	private int node_height = 30;//imaginary rectangle's ht to draw the circle (node)
    	private int node_width = 30;//imaginary rectangle's width to draw the circle (node)
    	private int canvas_width = 360;//width of JFrame
    	private int canvas_height = 360;//height of JFrame
    	private int start_x = (canvas_width/2) - node_width/2;
    	private int start_y = 10;
    	private int delay = 200;
    	private Color color_arr[] = {Color.BLUE, Color.GREEN};
    	private int cur_index = 0;//to point to current index in the Color array
     
    	public Circle_Change_Color( )
    	{		
    		this.add( new Canvas() );
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.setVisible(true);
    		this.pack();
     
     
    	}	
     
    	//draw the initial binary heap here only
    	private class Canvas extends JPanel
    	{
    		public Canvas() {
    	        setBorder(BorderFactory.createLineBorder(Color.black));
    	    }
     
    	    public Dimension getPreferredSize() {//overridden method (to draw inside Canvas, NOT JFrame)
    	        return new Dimension(360,360);
    	    }
     
    		public void paintComponent(Graphics g)//NB: paintComponent is a method that I override from JPanel class (which I extend)
    		{
    			super.paintComponent(g);//Q:why do I need this again? A:
    			//	 Most of the standard Swing components have their look & feel
    			//	implemented by separate "UI Delegate" objs. The invocation of super.paintComponent(g) passes the graphics context off to the component's 
    			//	UI delegate, which paints the panel's background (src: http://docs.oracle.com/javase/tutorial/uiswing/painting/step2.html)
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    			//draw first node centered to canvas
    			g2d.setColor(Color.YELLOW);
     
    			g2d.fillOval(start_x, start_y, node_width, node_height);
     
    			g2d.setColor(Color.BLACK);
    			g2d.drawOval(start_x, start_y, node_width, node_height);
     
    			g2d.drawString("80", start_x + 5, start_y + 15);
     
    			Timer t = new Timer(delay, new ActionListener() {//Timer is the listener
     
    				public void actionPerformed(ActionEvent e)
    				{
    						g2d.setColor( color_arr[cur_index % color_arr.length]  );//alternate circle's color between green and blue
     
    						repaint(/**ball_x, ball_y, ball_width, ball_height*/);//how do I only redraw necessary updates and not entire graphics for the red ball?
    						cur_index++;
    				}
     
    			});
     
    			t.start();		
    		}
    	}
    }
    This should seem simple, any help appreciated. Or should the Timer should not be inside the inner class: Canvas which extends JPanel and contains the paiintComponent method, I'll look up in meantime.

    --- Update ---

    I just realized I changed the color, but forgot to invoke fillOval, but even after doing so, no luck as it only shows up yellow circle still. I'd tear my hair out if I had long enough, this is frustrating. Here is what I have in my paintComponent method in the Circle_Change_Color class

    public void paintComponent(Graphics g)//NB: paintComponent is a method that I override from JPanel class (which I extend)
    		{
    			super.paintComponent(g);//Q:why do I need this again? Ans:
    			//	 Most of the standard Swing components have their look & feel
    			//	implemented by separate "UI Delegate" objs. The invocation of super.paintComponent(g) passes the graphics context off to the component's 
    			//	UI delegate, which paints the panel's background (src: http://docs.oracle.com/javase/tutorial/uiswing/painting/step2.html)
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    			//draw first node centered to canvas
    			g2d.setColor(Color.YELLOW);
     
    			g2d.fillOval(start_x, start_y, node_width, node_height);
     
    			g2d.setColor(Color.BLACK);
    			g2d.drawOval(start_x, start_y, node_width, node_height);
     
    			g2d.drawString("80", start_x + 5, start_y + 15);
     
    			ActionListener updateTask = new ActionListener() {//Timer is the listener
     
    				public void actionPerformed(ActionEvent e)
    				{
    					g2d.setColor( color_arr[cur_index % color_arr.length]  );//alternate circle's color between green and blue
     
    					g2d.fillOval(start_x, start_y, node_width, node_height);
     
    					g2d.setColor(Color.BLACK);
    					g2d.drawOval(start_x, start_y, node_width, node_height);
     
    					g2d.drawString("80", start_x + 5, start_y + 15);
     
    					cur_index++;
     
    					repaint();//
    				}
    			};
     
    			t = new Timer(delay, updateTask);
    			t.setInitialDelay(10_000);//wait 10s w/ initial circle of color yellow before starting green-and-blue color change animation
    			t.start();	
    		}

  9. #9
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    Can you post a small, complete program that compiles, executes and shows the problem. All these pieces of code are confusing.


    The Timer should not be created and started from inside the paintComponent() method.
    The decision on what color to use should be made outside of the paintComponent() method. For example the value of cur_index should be changed outside of the paintComponent() method and its value used in the method to select which color to use.
    If you don't understand my answer, don't ignore it, ask a question.

  10. #10
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    ok I moved the Timer to constructor, but currently it only displays the yellow circle. I also created a method to change color with a reference to same Graphics2D object. This is the complete compileable code.

    import javax.swing.*;
    import java.awt.*;
    import javax.swing.Timer;
    import java.awt.event.*;
     
    @SuppressWarnings("serial")
    public class Circle_Change_Color extends JFrame {
     
    	private int node_height = 30;//imaginary rectangle's ht to draw the circle (node)
    	private int node_width = 30;//imaginary rectangle's width to draw the circle (node)
    	private int canvas_width = 360;//width of JFrame
    	private int canvas_height = 360;//height of JFrame
    	private int start_x = (canvas_width/2) - node_width/2;
    	private int start_y = 10;
    	private int delay = 200;
    	private Color color_arr[] = {Color.BLUE, Color.GREEN};
    	private int cur_index = 0;
    	private int iterations = 0;
    	private Timer t = null;
    	private Color cur_color;
    	private ActionListener updateTask;
     
    	public Circle_Change_Color( )
    	{		
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.setVisible(true);
    		this.setResizable(false);
    		this.add( new Canvas() );
    		this.pack();
     
    		t = new Timer(delay, updateTask);
    		t.setInitialDelay(10_000);//wait 10s w/ initial circle of color yellow before starting green-and-blue color change animation
    		t.start();
    	}
     
    	public Color change_color(Graphics2D g2d)
    	{
    		cur_color = color_arr[cur_index % color_arr.length];
    		cur_index++;
    		return cur_color;
    	}
     
    	//draw the initial binary heap here only
    	private class Canvas extends JPanel
    	{
    		public Canvas() {
    	        setBorder(BorderFactory.createLineBorder(Color.black));
    	    }
     
    	    public Dimension getPreferredSize() {//overridden method (to draw inside Canvas, NOT JFrame)
    	        return new Dimension(360,360);
    	    }
     
    		public void paintComponent(Graphics g)
    		{
    			super.paintComponent(g);
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    			//draw first node centered to canvas
    			g2d.setColor(Color.YELLOW);
     
    			g2d.fillOval(start_x, start_y, node_width, node_height);
     
    			g2d.setColor(Color.BLACK);
    			g2d.drawOval(start_x, start_y, node_width, node_height);
     
    			g2d.drawString("80", start_x + 5, start_y + 15);
     
    			updateTask = new ActionListener() {//Timer is the listener
     
    				public void actionPerformed(ActionEvent e)
    				{
    					g2d.setColor( change_color(g2d) );//alternate circle's color between green and blue
     
    					g2d.fillOval(start_x, start_y, node_width, node_height);
     
    					g2d.setColor(Color.BLACK);
    					g2d.drawOval(start_x, start_y, node_width, node_height);
     
    					g2d.drawString("80", start_x + 5, start_y + 15);
     
    					repaint(/**wwwball_x, ball_y, ball_width, ball_height*/);//how do I only redraw necessary updates and not entire graphics for the red ball?
    				}
    			};		
    		}
    	}
     
    	//entry point
    	public static void main(String[] args) throws InvocationTargetException, InterruptedException
    	{
    		SwingUtilities.invokeLater(new Runnable() {//Q: what' difference w/ SwingUtitilities.invokeLater vs EventQueue.invokeLater? (look up later)
                public void run() {
                     new Circle_Change_Color(); 
                }
            });		
    	}
    }

  11. #11
    Crazy Cat Lady KevinWorkman's Avatar
    Join Date
    Oct 2010
    Location
    Washington, DC
    Posts
    5,424
    My Mood
    Hungover
    Thanks
    144
    Thanked 636 Times in 540 Posts

    Default Re: How to animate a circle changing color

    Stop putting ActionListeners inside your paintComponent() method.

    Setting the updateTask to a new ActionListener does not set the ActionListener that you passed into the Timer.

    All you need to do from your Timer ActionListener is increment what color should be used and then trigger a repaint.
    Useful links: How to Ask Questions the Smart Way | Use Code Tags | Java Tutorials
    Static Void Games - Play indie games, learn from game tutorials and source code, upload your own games!

  12. #12
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    Another problem I see i that the paintComponent() method ALWAYS sets the color to yellow.
    The call to setColor() should either be conditional: first yellow then toggle between the other two colors
    or the color to be used should be set by the timer method and used by paintComponent(). That could be done by having a Color variable that holds the color to be used. It would be set by the timer method and used by the painComponent() method.
    If you don't understand my answer, don't ignore it, ask a question.

  13. #13
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    Quote Originally Posted by KevinWorkman View Post
    Stop putting ActionListeners inside your paintComponent() method.

    Setting the updateTask to a new ActionListener does not set the ActionListener that you passed into the Timer.

    All you need to do from your Timer ActionListener is increment what color should be used and then trigger a repaint.
    How would I carry out the action performed since I need to pass the listener to the Timer in the constructor because I can't put the variable updateTask outside since it needs to reference the g2d Graphics2d object to change the same object's color, so I added an instance variable incrementer and switches between coloring the circle yellow or black but it still doesn't work. Here's what I have:

    public void paintComponent(Graphics g)//NB: paintComponent is a method that I override from JPanel class (which I extend)
    		{
    			super.paintComponent(g);
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    			updateTask = new ActionListener() {//Timer is the listener
     
    				public void actionPerformed(ActionEvent e)
    				{
    					if ( incrementer % 2 == 0 )
    					{
    						//draw first node centered to canvas
    						g2d.setColor(Color.YELLOW);
     
    						g2d.fillOval(start_x, start_y, node_width, node_height);
     
    						g2d.setColor(Color.BLACK);
    						g2d.drawOval(start_x, start_y, node_width, node_height);
     
    						g2d.drawString("80", start_x + 5, start_y + 15);
     
    						incrementer++;//this is an instance variable 
    					}
    					else
    					{
    						//draw first node centered to canvas
    						g2d.setColor(Color.BLUE);
     
    						g2d.fillOval(start_x, start_y, node_width, node_height);
     
    						g2d.setColor(Color.BLACK);
    						g2d.drawOval(start_x, start_y, node_width, node_height);
     
    						g2d.drawString("80", start_x + 5, start_y + 15);
    						incrementer++;
    					}
     
    					repaint();
    				}
    			};
    		}
    	}

  14. #14
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    it needs to reference the g2d Graphics2d object to change the same object's color,
    No it doesn't. The code in a method can set the value of a variable to tell the paintComponent() method what to do.
    When paintComponent() method executes, it can look at the variable's values to determine what to do.
    If you don't understand my answer, don't ignore it, ask a question.

  15. #15
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    I made a separate method (called change_color) that handles the color change and it compiles and runs but it's a blank canvas, here's the latest (I re-posted the entire class below)

    import javax.swing.*;
    import java.awt.*;
    import javax.swing.Timer;
    import java.awt.event.*;
    import java.lang.reflect.InvocationTargetException;
     
    @SuppressWarnings("serial")
    public class Circle_Change_Color extends JFrame {
     
    	private int node_height = 30;//imaginary rectangle's ht to draw the circle (node)
    	private int node_width = 30;//imaginary rectangle's width to draw the circle (node)
    	private int canvas_width = 360;//width of JFrame
    	private int canvas_height = 360;//height of JFrame
    	private int start_x = (canvas_width/2) - node_width/2;
    	private int start_y = 10;
    	private int delay = 200;
    	private Color color_arr[] = {Color.BLUE, Color.GREEN};
    	private int iterations = 0;
    	private Timer t = null;
    	private Color cur_color;
    	private ActionListener updateTask;
    	private int incrementer = 0;//used to alternate b/t odd et even int for which color to use
     
    	public Circle_Change_Color( )
    	{		
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.setVisible(true);
    		this.setResizable(false);
    		this.add( new Canvas() );
    		this.pack();
     
    		t = new Timer(delay, updateTask);
    		t.setInitialDelay(10_000);//wait 10s w/ initial circle of color yellow before starting green-and-blue color change animation
    		t.start();
    	}
     
    	public void change_color(final Graphics2D g2d)/**NEW METHOD I JUST ADDED*/
    	{
    		updateTask = new ActionListener() {//Timer is the listener
     
    			public void actionPerformed(ActionEvent e)
    			{
    				if ( incrementer % 2 == 0 )
    				{
    					//draw first node centered to canvas
    					g2d.setColor(Color.YELLOW);
     
    					g2d.fillOval(start_x, start_y, node_width, node_height);
     
    					g2d.setColor(Color.BLACK);
    					g2d.drawOval(start_x, start_y, node_width, node_height);
     
    					g2d.drawString("80", start_x + 5, start_y + 15);
     
    					incrementer++;
    				}
    				else
    				{
    					//draw first node centered to canvas
    					g2d.setColor(Color.BLUE);
     
    					g2d.fillOval(start_x, start_y, node_width, node_height);
     
    					g2d.setColor(Color.BLACK);
    					g2d.drawOval(start_x, start_y, node_width, node_height);
     
    					g2d.drawString("80", start_x + 5, start_y + 15);
    					incrementer++;
    				}
     
    				repaint();
    			}
    		};
    	}
     
    	//draw the initial binary heap here only
    	private class Canvas extends JPanel
    	{
    		public Canvas() {
    	        setBorder(BorderFactory.createLineBorder(Color.black));
    	    }
     
    	    public Dimension getPreferredSize() {//overridden method (to draw inside Canvas, NOT JFrame)
    	        return new Dimension(360,360);
    	    }
     
    		public void paintComponent(Graphics g)//paintComponent is a method that I override from JPanel class (which I extend)
    		{
    			super.paintComponent(g);
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    			change_color(g2d);
    		}
    	}
     
    	//entry point
    	public static void main(String[] args) throws InvocationTargetException, InterruptedException
    	{
    		SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     new Circle_Change_Color(); 
                }
            });		
    	}
    }

    **EDIT: ok, I had some typos, now it compiles and runs but nothing shows up in canvas**

  16. #16
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    The posted code does not compile without errors. Please fix the errors and repost.

    Moving the code to another method and calling that method from the paintComponent() method changes NOTHING. The code is still WRONG.
    If you don't understand my answer, don't ignore it, ask a question.

  17. #17
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    I just updated the latest code I had above, it so it compiles and runs, but nothing shows up in canvas. Appreciate it.

  18. #18
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    Moving the code to another method and calling that method from the paintComponent() method changes NOTHING. The code is still WRONG.

    The code in a method can set the value of a variable to tell the paintComponent() method what to do.
    When paintComponent() method executes, it can look at the variable's values to determine what to do.
    If you don't understand my answer, don't ignore it, ask a question.

  19. #19
    Member
    Join Date
    May 2011
    Posts
    61
    My Mood
    Busy
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: How to animate a circle changing color

    Appreciate today's encouragements, it works! This is what I did, so now I just have to have a longer timer delay. Thanks Norm. Another questions, I'm wanting to build a selection sort and the change colors is to flash for what items in the eventual animation I'll create is being dealt with at the moment but I was curious in general for any program I want to write should I stick with Java Swing all the way to build applications for GUI and animations rather than learn Java Applets or JApplets? Also, whenever I use a timer for animation, should I always place the timer as an inner class inside the constructor like below?

    import javax.swing.*;
    import java.awt.*;
    import javax.swing.Timer;
    import java.awt.event.*;
    import java.lang.reflect.InvocationTargetException;
     
    @SuppressWarnings("serial")
    public class Circle_Change_Color extends JFrame {
     
    	private int node_height = 30;//imaginary rectangle's ht to draw the circle (node)
    	private int node_width = 30;//imaginary rectangle's width to draw the circle (node)
    	private int canvas_width = 360;//width of JFrame
    	private int canvas_height = 360;//height of JFrame
    	private int start_x = (canvas_width/2) - node_width/2;
    	private int start_y = 10;
    	private int num_nodes;
    	private int delay = 1000;
    	private Color color_arr[] = {Color.BLUE, Color.GREEN};
    	private int iterations = 0;
    	private Timer t = null;
    	private Color cur_color;
    	private ActionListener updateTask;
    	private int incrementer = 0;//used to alternate b/t odd et even int for which color to use
     
    	public Circle_Change_Color( )
    	{		
    		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    		this.setVisible(true);
    		this.setResizable(false);
    		this.add( new Canvas() );
    		this.pack();
     
    updateTask = new ActionListener() {//Timer is the listener
     
    			public void actionPerformed(ActionEvent e)
    			{
    				incrementer++;
    				repaint();
    			}
    		};
     
    		t = new Timer(delay, updateTask);
    		t.setInitialDelay(10_000);//wait 10s w/ initial circle of color yellow before starting green-and-blue color change animation
    		t.start();
    	}
     
    	//draw the initial binary heap here only
    	private class Canvas extends JPanel
    	{
    		public Canvas() {
    	        setBorder(BorderFactory.createLineBorder(Color.black));
    	    }
     
    	    public Dimension getPreferredSize() {//overridden method (to draw inside Canvas, NOT JFrame)
    	        return new Dimension(360,360);
    	    }
     
    		public void paintComponent(Graphics g)//paintComponent is a method that I override from JPanel class (which I extend)
    		{
    			super.paintComponent(g);
     
    			final Graphics2D g2d = (Graphics2D)g;
     
    				if ( incrementer % 2 == 0)
    				{
    					//draw first node centered to canvas
    					g2d.setColor(Color.YELLOW);
     
    					g2d.fillOval(start_x, start_y, node_width, node_height);
    				}
    				else
    				{
    					//draw first node centered to canvas
    					g2d.setColor(Color.BLUE);
     
    					g2d.fillOval(start_x, start_y, node_width, node_height);
    				}
     
    				g2d.setColor(Color.BLACK);
    				g2d.drawOval(start_x, start_y, node_width, node_height);
     
    				g2d.drawString("80", start_x + 5, start_y + 15);
    			}			
    		}
     
    	//entry point
    	public static void main(String[] args) throws InvocationTargetException, InterruptedException
    	{
    		SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                     new Circle_Change_Color(); 
                }
            });
     
    	}
    }

  20. #20
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,140
    Thanks
    65
    Thanked 2,720 Times in 2,670 Posts

    Default Re: How to animate a circle changing color

    You shouldn't call repaint() from inside the painting method.

    Applets are web based.

    An inner class is useful for listeners.
    If you don't understand my answer, don't ignore it, ask a question.

Similar Threads

  1. JTextPane changing text color issues
    By donnierisk in forum What's Wrong With My Code?
    Replies: 1
    Last Post: April 30th, 2012, 11:29 AM
  2. How Do I Make Color Changing Buttons?
    By blurredvis0n in forum AWT / Java Swing
    Replies: 3
    Last Post: August 30th, 2011, 02:14 PM
  3. Need help with changing color of JOptionPane
    By jwise95 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: April 22nd, 2011, 09:49 AM
  4. Changing Panel Color with a ComboBox
    By bengregg in forum AWT / Java Swing
    Replies: 7
    Last Post: March 2nd, 2011, 10:04 PM
  5. changing the visited links color in JEditorpane
    By nasi in forum AWT / Java Swing
    Replies: 5
    Last Post: April 18th, 2010, 08:44 AM