Tuesday, June 17, 2008

Implementing A Selected Item Ticker In A List


A discussion came up in the LWUIT forum/list regarding animating list items e.g. ticker functionality where the selected element in the list is animated. This is a confusing subject because the renderer paradigm inspired by Swing doesn't allow a state and thus doesn't allow animations. So the List component itself must be animated. However if you want to animate a specific item you must implement the animation logic in the renderer code thus decoupling the functionality.
This is a bit counter intuitive but there are complexities when creating an efficient/scalable list thats infinitely customizable... Once you accept the basic premise of renderers this approach makes allot of sense.

Notice that the renderer in the code bellow is not really animated but rather allows the list (which is) to paint its state. Also notice that the list animate() method takes care to invoke its super class otherwise list traversal animations would break.
Form f = new Form("Ticker List");
class TickerRenderer extends DefaultListCellRenderer {
private int position;
public void resetPosition() {
position = 0;
}
public void incrementPosition() {
position += 5;
}

public void paint(Graphics g) {
if(hasFocus()) {
String text = getText();
Style s = getStyle();
int width = s.getFont().stringWidth(text);
if(getWidth() >= width) {
super.paint(g);
return;
}
UIManager.getInstance().getLookAndFeel().setFG(g, this);
int actualPosition = position % width;
g.translate(-actualPosition, 0);
g.drawString(text, getX() + s.getPadding(LEFT), getY());
g.translate(width + 20, 0);
g.drawString(text, getX(), getY());
g.translate(actualPosition - 20 - width , 0);
} else {
super.paint(g);
}
}

public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {
super.getListCellRendererComponent(list, value, index, isSelected);
return this;
}
}
final TickerRenderer renderer = new TickerRenderer();
List myList = new List(new String[] {"First", "Second", "Really long string that goes on and on and on and on and on and on",
"and on and on and on and on and on and on and on and on and on and on and on and on",
"Well enough already with the damn long strings this is really getting old...",
"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 !!!!....."}) {
private long tickTime = System.currentTimeMillis();
private int lastSelection = -1;
public boolean animate() {
boolean val = super.animate();
if(hasFocus()) {
long currentTime = System.currentTimeMillis();
if(currentTime - tickTime > 300) {
if(lastSelection == getSelectedIndex()) {
renderer.incrementPosition();
} else {
lastSelection = getSelectedIndex();
renderer.resetPosition();
}
return true;
}
}
return val;
}
};
myList.setListCellRenderer(renderer);
f.setLayout(new BorderLayout());
f.addComponent(BorderLayout.CENTER, myList);
f.show();

16 comments:

  1. shai,
    I'm trying LWUIT in one of our application. There were issues with the Text wrapping and word wrapping in Text area earlier. When I checked out the SVN code on this Monday the issues were solved but now the test area has become extreamly slow, especially when long text has been appended in Text Area. is LWUIT team already aware of this issue? r u going to fix this? When can we have the fixed build?

    ReplyDelete
  2. please when the items greater than the height of the screen this causes UP and Down scrolling Problems .

    please if u have a class that handle scroll list up and down with selected item Ticker send it to me .

    adel.salama2010@gmail.com

    please help me soon

    thanks alot

    ReplyDelete
  3. Disable the scrolling for the form as explained in the developer forum multiple times.

    ReplyDelete
  4. This works well with one line of code [form.setScrollable(false);].


    Thank you for your help. :)

    ReplyDelete
  5. Hi all ,

    please i need to change the aligment of the text and the ticker to be from right to left . how can i do this .

    please help me .

    Adel Salama

    ReplyDelete
  6. sorry , i need also to know how can i remove the number that written before each list Item for example [1.First] i need it to be [First]without 1.

    please replay me soon .

    ReplyDelete
  7. There is a constructor for the default cell renderer that allows you to avoid the numbers there are also methods to determine alignment.

    ReplyDelete
  8. Shai,
    i'm trying it and it works very well.
    but now i need to make list ticker text to be from left to right as in my application i have an arabic Rss List News and need to ticker them from left to right , i tried to change the position of the text using those two methods incrementPosition() and resetPosition() at TickerRenderer Class but it is not efficient there exist delay and other problems .

    please help me .

    and thanks a lot every time .

    ReplyDelete
  9. Bidi/RTL support is problematic for the label widget, the draw label method fails with right alignment and due to its complexity its very hard to fix.
    You can try fixing this by overriding the paint method.

    ReplyDelete
  10. Shai I´m using lwuit.

    I´ve a List question.

    In a few oportunities I needed to put a "separator" between list elements.

    It is possible?

    I think a lot of dirty solutions but I want to know if a elegant one exists.

    Tks a lot

    Regards

    Santiago.

    ReplyDelete
  11. Most separators in list are hacks I have one such hack here:
    http://lwuit.blogspot.com/2008/09/cooking-with-lwuit-movie.html

    ReplyDelete
  12. Hi Shai,

    i am j2me dev and now learning lwuit.
    if i have list with 2000 element, alpha sorted order, and i want to provide ajax like functionality where end user will type first 2-3 char and it will show relavant element of list (may be starting with those char.)

    i have implemented this in j2me using choice group and text box (as in j2me you cant have textbox/textfield and list on same form), however in lwuit this kind of functionality is possible ?

    1. to have textbox/field and list on same form (can list be part of form/tabpane?)
    2. if yes/no, can ajax like list possible in lwuit ?

    Thanks
    Raxit Sheth
    raxit(at)m4mum(dot)com

    ReplyDelete
  13. Hi Shai,
    This article is very helpful in case of having Lists with just a Label. But since my List renderer has to deal with complex layouts, I'm trying to avoid messing with the paint() method.
    Is there anyway to achieve this by implementing the Ticker to a char level? It's to say, the Ticker advances one char per iteration, and I just set the proper text to the label and call the super paint method.
    How difficult do you think it that?
    Regards.

    ReplyDelete
  14. I just saw the IODemo, with an example on how to achieve what I just asked, to be more specific, the ResultRenderer.
    So consider my question answered.

    ReplyDelete
  15. I have read so many posts about the blogger lovers except this paragraph is really a fastidious paragraph, keep it up.Forum list

    ReplyDelete
  16. Thank you for sharing this artcle. I share this blog with my friends. Keep on posting like this article.
    global payments

    ReplyDelete