×
Namespaces

Variants
Actions
(Difference between revisions)

Understanding LWUIT List

From Nokia Developer Wiki
Jump to: navigation, search
arunkam (Talk | contribs)
m (Arunkam -)
hamishwillee (Talk | contribs)
m (Hamishwillee - Subedited/Reviewed)
 
Line 1: Line 1:
[[Category:Nokia Asha Platform 1.0]][[Category:Nokia Asha]][[Category:Series 40 Developer Platform 2.0]][[Category:Series 40 Developer Platform 1.1]][[Category:Java ME]][[Category:Code Snippet]][[Category:Code Examples]][[Category:UI on Java ME]]
+
[[Category:Nokia Asha Platform 1.0]][[Category:Nokia Asha]][[Category:Series 40 Developer Platform 2.0]][[Category:Series 40 Developer Platform 1.1]][[Category:LWUIT]][[Category:Code Examples]]
 
{{FeaturedArticle|timestamp=20140202}}
 
{{FeaturedArticle|timestamp=20140202}}
{{Abstract|This article explains the Lightweight User Interface Toolkit (LWUIT) List Component. This component is usually the hardest to understand out of all the LWUIT components. This article is intended as an overview for beginners.}}
+
{{Abstract|This article provides an introductory overview to the Lightweight User Interface Toolkit (LWUIT) List component. }}
  
 
{{ArticleMetaData <!-- v1.3 -->
 
{{ArticleMetaData <!-- v1.3 -->
|sourcecode= <!-- Link to example source code e.g. [[Media:The Code Example ZIP.zip]] --> [[Media:List Sample.zip]]
+
|sourcecode= [[Media:List Sample.zip]]
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.wgt]]) -->
 
|installfile= <!-- Link to installation file (e.g. [[Media:The Installation File.wgt]]) -->
 
|devices= <!-- Devices tested against - e.g. Nokia Lumia 928, Nokia Asha 501) -->
 
|devices= <!-- Devices tested against - e.g. Nokia Lumia 928, Nokia Asha 501) -->
Line 22: Line 22:
 
|author=[[User:arunkam]]
 
|author=[[User:arunkam]]
 
}}
 
}}
 +
 
== Introduction ==
 
== Introduction ==
  
 
LWUIT List is one of the most often used components of LWUIT. At the same time, it is the least understood component. This is primarily because a LWUIT list makes use of the MVC model.
 
LWUIT List is one of the most often used components of LWUIT. At the same time, it is the least understood component. This is primarily because a LWUIT list makes use of the MVC model.
 +
 +
<gallery widths="200px" heights="300px">
 +
File:Simple_list.png|Simple List
 +
File:Complex.png|A Complex List
 +
</gallery>
  
 
== MVC Model ==
 
== MVC Model ==
 
 
MVC stands for Model - View - Controller.  
 
MVC stands for Model - View - Controller.  
 +
# Model - The Model contains the data that is to be displayed.
 +
# View - The View contains the logic that renders the list on the screen.
 +
# Controller - The Controller coordinates the Model and the View.
  
1.) Model - The Model contains the data that is to be displayed.
+
In LWUIT List, the Model is a List Model, View is a {{Icode|ListCellRenderer}} and the Controller is the List itself.
 
+
2.) View - The View contains the logic that renders the list on the screen.
+
 
+
3.) Controller - The Controller coordinates the Model and the View.
+
 
+
In LWUIT List, the Model is a List Model, View is a List Cell Renderer and the Controller is the List itself.
+
  
 
== Default Model and Renderer ==
 
== Default Model and Renderer ==
  
While this might seem like a complex set of processes that need to be taken care of to create a list, LWUIT has a default List Model and default List Cell Renderer that are suitable for most common operations.
+
While this might seem like a complex set of processes that need to be taken care of to create a list, LWUIT has a default List Model and default {{Icode|ListCellRenderer}} that are suitable for most common operations.
  
