You Are Here:

Community: Developer Discussion Boards

#1 Old Repaint calls ignored in paint method on S40 - 2003-07-22, 22:26

Join Date: May 2003
Posts: 72
sam.hendley
Offline
Regular Contributor
Why are repaint calls ignored in the paint method on the series 40 series? No other phone does this. Anyone know a work around? Attached is a complete midlet that shows the problem. Press the "0" key and you only see one rectangle. Now press the "4" key which only calls repaint again and you see the second rectangel it shoudl have drawn.
Code:
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class RepaintTest extends MIDlet {
    private MainCanvas myCanvas;
    private Display myDisplay;
    public RepaintTest() {
        myCanvas = new MainCanvas();
        myDisplay = Display.getDisplay(this);
    }
    public void startApp()
            throws MIDletStateChangeException {
        myDisplay.setCurrent(myCanvas);
        myCanvas.repaint();
    }			
    public void pauseApp() {}
    public void destroyApp(boolean unconditional) {}

    class MainCanvas extends Canvas {
   		public int repainttest3 = 0;
        public void paint(Graphics g) {
			if(repainttest3==2){
				g.setColor(255,0,255);
				g.fillRect(45,67,58,23);
				repainttest3 = 0;
			}
			if(repainttest3==1){
				g.setColor(0,255,255);
				g.fillRect(12,34,58,23);
				repainttest3++;
				repaint();
			}	
        }
        public void keyPressed(int key){
			if(key == Canvas.KEY_NUM0){
        		repainttest3 = 1;	
        		repaint();	
        	}
        	if(key == Canvas.KEY_NUM4){
				repaint();
			}
        }
    }
}
Reply With Quote

#2 Old 2003-07-23, 09:35

Join Date: Jul 2003
Posts: 1,094
Location: Finland, Tampere
doctordwarf
Offline
Super Contributor
sam.hendley
Ok, here you are.
I even had to run your code trying to solve it, what a shame :) (kidding)

There are two things you should know:
1. Repaint requests gather at some System stack and phone does repainting when it has time. Series40 phones are pretty idle with it unfortunately :( If you need to repaint now, use serviceRepaints() method.

2. Repainting itself does not erase previous image. You should paint background color yopurself.

After considering this two things, everything works normally :)
Reply With Quote

#3 Old 2003-07-23, 22:04

Join Date: May 2003
Posts: 72
sam.hendley
Offline
Regular Contributor
You have misunderstood what this demo was supposed to show. I wasnt saying anything about the background repainting or not. What I was trying to show is that the code doent behave in the logical fashion that every other device does. On this device the calls to repaint() from inside paint are ignored. If you try this exact code on other devices you see the two rectangles appear with one button press. If you add a serviceRepaints() call after the repaint() in the painting code it works; *BUT* this doesnt "flush the screen buffer". By "flush the screen buffer" I mean the way that painting commands are not actually sent to the screen until the paint method exits. This is a major problem if you are trying to show a loading screen while loading your graphics and stuff. Here is a slightly modified version of the Main Canvas from below. Try it out, try uncommenting the serviceRepaints(); line and seeing what happens.
Code:
    class MainCanvas extends Canvas {
   		public int repainttest3 = 0;
        public void paint(Graphics g) {
			if(repainttest3==2){
				g.setColor(255,0,255);
				g.fillRect(45,67,58,23);
				repainttest3 = 0;
			}
			if(repainttest3==1){
				g.setColor(0,255,255);
				g.fillRect(12,34,58,23);
				repainttest3++;
				repaint();
				//serviceRepaints();
			}	
        }
        public void keyPressed(int key){
			if(key == Canvas.KEY_NUM0){
        		repainttest3 = 1;	
        		repaint();	
        	}
        	if(key == Canvas.KEY_NUM4){
				repaint();
			}
			if(key == Canvas.KEY_NUM5){
				serviceRepaints();
			}
        }
    }
