You Are Here:

Community: Developer Discussion Boards

#1 Old Threads and setCurrent problem in Nokia 6600 - 2004-08-28, 12:30

Join Date: Jul 2004
Posts: 8
Clocklabs Ltd
Offline
Registered User
Hi,

I have a problem with the Display.setCurrent() method in the Nokia 6600. My app contains a List which enables the user to drill down and navigate in a tree of options: when she selects an item, the midlet fetchs the suboptions for the selected option and update the List with the new options. Updating the list takes about a second, and the user can see the old items being deleted and the new items being added. This does not look very good, so I try to perform the update off-screen. When the user selects an item, I use setCurrent to switch the display to an empty Form, then I signal a blocked thread to fetch the new options and to update the List. When this is done, I call setCurrent again to switch back to the List.

Now the problem: sometimes, the screen is blocked on the empty screen. This happen fairly often. According to the traces, the updates and the setCurrent calls are performed correctly. In this precise case, it seems that updating the options is so fast that the List is redisplayed before the empty screen, leading to the following behavior:
-- The user selects an item,
-- The List is updated on-screen,
-- The empty Screen is displayed and the screen stays blank.

So I'm thinking that calls to setCurrent are not correctly serialized by the JVM.

This behavior happens only in the 6600 and in the Nokia MIDP SDK 2.1 beta. It works fine in all the other emulors and phones.

Any idea to solve this problem that would not look like a hack (like slowing down the app or always update the list offscreen)?

If you want to experiment the problem first hand, you can download a trial version from my WAP site: wap.clocklabs.com. Please drop me an email if you need a registration code.

Best Regards,
David
--------------------

Lost in the Tube? Download PocketMetro 2.0 to your mobile phone and never get lost again!
Reply With Quote

#2 Old 2004-08-29, 12:37

Join Date: Mar 2003
Posts: 87
dmford
Offline
Regular Contributor
Have you tried calling repaint() and serviceRepaints() on the screen afterwards ?

I also have a Thread.yield() before any repainting to ensure other operations (including key events) have finished.

So try this after set Current(..) :

Thread.yield();
myScreen.repaint();
myScreen.serviceRepaints();
Reply With Quote

#3 Old 2004-08-29, 13:18

Join Date: Jul 2004
Posts: 8
Clocklabs Ltd
Offline
Registered User
@dmford

Thanks for you answer but it does not apply to my case, because I'm using List and Forms (subclasses of Screen) instead of a Canvas.

Regards,
David
Reply With Quote

#4 Old 2004-08-29, 15:04

Join Date: Mar 2003
Posts: 87
dmford
Offline
Regular Contributor
Sorry about that, I thought all screens had those methods.

Have you tried adding an ItemStateListener to your Form which could monitor the state or the List ?
Reply With Quote

#5 Old 2004-08-29, 16:19

Join Date: Jul 2004
Posts: 8
Clocklabs Ltd
Offline
Registered User
@dmford

Hum, the part that handle the selection is fine, the problem really lies with the Display.setCurrent() method (or so I think).

Best Regards,
David
Reply With Quote

#6 Old 2004-08-29, 16:46

Join Date: Mar 2003
Posts: 2,280
Location: Israel
shmoove
Offline
Forum Nokia Champion
Quote:
When the user selects an item, I use setCurrent to switch the display to an empty Form, then I signal a blocked thread to fetch the new options and to update the List. When this is done, I call setCurrent again to switch back to the List.
Would you mind posting the code where you do all this?

I would suggest that all the displayable changes be performed in the same thread so that you can be sure that they are being called in the correct order: when an option is selected you signal the blocked thread, and this thread is the one to set the empty Form, fetch the new options, and then set the displayable to the updated list.

shmoove
Reply With Quote

#7 Old an offer - 2004-08-30, 15:44

Join Date: Aug 2004
Posts: 8
omerbilalorhan
Offline
Registered User
to make your screen wait when another thred is running ;
you should try using an alert


Alert alert=new Alert(...);

//staf to modify your Alert

display.setCurrent( alert , this );

//i assumed this code will be called in a Form
//and "this" means a displayable in this situation

You can set an estimated timeout for Alert,

However my reply doesnt directly relavant to your problem ,
really look great in midlet.
Reply With Quote

#8 Old 2004-08-30, 22:27

Join Date: Jul 2004
Posts: 8
Clocklabs Ltd
Offline
Registered User
@shmoove

The mystery thickens...

The JavaDoc for setCurrent() says:
Quote:
Calls to setCurrent() are not queued. A delayed request made by a setCurrent() call may be superseded by a subsequent call to setCurrent(). For example, if screen S1 is current, then


d.setCurrent(S2);
d.setCurrent(S3);

may eventually result in S3 being made current, bypassing S2 entirely.
This is not consistent with the behavior I'm observing.

I made a small demo midlet:
Code:
package com.clocklabs.bugdemo;

import java.util.Random;
import javax.microedition.lcdui.*;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.List;
import javax.microedition.midlet.*;

public class Demo extends MIDlet implements CommandListener
{
    private Form emptyUI= null;
    private List randomList = null;
    private Random random=null;
    public Demo()
	{
	    random = new Random();
	    emptyUI = new Form("EmptyUI");
	    randomList = new List("RandomList", List.IMPLICIT);
	    randomList.setCommandListener(this);	    
	}

