In this post I will review the List Renderer to give you a better understanding what you can achive when you create your own Renderer to the List.
When we designed this widget we took the MVC separation model from Swing, that means we created a data model to encapsulate the data and a renderer to display the data items to the screen.
The renderer:
Let's have a closer look at the List Renderer, the Renderer is a simple interface with 2 methods:
public interface ListCellRenderer {
//This method is called by the List for each item, when the List paints itself.Now let's try to implement our own renderer's.
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected);
//This method returns the List animated focus.
public Component getListFocusComponent(List list);
}
The most simple/naive implementation may choose to implement the renderer as follows:
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected){
return new Label(value.toString());
}
public Component getListFocusComponent(List list){
return null;
}
This will compile and work, but won't give you much, notice that you won't see the List selection moves on the List, this is just because the renderer returns a Label with the same style regardless if it's being selected or not.
Now Let's try to make it a bit more useful.
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected){
Label l = new Label(value.toString());
if (isSelected) {
l.setFocus(true);
l.getStyle().setBgTransparency(100);
} else {
l.setFocus(false);
l.getStyle().setBgTransparency(0);
}
return l;
} public Component getListFocusComponent(List list){
return null;
}
In this renderer we set the Label.setFocus(true) if it's selected, calling to this method doesn't really gives the focus to the Label,
it is simply indicates to the LookAndFeel to draw the Label with fgSelectionColor and bgSelectionColor instead of fgColor and bgColor.
Then we call to Label.getStyle().setBgTransparency(100) to give the selection semi transparency and 0 for full transparency if not selected.
OK that's a bit more functional, but not very efficient that's because we create a new Label each time the method is called.
To make it more device friendly keep a reference to the Component or extend the Widget.
class MyRenderer extends Label{Now Let's have a look at a more advanced Renderer (This was taken from the LWUIT Scrolling Demo)
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected){
setText(value.toString());
if (isSelected) {
setFocus(true);
getStyle().setBgTransparency(100);
} else {
setFocus(false);
getStyle().setBgTransparency(0);
}
return this;
}
}
}
class ContactsRenderer extends Container implements ListCellRenderer {
private Label name = new Label("");
private Label email = new Label("");
private Label pic = new Label("");
private Label focus = new Label("");
public ContactsRenderer() {
setLayout(new BorderLayout());
addComponent(BorderLayout.WEST, pic);
Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS));
name.getStyle().setBgTransparency(0);
name.getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
email.getStyle().setBgTransparency(0);
cnt.addComponent(name);
cnt.addComponent(email);
addComponent(BorderLayout.CENTER, cnt);
focus.getStyle().setBgTransparency(100);
}
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected) {
Contact person = (Contact) value;
name.setText(person.getName());
email.setText(person.getEmail());
pic.setIcon(person.getPic());
return this;
}
public Component getListFocusComponent(List list) {
return focus;
}
}
In this renderer we want to renderer a Contact Object to the Screen, we build the Component in the constructor and in the getListCellRendererComponent we simply updates the Labels texts according to the Contact Object.
Notice that in this renderer I return a focus Label with semi transparency, as mentioned before the focus component can be modified by using this method.
For example I can modify the focus Component to have an icon.
focus.getStyle().setBgTransparency(100);
try {
focus.setIcon(Image.createImage("/duke.png"));
focus.setAlignment(Component.RIGHT);
} catch (IOException ex) {
ex.printStackTrace();
}
In the next post I will review the List Model
Chen
Hello Shai and Chen,
ReplyDeleteHow about doing a Label ticker in the list above, say the name is too long. I've done the label ticker in a Form by simply calling its startTicker method, but when i do that in the getListCellRendererComponent method of the ListCellRenderer, I get an IllegalArgumentException. Is this the right place to that? A code snippets will be of great help. Thanks!
You mean this:
ReplyDeletehttp://lwuit.blogspot.com/2008/06/implementing-selected-item-ticker-in.html
Thanks for the reply. I already saw your posted link before. Sorry to confuse you on what I'm trying to do. Since the Million Contacts March consists of several controls per list item, your link in its sense, won't work. I used the label.setShiftText in the getListCellRendererComponent method instead.
ReplyDeleteBut now I'm facing a slight problem- I can't get the ticker work like that of your label implementation on a form (say label.startTicker(100, true);), which scrolls (on the second pass) starting from the end of the screen when its last character is not visible anymore. Mine always start from 0 position. Here's my code snippet:
int titleWidth = container.getStyle().getFont().stringWidth(title.getText());
int visibleWidth = container.getLayoutWidth();
if (isSelected && (titleWidth > visibleWidth))
title.setShiftText(-(position % (title.getText().length() * 6)));
else
title.setShiftText(0);
position changes its value in list's animate method (just like your code). Thanks again!
I don't understand the question.
ReplyDeleteHello Shai,
ReplyDeleteThis is a great blog and answered all my queries on list except this one. In the LWUIT Demo - Scroll Demo Application I scroll in the List to the last record. But when I want to come scroll up from the last record, the list does not scroll. Is there some property for the same. Also I want to make the list Scroll to the first record from the last record. Is there any property that can help me with this.
Regards,
Shubham
I don't understand the first question, check that you are using the latest version from SVN.
ReplyDeleteFor cyclic scrolling use the fixed cyclic mode of the list.
Nice one, I just updated my LWUIT from SVN and I just tried creating a simple list and adding 100 labels to it. The list doesn't seem to scroll anymore.
ReplyDeleteOk my bad was too impatient. I did not read the million entry thingy about how the list work. I guess i need a list model.
ReplyDeleteYou don't need a model if your list doesn't scroll. Most likely you placed it in a scrollable form and didn't use a layout such as border layout. Please search the forum for this question, it is answered repeatedly.
ReplyDeletethx did not use cell renderer as well so obviously no painting.
ReplyDeleteform.setscrollable(false)
ReplyDeleteHi there. I was wondering, I need the list to autoscroll when new items are being populated to the list, so I have set the list to FIXED_TRAIL when the
ReplyDeletelist.getScrollDimension().getHeight() > list.getHeight() which I set to 7/10 of the screen size using the setPreferedHeight method.
This is my problem: Everything seems to go smoothly but once the list.getDimension.getHeight > list.getheight, it seems that the first element that was previously entered appears and stays at the bottom of the list. Is this an expected behaviour?
Many thanks.
I don't understand the question.
ReplyDeletehi Shai and Chen,
ReplyDeletei dnt get this one.
i want to add a Image to a list.
but List expects an Object.
so when i add a image to a list the hashcode of the image eill displayed.
how can i sort this out???
regards,
Randika
Did u read the tutorial ?
ReplyDeleteI'm trying to implement the thumbnail image on the focused item on the list. The thumbnail image have height bigger than list item height (the image is sliced to the height of the row), so how can I set the height of the focused item bigger and get displayed all the immage?
ReplyDeleteI'm trying to implement the thumbnail image on the focused item on the list. The thumbnail image have height bigger than list item height (the image is sliced to the height of the row), so how can I set the height of the focused item bigger and get displayed all the immage?
ReplyDelete@me4tatel See the renderer demo in LWUIT demo, select the Fisheye demo.
ReplyDelete@saini add an action listener to the list and in it change the state of the MODEL to reflect selection. When rendering use that state to invoke checkbox.setSelected.
ReplyDeleteWhat if the images in the Million Contacts are animated gifs ? Animated gifs look static when put inside a List. Is there any way around this ?
ReplyDeleteThanks
@The.JagaL: animated renderers are really mean the list should be animated and it should handle that. See the ticker post for examples of that...
ReplyDeleteMakes sense. But it actually only animates the currently selected item in the list. What if I need to animate an unselected item ?
ReplyDeleteThanks
I think I figured it out. I just had to override the list's animate method in addition to the renderer's animate method, unless there's an easier way ?
ReplyDeleteYou can disable all visual effects using the LookAndFeel/Form classes
ReplyDeleteHi!
ReplyDeleteFirst, thanks you for this tuto.
I have a question, how can I add buttons to the list and propagate touch/keys events?
Thanks and best regards!
u can just use a normal form for that . No need for a list.
ReplyDeletei want to add a set of buttons to a single tab of a Tabbedpane.so i am planning to add all these buttons to a list n then add this list to a particular tab.
ReplyDeletewhen i do this....i am displayed some internal representation of the button on the form. i have to override the toString() method.but i dont know where i have to do it.
can anybody help me plzz.
@Swetha: read the post.
ReplyDelete@DX: Try the UI demo, it performs fine on 5800 and has two labels and an image. Check your theme/images to see which is causing the slow down.
Hello all,i'm having a problem with scrolls in lwuit...
ReplyDeleteI have added a list to a form but when i press the down-key of a (non-touch phone) the scroll goes towards right side and shows me the last-part of the content of list and when i press the left key to view the start part of the list content,it doesnt go there.....what do i do?
I'm not sure what you are trying to describe. Try using the next focus left/right/up/down methods of component.
ReplyDeleteHey bro,
ReplyDeleteIn my form, there is first a label.. with an image, and then a container which has the list, but when i scroll down the list and come back up, the label won't show. It just vanishes. Can u help me please?
Its hard to tell without understanding the full details. Make sure you are using the latest LWUIT.
ReplyDeleteTry to reproduce this by adding a label to the north of the LWUIT demo scroll demo. Assuming it doesn't reproduce see the difference between that and your code.
Hi i have implement listrender with image and name like now i have to any one of the select list of item it should display another list can any one give solution for this
ReplyDeletepls how to implement listcellrender have another list can you pls guide me how to do this
ReplyDeleteLook at the LWUIT Demo scroll and renderer code.
ReplyDeleteHi shai,
ReplyDeleteI got a problem with the list.
I am generating a checkbox list dynamically.i use a use a separate class to store the state(selected or not) and the name of the checkbox.
i make an array out of the class an make it a model.
but when i make changes to array elements, how i can automatically refresh the list.ryt now the list react to earlier changes after i make a new change in the list..(Here i'm referring to selecting or unselecting a checkbox as a change )
How can i make the list auto refresh?..
pls reply..
When changing the model it should fire the model change event (see the default list model code) thus notifying the list it needs a refresh.
ReplyDeleteThe list will request the renderer over again which you can mark as selected/unselected.
I built a container list with 3 labels and 1 button. the button doesnt work. I looked around I didn't find anything useful for me. Please help me out
ReplyDeleteOk, so how can I use button or checkbox anyway?
ReplyDeletehey can you plz give me a simple list code with left side image and right side text
ReplyDeletewith implantation code
And one more problem i am facing
ReplyDeletewhen i remove all item and ad label with waiting text and send http request.
form dose not change until http request complete
means i cannot implement wait form ..
Look at the LWUITDemo for a sample.
ReplyDeleteYou are blocking the EDT on networking, use a thread and read up on the LWUIT EDT in the developer guide.
This comment has been removed by the author.
ReplyDeletehey can you give me sample code what to put before sending http request to
ReplyDeleteupdate my form i m using single thread app
i dont understand how to use Display methods callSerially, callSeriallyAndWait, and
invokeAndBlock etc..
actually i want to make Login form while sending authentication request i just want to show waiting image and text ..
help me to do so
i got the answer thanks ...
ReplyDeletebut still unable to to make simple list with image left side and text right side
done with image list ....
ReplyDeleteThanks for advise
Hi, I have problems on the ComboBox popup list theming. I've tried some component but nothing seems to work. How can I change the theme of those ComboBox popups?
ReplyDeleteMurugan
ReplyDeleteHello,Am getting Name and number from server database ,That one i want make it as a list view for example like contact viewing name and number know like that -please any one help me.
Thanks.
Hi Shai,
ReplyDeleteI'm having a problem in displaying very long lists(30 entries or more). On the screen, the list gets displayed in a compressed area. it looks like this.
---------------
item6
item7
item8
item9
item..
item..
item..
item..
item..
-------------
and the list consumes only half of the screen.
Im using the 'wood' theme in resource editor
can anyone create this example in a midlet so i can run and test this. i can't get any of this. i'm new to this field. i need a interface exactly like this for an assessment. please paste the code here.
ReplyDeletecan anyone explain to me where the class Contact is initialized? how if i want to create a list with 3 labels and 2 images inside every list item?
ReplyDelete@ Herahadi, am also wondering the same thing. could someone please explain where the Contact object is declared and initialized?
ReplyDeleteThis comment has been removed by the author.
ReplyDelete