Reply With Quote

#4 Old 2003-07-24, 09:25

Join Date: Jul 2003
Posts: 1,094
Location: Finland, Tampere
doctordwarf
Offline
Super Contributor
sam.hendley
Oh, now I see your problem.

Why are repaint calls ignored in the paint method on the series 40 series?

Don't blame me really hard, I've read this part of docs rather long ago, but as I remeber it's up to phone how to decide when it has time for launching paint(). He also can stack several repaint() request together and call your paint() only once.
I guess that Series40 phones clear this stack of painting request after finishing paint() method.

If I'm not mistaken this is correct behaviour. Although other phones behave in other way, this also conforms to specifications.

This is a major problem if you are trying to show a loading screen while loading your graphics and stuff.
Anyone know a work around?

1. I can propose calling serviceRepaints() - this will make repaint() behave similar to wthat you got used to.
2. Otherwise you can load graphics and stuff not inside your paint handler. You may create some variable to count persentage of loaded stuff, increment it step by step and call repaint() after (serviceRepaint() might be also needed). Inside paint() draw animation according to load persentage.

Hope this will help :)
Reply With Quote

#5 Old 2003-07-24, 16:28

Join Date: May 2003
Posts: 72
sam.hendley
Offline
Regular Contributor
Thanks for your input dd. I have come to the same conclusion about the repaint queue being cleared at the end of paint. I think that this is a violation of the MIDP specs though, a call to repaint() should always mean that a call to paint() is going to be made in the future, but there is little point in arguing about it, were stuck with what Nokia gave us. Here is a workaround that works for what I was trying to do, its ugly as anything but it works and it means I don't have to alter the code that works on the other five devices.
Code:
class MainCanvas extends Canvas {
	MIDlet midp;
	public MainCanvas(MIDlet midp){
		this.midp = midp;
	}
	class forcedRepainter implements Runnable{
		  public forcedRepainter(){ }
		  public void run(){
		   		repaint();
		  }
	}
	private forcedRepainter fr;
	public int repainttest3 = 0;
    public void paint(Graphics g) {
		if(repainttest3==2){
			g.setColor(255,0,255);
			g.fillRect(45,67,58,23);
			repainttest3 = 0;
		}
		if(repainttest3==1){
			g.setColor(0,255,255);
			g.fillRect(12,34,58,23);
			repainttest3++;
			//repaint();
			//serviceRepaints();
			fr = new forcedRepainter();
			Display.getDisplay(midp).callSerially(fr);
		}	
    }
Reply With Quote

#6 Old 2003-07-26, 07:45

Join Date: Mar 2003
Posts: 20
jozart
Offline
Registered User
repaint() simply marks the entire canvas as dirty and repaint(x,y,w,h) marks the specified region as dirty.

When paint() is called, the internal Graphics clip rectangle will be set to the accumulated dirty region of all previous repaint requests, and the dirty region will be cleared.

paint either happens periodically based on a timer, or on demand (by one or more repaint calls), but there is not a one-to-one correspondence between repaint and paint.

If a one-one correspondence is desired, use serviceRepaints.
Reply With Quote
Reply « Previous Thread | Next Thread »
Display Modes
Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules

You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Forum Jump

Rate This

 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZidentifierQSxhttpE3aE2fE2fdiscussionE2eforumE2enokiaE2ecomE2fforumE2fshowthreadE2ephpE3ftE3d134434X qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE44iscussionQ qdcZtypeQUqfntypeZE44iscussionContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qfnZtopicQUqfnTopicZentertainmentQ qfnZtopicQUqfnTopicZj2meQ qfnZtopicQUqfnTopicZjavaQ qfnZtopicQUqfnTopicZmediaQ qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE44iscussionQ qfnZtypeQUqfntypeZE44iscussionContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE44iscussionQ qrdfZtypeQUqfntypeZE44iscussionContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