    protected void destroyApp( boolean p1 ) throws MIDletStateChangeException
	{
	}
    
    protected void startApp(  ) throws MIDletStateChangeException
	{
	    updateList();	    
	}
    
    protected void pauseApp(  )
	{
	}

    public void commandAction( Command p1, Displayable p2 )
	{
	    updateList();
	}

    private void updateList(){
	System.out.println("Displaying EmptyUI");
	 Display.getDisplay(this).setCurrent(emptyUI);
	/* Generate some random entries. */
	int[] keys = new int[10];
	
	for(int i =0; i<keys.length;i++){
	    keys[i]= random.nextInt();
	}

	synchronized (randomList) {
            /* Delete all the components in this list. */
            for (int i = randomList.size() - 1; i >= 0; i--) {
                randomList.delete(i);
            }
        
	    /* Add the new ones. */
            for (int i = 0, max = keys.length; i < max; i++) {
                randomList.append(""+keys[i], null);
            }
	}
	
	System.out.println("Displaying RandomList");
	 Display.getDisplay(this).setCurrent(randomList);	
	System.out.println("Done updating");
    }
    

}
For your convenience, you can download the package midlet from here:
BugDemo.jar and BugDemo.jad

(Don't try this on a real phone, there is no exit button).

It seems pretty straightforward and is very similar to the actual code of the PocketMetro midlet. But it does not work according to what the spec says.

It works fine with the 3300 emu (Series 40), however, with the Series 60 2.1 SDK and both versions of the WTK, the phones blocks on the emptyUI: when updateList() method is called through the commandAction, the phone does not "redisplay" the randomList.
According to the spec, the phone may skip the emptyUI, but it should display the last Screen passed to setCurrent()


It seems so simple... Am I missing something here? Am I only allowed one call to setCurrent per event?

Best Regards,
David
Reply With Quote

#9 Old Try this one. - 2004-08-31, 17:16

Join Date: Aug 2004
Posts: 8
omerbilalorhan
Offline
Registered User
I made a bit change on your code it works fine in emulator , i am sure will look even better in your phone (6600 ) .

I think when you change the display with setCurrent(); method it deallocates the previus displayable or does something similar
iwork on a project that has lots of forms and canvas's etc. When i pass to options form from main menu it s fine but returning back made me sick(because it didnt).I had to create a new main menu to return.

you should find a good solution for navigating between those forms.
(i have a solution but some kind of dummy sure you can find better one)

Back to your prob. try the code below:


///////////////////////////////////////////////////////////////////////////


import java.util.Random;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

public class Demo extends MIDlet implements CommandListener
{
Command command=new Command("random table",Command.OK,2);//just for appereance
private Form emptyUI= null;
private List randomList = null;
private Random random=null;
public Demo()
{
random = new Random();
// emptyUI = new Form("EmptyUI");

randomList = new List("RandomList", List.IMPLICIT);
randomList.setCommandListener(this);
randomList.addCommand(command);// adding command to list
}

protected void destroyApp( boolean p1 ) throws MIDletStateChangeException
{
}

protected void startApp( ) throws MIDletStateChangeException
{
updateList();
}

protected void pauseApp( )
{
}

public void commandAction( Command p1, Displayable p2 )
{

if(p1 == command)
updateList();
}

private void updateList(){
System.out.println("Displaying EmptyUI");

//makes the screen wait for a time
Alert alert = new Alert("simple alert");
alert.setString("List is being prepaired...");

Display.getDisplay(this).setCurrent(alert);

/**You can make your alert much more specific with enabling below two lines..*/
//alert.setTimeout(5000);
//alert.setType(AlertType.CONFIRMATION);



// Display.getDisplay(this).setCurrent(emptyUI);
/* Generate some random entries. */
int[] keys = new int[10];

for(int i =0; i<keys.length;i++){
keys[i]= random.nextInt();
}

synchronized (randomList) {
/* Delete all the components in this list. */
randomList.deleteAll();
/*
for (int i = randomList.size() - 1; i >= 0; i--) {
randomList.delete(i);
}*/

/* Add the new ones. */
for (int i = 0, max = keys.length; i < max; i++) {
randomList.append(""+keys[i], null);
}
}

System.out.println("Displaying RandomList");
Display.getDisplay(this).setCurrent(randomList);
System.out.println("Done updating");
}


}
///////////////////////////////////////////////////////////////



i hope it helps.
Reply With Quote

#10 Old 2004-08-31, 21:07

Join Date: Jul 2004
Posts: 8
Clocklabs Ltd
Offline
Registered User
@omerbilalorhan

Thanks for your input. The solution with Alert does work but I'm not fully satisfied. The Alert expires after a adjustable amount of time, but I can't make it expires early. Since the amount of time required to update the list varies between 0 and 1s (according to the state of the midlet and the speed of the phone), I can't really hardcode a value: browsing this List must be smooth and quick, with very few pauses.

So it works in low-end phones but it breaks on high-end phones. Neat. I'm thinking that this may be a problem with the Monty VM. It works on my N-Gage, 6310 in the 3300 emu (traditional VM) and in many other phones while it breaks in the 6600 and in the Series 60 SDK 2.1 (Monty VM).

Anyway, thanks for your help and see you around.

Best Regards,
David
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