The default List Model and the default List Cell Renderer are created in the background for simple lists that display a string at each row.
+
The default List Model and the default {{Icode|ListCellRenderer}} are created in the background for simple lists that display a string at each row.
  
 
<code java>
 
<code java>
Line 54: Line 56:
 
</code>
 
</code>
  
This automatically creates a simple list, with a default list model and a default list cell renderer, each row containing one entry. The entries apple, orange, mangoes and peaches are added into the default list model.
+
This automatically creates a simple list, with a default list model and a default {{Icode|ListCellRenderer}}, each row containing one entry. The entries apple, orange, mangoes and peaches are added into the default list model.
  
 
[[File:Simple_list.png|frame|none|Simple List]]
 
[[File:Simple_list.png|frame|none|Simple List]]
  
== A Custom Designed list ==
+
== Custom list ==
  
 
We will now talk about how to create the custom list shown in the figure.
 
We will now talk about how to create the custom list shown in the figure.
Line 124: Line 126:
 
=== List Renderer ===
 
=== List Renderer ===
  
We will now create our List Cell Renderer. To do this, we need to implement the {{Icode|ListCellRenderer}} interface.
+
We will now create our {{Icode|ListCellRenderer}}. To do this, we need to implement the {{Icode|ListCellRenderer}} interface.
  
 
<code java>
 
<code java>
Line 130: Line 132:
 
{
 
{
  
    public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
+
  public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
    {
+
  {
    }
+
  }
  
    public Component getListFocusComponent(List list)
+
  public Component getListFocusComponent(List list)
    {
+
  {
    }
+
  }
 
}
 
}
 
</code>
 
</code>
  
  
The {{Icode|getListCellRendererComponent}} method is called to paint each row in the list. This method is expected to return a component each time it is called. Since memory allocation is a time-consuming process, it is not advisable to create a new component and return that. We will instead extend a pre-existing component and return that.
+
The {{Icode|getListCellRendererComponent}} method is called to paint each row in the list. This method is expected to return a component each time it is called. Since memory allocation is a time-consuming process, it is not advisable to create a new component and return that. We will instead extend a pre-existing component and return it instead.
  
 
<code java>
 
<code java>
 
class myRenderer extends Container implements ListCellRenderer
 
class myRenderer extends Container implements ListCellRenderer
 
{
 
{
    myRenderer()
+
  myRenderer()
    {
+
  {
   
+
 
    }
+
  }
    public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
+
 
    {
+
  public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
        return this;
+
  {
    }
+
    return this;
    public Component getListFocusComponent(List list)
+
  }
    {
+
 
        return this;
+
  public Component getListFocusComponent(List list)
    }
+
  {
 +
    return this;
 +
  }
 
}
 
}
 
</code>
 
</code>
Line 201: Line 205:
 
In the above code, we created the necessary layout. We will now map the data to the components in this container. This is done in the {{Icode|getListCellRendererComponent }} method.
 
In the above code, we created the necessary layout. We will now map the data to the components in this container. This is done in the {{Icode|getListCellRendererComponent }} method.
  
{{Icode|getListCellRendererComponent(List list, Object value, int index, boolean isSelected) }}
+
<code java>getListCellRendererComponent(List list, Object value, int index, boolean isSelected)</code>
  
 
This method is called to render each row. The present index which is being rendered is available in the ''index'' variable. The ''value'' variable contains the data for that particular index, taken from the list model. We will typecast the ''value'' variable as needed and then use it. The resulting method is shown below.
 
This method is called to render each row. The present index which is being rendered is available in the ''index'' variable. The ''value'' variable contains the data for that particular index, taken from the list model. We will typecast the ''value'' variable as needed and then use it. The resulting method is shown below.
Line 207: Line 211:
 
<code java>
 
<code java>
 
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
 
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
    {
+
  {
ModelData m = (ModelData) value;
+
    ModelData m = (ModelData) value;
dp.setIcon(m.getDisplay_pic());
+
    dp.setIcon(m.getDisplay_pic());
heading.setText(m.getHeading());
+
    heading.setText(m.getHeading());
description.setText(m.getDescription());
+
    description.setText(m.getDescription());
return this;
+
    return this;
 
     }
 
     }
 
