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 10 of 10

Thread: Drawing in applets. Tell me why this way is wrong.

  1. #1
    Member
    Join Date
    Jun 2010
    Posts
    48
    Thanks
    12
    Thanked 2 Times in 2 Posts

    Default Drawing in applets. Tell me why this way is wrong.

    CHECK MY LAST POST FOR A BETTER CODE EXAMPLE

    Hello,
    I tried to draw a game on an applet and got huge flickering. The way I am drawing is:
    I create an off-screen image of applet size, get its graphics, draw the objects on it I want to display with drawMaze and drawScore methods and in the end draw that off-screen image on the applet.
    	public void paint(Graphics g) {
    		super.paint(g);
     
    		if(gOff == null) {
    			gOffImage = createImage(d.width, d.height);
    			gOff = gOffImage.getGraphics();
    		}
     
    		gOff.setColor(Color.BLACK);
    		gOff.fillRect(0, 0, d.width, d.height);
    		drawMaze();
    		drawScore();
     
    		g.drawImage(gOffImage, 0, 0, this);
    	}

    The program updates the image with thread. I simply put repaint() in the thread and sleep for a particual delay time. This way I get very big flickering.
    public void run() {
    		long timeBefore = System.currentTimeMillis();
    		Thread thread2 = Thread.currentThread();
    		while(thread == thread2) {
    			repaint();
    			long timeDifference = System.currentTimeMillis() - timeBefore;
    			int sleep = gameDelay - (int)timeDifference;
    			if(sleep < 0) sleep = 2;
    			try {
    				thread.sleep(sleep);
    			} catch(InterruptedException ex) {
    				ex.printStackTrace();
    			}
                        timeBefore = System.currentTimeMillis();
    		}
    	}

    After looking at some examples I notice another way of "repaint'ing", which looks like this:
    public void run() {
    		Graphics g = getGraphics();
    		long timeBefore = System.currentTimeMillis();
    		Thread thread2 = Thread.currentThread();
    		while(thread == thread2) {
    			paint(g);
    			long timeDifference = System.currentTimeMillis() - timeBefore;
    			int sleep = gameDelay - (int)timeDifference;
    			if(sleep < 0) sleep = 2;
    			try {
    				thread.sleep(gameDelay);
    			} catch(InterruptedException ex) {
    				ex.printStackTrace();
    			}
                         timeBefore = System.currentTimeMillis();
    		}
    	}

    I tried it and it worked. No flickering at all.
    So I want to understand: why this way there is no flickering? What is the difference between calling repaint() and paint(g) methods? Why repaint() produces flickering and paint(g) not? Doesn't repaint() just simply calls paint() method?
    Last edited by Asido; July 31st, 2010 at 05:59 PM.


  2. #2
    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: Drawing in applets. Tell me why this way is wrong.

    I don't know why it does what it does.
    Can you create a small program that demos the problem and post it here?

    Could it be that the sleep duration is different in the two pieces of code you posted.
    What is the difference in values between the variables: sleep and gameDelay

  3. #3
    Member
    Join Date
    Jun 2010
    Posts
    48
    Thanks
    12
    Thanked 2 Times in 2 Posts

    Default Re: Drawing in applets. Tell me why this way is wrong.

    The gameDelay is 40. I tryed to put System.out.println(sleep) and it showed most of the time 30+. But it is interesting that if I type repaint() instead of paint(g), sleep is always equals to gameDelay - 40, but produces the flickering. The full code consists of nearly 1000 lines, so I don't think that you want to look at all this
    The thing is, lets say in the run method:
    public void run() {
    		Graphics g = getGraphics();
    		long timeBefore = System.currentTimeMillis();
    		Thread thread2 = Thread.currentThread();
    		while(thread == thread2) {
    			paint(g);
    			long timeDifference = System.currentTimeMillis() - timeBefore;
    			int sleep = gameDelay - (int)timeDifference;
    			if(sleep < 0) sleep = 2;
    			try {
    				thread.sleep(sleep);
    			} catch(InterruptedException ex) {
    				ex.printStackTrace();
    			}
    			timeBefore = System.currentTimeMillis();
    		}
    	}
    It is enough to replace paint(g) with update(g) or repaint() and I get flickering. So I want to understand why is so? Sleep time has nothing to do with that. I can set it to 1 and with paint(g) in the run method I will see totally smooth animations with 0 flickering, only 40 times faster. But if I change to repaint(), with 1 delay I could hardly see anything in the applet. Huge flickering only.
    Last edited by Asido; July 31st, 2010 at 04:35 PM.

  4. #4
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,318
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Drawing in applets. Tell me why this way is wrong.

    I'd say it has to do with two things. First, you are directly accessing the Graphics object from another thread, and drawing to that graphics, in effect asynchronously drawing the GUI, while the system is doing its own drawing using the single threaded model, you are stepping in and possibly disrupting that (according to the API, getGraphics 'creates' a Graphics context, which may also result in the creation of additional graphics objects for the component being divided between what the component is drawing, and what you are drawing to) Second, swing components are double buffered by default. Calling repaint takes advantage of this (regardless of whether you are drawing offscreen - see point 1).
    Last edited by copeg; July 31st, 2010 at 04:59 PM.

  5. #5
    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: Drawing in applets. Tell me why this way is wrong.

    Can you create asmall program that demos the problem and post it here?

  6. #6
    Member
    Join Date
    Jun 2010
    Posts
    48
    Thanks
    12
    Thanked 2 Times in 2 Posts

    Default Re: Drawing in applets. Tell me why this way is wrong.

    Quote Originally Posted by copeg View Post
    I'd say it has to do with two things. First, you are directly accessing the Graphics object from another thread, and drawing to that graphics, in effect asynchronously drawing the GUI, while the system is doing its own drawing using the single threaded model, you are stepping in and possibly disrupting that. Second, swing components are double buffered by default. Calling repaint takes advantage of this (regardles of whether you are drawing offscreen - see point 1).
    1. There is one active thread only. The one I created in the run method is just the way to stop the main one since thread.stop() method is deprecated.
    2. This is applet. I use AWT, not Swing.

    But what I have noticed is that repaint() happens immediately while calling paint(g) takes nearly 10ms.
    Furthermore, what I read in java.sun website:
    repaint():
    If this component is a lightweight component, this method causes a call to this component's paint  method as soon as possible. Otherwise, this method causes a call to this component's update method as soon as possible.
    So I guess in my case it calls update(g) method, which gives me flickering.

  7. #7
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,318
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Drawing in applets. Tell me why this way is wrong.

    a) See the edit to my post about calling getGraphics

    b) What do you mean there is only one thread? Does this include the EDT? Are you calling Thread.start at any time during your program? As norm stated, a short program to reproduce this would easily answer all these questions

  8. #8
    Member
    Join Date
    Jun 2010
    Posts
    48
    Thanks
    12
    Thanked 2 Times in 2 Posts

    Default Re: Drawing in applets. Tell me why this way is wrong.

    Quote Originally Posted by Norm View Post
    Can you create asmall program that demos the problem and post it here?
    Ok, I made the mini demo program the same way I did my game. The result is the same: if in run method I call repaint() - i get huge flickering. And if I call paint(g) - I get smooth applet without any flickering even without sleep.
    import java.applet.Applet;
    import java.awt.Color;
    import java.awt.Image;
    import java.awt.Dimension;
    import java.awt.Graphics;
     
    public class Demo extends Applet implements Runnable {
    	Graphics gOff;
    	Image image;
    	Thread thread;
    	Dimension d;
     
    	public void init() {
    		d = getSize();
    		image = createImage(d.width, d.height);
    		gOff = image.getGraphics();
    		thread = new Thread(this);
    		thread.start();
    	}
     
    	public void paint(Graphics g) {
    		gOff.setColor(Color.BLACK);
    		gOff.fillRect(0, 0, d.width, d.height);
    		g.drawImage(image, 0, 0, this);
    	}
     
    	public void run() {
    		Graphics g = getGraphics();
    		while(true) {
    //			update(g); //huge flickering
    //			repaint(); //huge flickering
    			paint(g); //none flickering
    		}
    	}
    }
    The main reason I am asking it is that I have always used repaint() and first time encounter the problem, even though in my eyes these two ways of repainting are exactly the same. I want to know what difference is there? Where exactly that flickering comes from? I am wondering perhaps to call paint(g) is better instead of repaint() in all cases?
    EDIT: I have read that when update methods is called, first it clears the component by filling it with the background color, then sets the color of the graphics context to be the foreground color of the component and finally calls the component's paint method to completely redraw this component. So I guess If I don't want/need to clear the existing draws, simply call paint(g)?
    Last edited by Asido; July 31st, 2010 at 05:43 PM.

  9. #9
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,318
    Thanks
    181
    Thanked 833 Times in 772 Posts
    Blog Entries
    5

    Default Re: Drawing in applets. Tell me why this way is wrong.

    I actually misread your original post to think you were saying the opposite. Sorry bout that. Now that you posted the small example its more clear, however I don't see any flickering with any of the calls (using appletviewer).

  10. #10
    Member
    Join Date
    Jun 2010
    Posts
    48
    Thanks
    12
    Thanked 2 Times in 2 Posts

    Default Re: Drawing in applets. Tell me why this way is wrong.

    Hmm, that is really strange. I managed to make a screen how my screen flickers when repaint is being called. As I said, in my case repaint() calls the method update(), which first clears the component by filling it with the background color, then sets the color of the graphics context to be the foreground color of the component and finally calls the component's paint method to completely redraw this component. So I guess it depends on performance of the PC.
    Last edited by Asido; August 1st, 2010 at 02:14 PM.

Similar Threads

  1. Applets
    By santiagomez in forum Java Theory & Questions
    Replies: 2
    Last Post: July 31st, 2010, 04:05 PM
  2. Help needed with applets
    By Brt93yoda in forum What's Wrong With My Code?
    Replies: 16
    Last Post: July 12th, 2010, 07:36 PM
  3. Drawing
    By toxikbuni in forum Java Theory & Questions
    Replies: 0
    Last Post: April 20th, 2010, 02:43 PM
  4. Audioclip play makes applets slow
    By Marcus in forum What's Wrong With My Code?
    Replies: 0
    Last Post: February 19th, 2010, 01:20 PM
  5. Learn applets in java
    By mohsendeveloper in forum Java Applets
    Replies: 2
    Last Post: June 25th, 2009, 02:50 PM