02-10-2009 03:14 PM
After not getting any replies in this thread: http://supportforums.blackberry.com/rim/board/mess
I thought I might try using a ListField as a last resort, since, if you read the thread linked above, it seems that 4.2.1 has a bug where it won't change the color of a manager's background even if I call invalidate.
However, I'm having a hard time figuring out how I would wrap text within a ListField row. What I'm going for is this:
[Bitmap] [Text text text text] [Bitmap]
-----------[Text text text text]
[Bitmap] [Text text text text] [Bitmap]
-----------[Text text text text]
[Bitmap] [Text text text text] [Bitmap]
-----------[Text text text text]
(Where '-' is just space).
I'm praying that I won't have to loop through the words in my string and calculate the width each wrapped line would take up. I also don't think drawText with ellipsis style is suitable.
Any tips would be greatly appreciated.
Solved! Go to Solution.
02-10-2009 03:42 PM
If anyone is having the same problem, I stumbled upon this great piece of code: http://pastie.org/282759/wrap
03-16-2009 03:48 AM
03-16-2009 03:54 AM
03-16-2009 03:58 AM
Hi,
I am not able to access the code , due to firewall settings in my company's network.
so can you post the code for it.
03-16-2009 04:00 AM
package org.emerick.rtm.ui.lists; import java.util.Vector; import net.rim.device.api.system.Bitmap; import net.rim.device.api.system.KeypadListener; import net.rim.device.api.ui.ContextMenu; import net.rim.device.api.ui.DrawStyle; import net.rim.device.api.ui.Field; import net.rim.device.api.ui.Font; import net.rim.device.api.ui.Graphics; import net.rim.device.api.ui.Keypad; import net.rim.device.api.ui.Manager; import net.rim.device.api.ui.MenuItem; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.component.BitmapField; import net.rim.device.api.ui.component.LabelField; import net.rim.device.api.ui.component.ListField; import net.rim.device.api.ui.component.ListFieldCallback; import net.rim.device.api.ui.component.NullField; import org.emerick.rtm.RTM; import org.emerick.rtm.beans.Task; import org.emerick.rtm.ui.field.FontColorField; import org.emerick.rtm.ui.screens.DetailTaskScreen; public class TaskListField extends ListField implements ListFieldCallback { private Vector tasks; private Vector rows; private Bitmap p1; private Bitmap p2; private Bitmap p3; public TaskListField(Vector tasks) { super(0, ListField.MULTI_SELECT); setRowHeight(40); setEmptyString("Hooray, no tasks here!", DrawStyle.HCENTER); setCallback(this); setSearchable(false); p1 = Bitmap.getBitmapResource("p1.png"); p2 = Bitmap.getBitmapResource("p2.png"); p3 = Bitmap.getBitmapResource("p3.png"); this.tasks = tasks; rows = new Vector(); for (int x = 0; x < tasks.size(); ++x) { TableRowManager row = new TableRowManager(); // SET THE PRIORITY BITMAP FIELD Task task = (Task)tasks.elementAt(x); switch (task.getPriority()) { case 1: // if high priority, display p1 bitmap row.add(new BitmapField(p1)); break; case 2: // if priority is 2, set p2 bitmap row.add(new BitmapField(p2)); break; case 3: // if priority is 3, set p3 bitmap row.add(new BitmapField(p3)); break; default: // no priority set row.add(new NullField()); break; } // SET THE TASK NAME LABELFIELD // if overdue, bold/underline LabelField taskname = new LabelField(task.getName(), DrawStyle.ELLIPSIS); // if due today, bold if (task.overdue()) { taskname.setFont(Font.getDefault().derive(Font.BOL
D | Font.UNDERLINED)); } else if (task.dueToday()) { taskname.setFont(Font.getDefault().derive(Font.BOL D)); } row.add(taskname); // SET THE LIST NAME row.add(new FontColorField(RTM.getListName(task.getListID()), DrawStyle.ELLIPSIS, 0x00878787)); // SET THE DUE DATE/TIME row.add(new FontColorField(task.getFormattedDue(), DrawStyle.ELLIPSIS | LabelField.USE_ALL_WIDTH | DrawStyle.RIGHT, 0x00878787)); rows.addElement(row); } setSize(rows.size()); } private class TableRowManager extends Manager { public TableRowManager() { super(0); } // Causes the fields within this row manager to be layed out then // painted. public void drawRow(Graphics g, int x, int y, int width, int height) { // Arrange the cell fields within this row manager. layout(width, height); // Place this row manager within its enclosing list. setPosition(x, y); // Apply a translating/clipping transformation to the graphics // context so that this row paints in the right area. g.pushRegion(getExtent()); // Paint this manager's controlled fields. subpaint(g); g.setColor(0x00CACACA); g.drawLine(0, 0, getPreferredWidth(), 0); g.drawLine(10, 0, 10, getPreferredHeight()); // Restore the graphics context. g.popContext(); } // Arrages this manager's controlled fields from left to right within // the enclosing table's columns. protected void sublayout(int width, int height) { // set the size and position of each field. int fontHeight = Font.getDefault().getHeight(); int preferredWidth = getPreferredWidth(); // start with the Bitmap Field of the priority icon Field field = getField(0); layoutChild(field, 10, 40); setPositionChild(field, 0, 0); // set the task name label field field = getField(1); layoutChild(field, preferredWidth - 16, fontHeight + 1); setPositionChild(field, 16, 3); // set the list name label field field = getField(2); layoutChild(field, 150, fontHeight + 1); setPositionChild(field, 16, fontHeight + 6); // set the due time name label field field = getField(3); layoutChild(field, 150, fontHeight + 1); setPositionChild(field, preferredWidth - 152, fontHeight + 6); setExtent(preferredWidth, getPreferredHeight()); } // The preferred width of a row is defined by the list renderer. public int getPreferredWidth() { return Graphics.getScreenWidth(); } // The preferred height of a row is the "row height" as defined in the // enclosing list. public int getPreferredHeight() { return getRowHeight(); } } // ListFieldCallback Implementation public void drawListRow(ListField listField, Graphics g, int index, int y, int width) { TaskListField list = (TaskListField) listField; TableRowManager rowManager = (TableRowManager) list.rows.elementAt(index); rowManager.drawRow(g, 0, y, width, list.getRowHeight()); } public Object get(ListField list, int index) { return tasks.elementAt(index); } public int indexOfList(ListField list, String prefix, int start) { for(int x = start; x < tasks.size(); ++x) { Task task = (Task)tasks.elementAt(x); if(task.getName().startsWith(prefix)) { return x; } } return -1; } public int getPreferredWidth(ListField list) { return Graphics.getScreenWidth(); } public ContextMenu getContextMenu() { ContextMenu menu = super.getContextMenu(); menu.addItem(new CompleteTaskMenuItem()); menu.addItem(new EditTaskMenuItem()); menu.addItem(new DeleteTaskMenuItem()); menu.addItem(new PostponeTaskMenuItem()); return menu; } protected boolean navigationClick(int status, int time) { if ((status & KeypadListener.STATUS_TRACKWHEEL) == KeypadListener.STATUS_TRACKWHEEL) return false; selectItem(); return true; } protected boolean keyDown(int keycode, int time) { if (Keypad.key(keycode) == Keypad.KEY_ENTER) { selectItem(); } else if (Keypad.key(keycode) == Keypad.KEY_DELETE) { deleteSelected(); } else if (Keypad.map(keycode) == 'c') { completeSelected(); } else if (Keypad.map(keycode) == 'p') { postponeSelected(); } else if(Keypad.map(keycode) == 't') { setSelectedIndex(0); setFocus(); } else if(Keypad.map(keycode) == 'b') { setSelectedIndex(tasks.size() - 1); setFocus(); } else { return false; } return true; } public void delete(int index) { super.delete(index); tasks.removeElementAt(index); } public void selectItem() { int index = getSelectedIndex(); UiApplication.getUiApplication().pushScreen(new DetailTaskScreen((Task)tasks.elementAt(index))); } public void completeSelected() { int[] items = getSelection(); for (int x = items.length; x > 0; x--) { RTM.completeTask((Task)tasks.elementAt(items[x - 1])); delete(items[x - 1]); } } public void deleteSelected() { int[] items = getSelection(); for (int x = items.length; x > 0; x--) { RTM.deleteTask((Task)tasks.elementAt(items[x - 1])); delete(items[x - 1]); } } public void postponeSelected() { int[] items = getSelection(); for (int x = items.length; x > 0; x--) { RTM.postponeTask((Task)tasks.elementAt(items[x - 1])); ((Task)tasks.elementAt(items[x - 1])).postpone(); } } private final class CompleteTaskMenuItem extends MenuItem { public CompleteTaskMenuItem() { super("Complete", 100000, 1); } public void run() { completeSelected(); } } private final class EditTaskMenuItem extends MenuItem { public EditTaskMenuItem() { super("Edit", 100001, 2); } public void run() { selectItem(); } } private final class DeleteTaskMenuItem extends MenuItem { public DeleteTaskMenuItem() { super("Delete", 100002, 3); } public void run() { deleteSelected(); } } private final class PostponeTaskMenuItem extends MenuItem { public PostponeTaskMenuItem() { super("Postpone", 100004, 4); } public void run() { postponeSelected(); } } }
06-03-2010 05:56 AM - edited 06-03-2010 05:58 AM
Could someone please explain which part of the above code is actually wrapping the text and setting the list item's height to the wrapped height?
I am not seeing it happen in my code.
I would appreciate it very much.
06-03-2010 10:24 AM
private Vector wrap (String text, int width)
{
Vector result = new Vector ();
String remaining = text;
while (remaining.length()>=0)
{
int index = getSplitIndex(remaining, width);
if (index == -1)
break;
result.addElement(remaining.substring(0,index));
remaining = remaining.substring(index);
if (index == 0)
break;
}
return result;
}
private int getSplitIndex(String bigString, int width)
{
int index = -1;
int lastSpace = -1;
String smallString="";
boolean spaceEncountered = false;
boolean maxWidthFound = false;
for (int i=0; i<bigString.length(); i++)
{
char current = bigString.charAt(i);
smallString += current;
if (current == ' ')
{
lastSpace = i;
spaceEncountered = true;
}
int linewidth = this.getFont().getAdvance(smallString,0, smallString.length());
if(linewidth>width)
{
if (spaceEncountered)
index = lastSpace+1;
else
index = i;
maxWidthFound = true;
break;
}
}
if (!maxWidthFound)
index = bigString.length();
return index;
}just pass the string as text and width and you will get the output.
if u find solution give kudos
01-29-2011 01:34 AM
Sir I am new to BlackBerry.Pls solve my problem.
I have a ObjectListField with some items in it.Now I want assign different tasks for each list item.How can I make this happen.
For ex, I have list items as follows:
Name1
Name2
Name3
After clicking on Name1 I have to show the details of Name1 in another screen. Like that for Name2 and Name3 also.
05-16-2012 02:20 AM
hello swapnil
its very userfull code and working fine who have to need wrap test in list field
in that i make minor changes for get wrap test font wise and in weap text vector last element return "" string in many case
so i use code like.......
public static Vector wrap (String text,Font font, int width)
{
Vector result = new Vector ();
String remaining = text;
while (remaining.length()>=0)
{
int index = getSplitIndex(remaining,font,width);
if (index == -1)
break;
result.addElement(remaining.substring(0,index));
remaining = remaining.substring(index);
if (index == 0)
break;
}
if(result!=null)
{
if(((String)result.lastElement()).trim().equalsIgn oreCase(""))
{
result.removeElementAt(result.size()-1);
}
}
return result;
}
private static int getSplitIndex(String bigString,Font font,int width)
{
int index = -1;
int lastSpace = -1;
String smallString="";
boolean spaceEncountered = false;
boolean maxWidthFound = false;
for (int i=0; i<bigString.length(); i++)
{
char current = bigString.charAt(i);
smallString += current;
if (current == ' ')
{
lastSpace = i;
spaceEncountered = true;
}
int linewidth = font.getAdvance(smallString,0, smallString.length());
if(linewidth>width)
{
if (spaceEncountered)
index = lastSpace+1;
else
index = i;
maxWidthFound = true;
break;
}
}
if (!maxWidthFound)
index = bigString.length();
return index;
}