</code>
 
</code>
Line 257: Line 261:
 
== Precautions & Limitations ==
 
== Precautions & Limitations ==
  
While Lists are very powerful ([http://lwuit.blogspot.in/2008/08/model-mvc-million-contacts-march.html |Million Entry List]), it is important to keep in mind that a list has limitations.
+
While Lists are very powerful ([http://lwuit.blogspot.in/2008/08/model-mvc-million-contacts-march.html Million Entry List]), it is important to keep in mind that a list has limitations.
  
A List Row can have only a fixed width/height. Hence complex animations/expansion of a particular row in a list is not possible. A Component called Container List does not have this problem.
+
A List row can have only a fixed width/height. Hence complex animations/expansion of a particular row in a list is not possible. A component called Container List does not have this problem.
  
 
The following articles are worth reading :  
 
The following articles are worth reading :  
 
+
* [http://codenameone.blogspot.in/2008/07/lwuit-list-renderer-by-chen-fishbein.html LWUIT List Renderer]
[http://codenameone.blogspot.in/2008/07/lwuit-list-renderer-by-chen-fishbein.html|LWUIT List Renderer]
+
* [http://www.codenameone.com/3/post/2013/12/deeper-in-the-renderer.html Deeper In The Renderer]
 
+
[http://www.codenameone.com/3/post/2013/12/deeper-in-the-renderer.html Deeper In The Renderer]
+
  
 
{{Note| Codename One was developed by the same engineers who designed and developed LWUIT. Codename One is similar to LWUIT in many ways. Hence some of the concepts in Codename One are applicable to LWUIT as well.}}
 
{{Note| Codename One was developed by the same engineers who designed and developed LWUIT. Codename One is similar to LWUIT in many ways. Hence some of the concepts in Codename One are applicable to LWUIT as well.}}

Latest revision as of 09:51, 4 February 2014

Featured Article
02 Feb
2014

This article provides an introductory overview to the Lightweight User Interface Toolkit (LWUIT) List component.

Article Metadata
Code ExampleCompatibilityArticle
Created: arunkam (04 Feb 2014)
Last edited: hamishwillee (04 Feb 2014)

Contents

[edit] Introduction

LWUIT List is one of the most often used components of LWUIT. At the same time, it is the least understood component. This is primarily because a LWUIT list makes use of the MVC model.

[edit] MVC Model

MVC stands for Model - View - Controller.

  1. Model - The Model contains the data that is to be displayed.
  2. View - The View contains the logic that renders the list on the screen.
  3. Controller - The Controller coordinates the Model and the View.

In LWUIT List, the Model is a List Model, View is a ListCellRenderer and the Controller is the List itself.

[edit] Default Model and Renderer

While this might seem like a complex set of processes that need to be taken care of to create a list, LWUIT has a default List Model and default ListCellRenderer that are suitable for most common operations.

The default List Model and the default ListCellRenderer are created in the background for simple lists that display a string at each row.

List l = new List();
 
l.addItem("Apple");
l.addItem("Orange");
l.addItem("Mangoes");
l.addItem("Peaches");

This automatically creates a simple list, with a default list model and a default ListCellRenderer, each row containing one entry. The entries apple, orange, mangoes and peaches are added into the default list model.

Simple List

[edit] Custom list

We will now talk about how to create the custom list shown in the figure.

A Complex List

[edit] List Model

The list model contains an image, a heading string and a description string. We will put all these into a class.

public class ModelData
{
Image display_pic;
String name;
String description;
 
public ModelData(String heading, String description, String imgLocation)
{
this.name = heading;
this.description = description;
try
{
this.display_pic = Image.createImage(imgLocation);
} catch (IOException ex)
{
ex.printStackTrace();
}
}
 
public Image getDisplay_pic()
{
return display_pic;
}
 
public void setDisplay_pic(Image display_pic)
{
this.display_pic = display_pic;
}
 
public String getName()
{
return name;
}
 
public void setName(String name)
{
this.name = name;
}
 
public String getDescription()
{
return description;
}
 
public void setDescription(String description)
{
this.description = description;
}
}

Now we can use an array/vector of objects of this class as our list model.

[edit] List Renderer

We will now create our ListCellRenderer. To do this, we need to implement the ListCellRenderer interface.

class myRenderer implements ListCellRenderer
{
 
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
{
}
 
public Component getListFocusComponent(List list)
{
}
}


The getListCellRendererComponent method is called to paint each row in the list. This method is expected to return a component each time it is called. Since memory allocation is a time-consuming process, it is not advisable to create a new component and return that. We will instead extend a pre-existing component and return it instead.

class myRenderer extends Container implements ListCellRenderer
{
myRenderer()
{
 
}
 
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
{
return this;
}
 
public Component getListFocusComponent(List list)
{
return this;
}
}

The image shows what each entry in the row should look like. We will implement this within our renderer using layouts.

A Single Row
class myRenderer extends Container implements ListCellRenderer
{
Label dp;
Label heading;
Label description;
myRenderer()
{
this.setLayout(new BoxLayout(BoxLayout.X_AXIS));
Container left = new Container();
Container right = new Container();
//Left Side
dp = new Label();
left.addComponent(dp);
//Right Side
heading = new Label();
description = new Label();
right.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
right.addComponent(heading);
right.addComponent(description);
//Adding them to the main container
this.addComponent(left);
this.addComponent(right);
}
public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
{
return this;
}
public Component getListFocusComponent(List list)
{
return this;
}
}

In the above code, we created the necessary layout. We will now map the data to the components in this container. This is done in the getListCellRendererComponent method.

getListCellRendererComponent(List list, Object value, int index, boolean isSelected)

This method is called to render each row. The present index which is being rendered is available in the index variable. The value variable contains the data for that particular index, taken from the list model. We will typecast the value variable as needed and then use it. The resulting method is shown below.

public Component getListCellRendererComponent(List list, Object value, int index, boolean isSelected)
{
ModelData m = (ModelData) value;
dp.setIcon(m.getDisplay_pic());
heading.setText(m.getHeading());
description.setText(m.getDescription());
return this;
}

Now everything is ready. We just need to populate the list with a few entries. I have added a few dummy entries along with a few sample pictures.

        List myComplexList = new List();
//Creating the data
ModelData entries[] = new ModelData[]
{
new ModelData("John", "Lives in New York", "/images/1.png"),
new ModelData("Jim", "He works in a bank.", "/images/2.png"),
new ModelData("Jack", " Lives in Australis", "/images/3.png"),
new ModelData("Jill", "Works with the Police", "/images/4.png")
};
//Creating a Default List Model and putting the data in it.
DefaultListModel dlm = new DefaultListModel(entries);
// Setting the model.
myComplexList.setModel(dlm);
// Setting the renderer.
myComplexList.setRenderer(new myRenderer());

[edit] Interacting with the List

You can use either a SelectionListener or an ActionListener to interact with a list. Action Listeners are more commonly used, especially in touch devices.

We use the method getSelectedItem() to get the currently selected item.

 myComplexList.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
ModelData selection = (ModelData) myComplexList.getSelectedItem();
System.out.println(selection.getName());
 
}
});


[edit] Precautions & Limitations

While Lists are very powerful (Million Entry List), it is important to keep in mind that a list has limitations.

A List row can have only a fixed width/height. Hence complex animations/expansion of a particular row in a list is not possible. A component called Container List does not have this problem.

The following articles are worth reading :

Note.pngNote: Codename One was developed by the same engineers who designed and developed LWUIT. Codename One is similar to LWUIT in many ways. Hence some of the concepts in Codename One are applicable to LWUIT as well.

[edit] Summary

This article is intended to give an introduction to LWUIT lists for beginners.

This page was last modified on 4 February 2014, at 09:51.
290 page views in the last 30 days.
×