first , please try to understand my problem because i know their are too many questions related to this , but in my case no-one is working
why i dont know , please see my code .
this is working
public final class MyScreen extends MainScreen implements FieldChangeListener
{
private combine enter_in;
private manager_s ms , ms_1 ;
private Bitmap img;
LabelField lb_1 , lb_2 , lb_3 ;
public MyScreen()
{
setTitle("MyTitle");
img = Bitmap.getBitmapResource("icon.png");
//Bitmap img_1 = Bitmap.getBitmapResource("icon.png");
enter_in = new combine ( Field.FOCUSABLE , img );
enter_in.setChangeListener(this);
ms = new manager_s( 0 , 4 );
ms.add(enter_in);
lb_1 = new LabelField("Menu") ;
lb_2 = new LabelField("Favorites") ;
lb_3 = new LabelField("Reserved") ;
ms.add(lb_1);
ms.add(lb_2);
ms.add(lb_3);
add(ms);
}
}
but when i am implementing FieldChangedListener , at that time ms.delete(lb_1) is not working but delete(ms) is working , please help solve this problem
public void fieldChanged(Field field, int context)
{
if ( field == enter_in )
{
ms.delete(lb_1);
}
}
so , i am asking that is , there any reason for ms.delete(lb_1) not working under MyScreen class .
see this is my manager_class which i am using as , Manager ( custom_manager ) and this manager is extended by my class , for adding the fields inside the screen
public class manager_s extends Manager
{
int col ;
int w_1 = 20 ;
protected manager_s(long style , int col )
{
super(style);
this.col = col ;
}
protected void sublayout(int width, int height)
{
for ( int i = 0 ; i < col ; i ++ )
{
Field field = getField (i);
layoutChild( field , 130 , 100 );
}
for ( int i = 0 ; i < col ; i ++ )
{
Field field = getField (i);
setPositionChild ( field , w_1 , 20 );
w_1 = w_1 + 135 ;
setExtent ( width , 200 );
}
}
}
and the error is INDEX_OUT_OF_BOUND_EXCEPTION , thats my question that , because every one on internet ( as a resource ) is saying that remove the field , but i my case nothing is working .
try this -
setTitle("MyTitle");
final ButtonField enter_in=new ButtonField("enter_in");
add(enter_in);
lb_1 = new LabelField("Menu") ;
lb_2 = new LabelField("Favorites") ;
lb_3 = new LabelField("Reserved") ;
final HorizontalFieldManager ms=new HorizontalFieldManager();
ms.add(lb_1);
lb_1.setMargin(0,50,0,0);//Here you can set the spacing between the Fields.
ms.add(lb_2);
lb_2.setMargin(0,50,0,0);//Here you can set the spacing between the Fields.
ms.add(lb_3);
add(ms);
FieldChangeListener listener=new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
if(field==enter_in){
ms.delete(lb_1);
ms.invalidate();
}
}
};
enter_in.setChangeListener(listener);
In place of my ButtonField , you can use your combine.
Related
I created a sort of a grid with multiple vertical and horizontal fieldmanagers.
The code to create the grid is:
public class CategoriasScreen extends MainScreen {
private int colores [] = {Color.BLUE, Color.ALICEBLUE, Color.CHOCOLATE, Color.DARKORANGE, Color.YELLOW};
private int rows;
public CategoriasScreen(){
VerticalFieldManager row;
CategoriaFieldManager cat;
HorizontalFieldManager par;
EncodedImage eImage;
LabelField lf;
rows = 1;
Font font = getFont().derive(Font.PLAIN, Font.getDefault().getHeight() - 8);
setTitle("Categorias");
for(int i = 0; i < rows; i++){
row = new VerticalFieldManager(Field.FIELD_VCENTER | Manager.USE_ALL_WIDTH | Field.NON_FOCUSABLE);
par = new HorizontalFieldManager(Field.FIELD_HCENTER | Field.NON_FOCUSABLE);
cat = new CategoriaFieldManager(i);
eImage = EncodedImage.getEncodedImageResource("img/categoria" + i +".png");
eImage = LoaderScreen.resize(eImage, (int) Display.getWidth() / 5, (int) Display.getHeight() / 5, true);
cat.add(new BitmapField(eImage.getBitmap()));
lf = new LabelField("Categoria " + i, Field.FIELD_HCENTER);
lf.setFont(font);
cat.add(lf);
par.add(cat);
cat = new CategoriaFieldManager(i + 2);
eImage = EncodedImage.getEncodedImageResource("img/categoria" + (i + 2) +".png");
eImage = LoaderScreen.resize(eImage, (int) Display.getWidth() / 5, (int) Display.getHeight() / 5, true);
cat.add(new BitmapField(eImage.getBitmap()));
lf = new LabelField("Categoria " + (i + 2), Field.FIELD_HCENTER);
lf.setFont(font);
cat.add(lf);
par.add(cat);
row.add(par);
add(row);
//add(cat);
}
}
}
For the element inside the grid i extended a VerticalFieldManager and implemented the FieldChangeListener:
public class CategoriaFieldManager extends VerticalFieldManager implements FieldChangeListener{
private int colores [] = {Color.BLUE, Color.ALICEBLUE, Color.CHOCOLATE, Color.DARKORANGE, Color.YELLOW};
private int _idCategoria;
public CategoriaFieldManager(int idCategoria){
super(Field.FOCUSABLE);
_idCategoria = idCategoria;
setBackground(BackgroundFactory.createSolidBackground(colores[0]));
this.setPadding(new XYEdges(15,30,10,30));
this.setBorder(BorderFactory.createSimpleBorder(new XYEdges(20,20,20,20), Border.STYLE_TRANSPARENT));
//cat.setCookie(new Integer(i));
this.setChangeListener(this);
}
protected void sublayout(int width, int height){
super.sublayout((int) Display.getWidth() / 5 , (int) Display.getWidth() / 5);
setExtent((int) Display.getWidth() / 5, (int) Display.getWidth() / 5);
}
protected void onFocus(int direction){
setBackground(BackgroundFactory.createSolidBackground(colores[1]));
}
protected void onUnfocus(){
setBackground(BackgroundFactory.createSolidBackground(colores[0]));
}
public boolean isFocusable(){
return true;
}
protected boolean touchEvent( TouchEvent message ) {
int x = message.getX( 1 );
int y = message.getY( 1 );
if( x < 0 || y < 0 || x > getExtent().width || y > getExtent().height ) {
// Outside the field
return false;
}
switch( message.getEvent() ) {
case TouchEvent.UNCLICK:
fieldChangeNotify(0);
return true;
}
return super.touchEvent( message );
}
protected boolean navigationClick(int status, int time) {
if (status != 0) { // you did not have this check
fieldChangeNotify(0);
}
return true;
}
public void fieldChanged(Field field, int context) {
UiApplication.getUiApplication().pushScreen( new ListadoEstablecimientosScreen(_idCategoria) );
/*UiApplication.getUiApplication().invokeLater(new Runnable(){
public void run() {
Dialog.alert("hola mundo");
}
});*/
}
}
The problem that I've found is that when I touch the screen (anywhere) and then use the trackpad the phone freezes, I have to restart it to use it again. Then comes a notification that says the application was using too many resources. If it helps I've been testing in a BlackBerry Bold 9900
I have tried this button.set() in multiple ways by doing this inside dateonset () method and I get a null pointer exception there though the editText4 contains the valid text to set the button. I tried the route of Shared preferences as I suspected the edittext4 is empty. Finally I tried this method to initialize the Datebtn inside the Onclick method from view. Here I don't get a null pointer exception but Datebtn.setText() inside switch case does not settext the selected date value & Datebtn text continues to show only the current date that was set in the onCreateView () method. I think I am missing something trivial.
public class AFragment extends Fragment implements OnClickListener {
private DataManipulator dh;
public Button Datebtn;
private Calendar mCalen;
private int day;
private int month;
private int year;
public String myEditText4;
#Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
View view = inflater.inflate( R.layout.afragment, container, false );
Button b1 = (Button)view.findViewById( R.id.Button01 );
b1.setOnClickListener( this );
Button Datebtn = (Button)view.findViewById( R.id.datepickerbutton );
mCalen = Calendar.getInstance();
day = mCalen.get( Calendar.DAY_OF_MONTH );
month = mCalen.get( Calendar.MONTH );
year = mCalen.get( Calendar.YEAR );
Datebtn.setText( day + " / " + (month + 1) + " / " + year );
myEditText4 = (String)Datebtn.getText();
Datebtn.setOnClickListener( this );
return view;
}
#SuppressLint( "CutPasteId" )
#Override
public void onClick( View view ) {
Context context = view.getContext();
Button Datebtn = (Button)view.findViewById( R.id.datepickerbutton );
switch( view.getId() ) {
case (R.id.datepickerbutton):
DatePickerFragment newDateFragment = new DatePickerFragment();
newDateFragment.setStyle( 1, 1 );
newDateFragment.show( getFragmentManager(), "DatePicker" );
Datebtn.setText( myEditText4 );
break;
case (R.id.Button01):
View editText1 = (EditText)getView().findViewById( R.id.ppl );
View editText2 = (EditText)getView().findViewById( R.id.litres );
View editText3 = (EditText)getView().findViewById( R.id.odo );
String myEditText1 = ((TextView)editText1).getText().toString();
String myEditText2 = ((TextView)editText2).getText().toString();
String myEditText3 = ((TextView)editText3).getText().toString();
dh = new DataManipulator( context );
if( myEditText1 != "" & myEditText2 != "" & myEditText3 != "" & myEditText4 != "" ) {
dh.insert( myEditText1, myEditText2, myEditText3, myEditText4 );
Toast.makeText( context.getApplicationContext(), "Submit Successful!!!", Toast.LENGTH_LONG ).show();
EditText text1 = (EditText)getView().findViewById( R.id.ppl );
text1.setText( "" );
EditText text2 = (EditText)getView().findViewById( R.id.litres );
text2.setText( "" );
EditText text3 = (EditText)getView().findViewById( R.id.odo );
text3.setText( "" );
} else {
Toast.makeText( context.getApplicationContext(), "Values can not be empty!!!", Toast.LENGTH_LONG ).show();
}
break;
}
}
#SuppressLint( "ValidFragment" )
public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
#Override
public Dialog onCreateDialog( Bundle savedInstanceState ) {
final Calendar c = Calendar.getInstance();
int year = c.get( Calendar.YEAR );
int month = c.get( Calendar.MONTH );
int day = c.get( Calendar.DAY_OF_MONTH );
return new DatePickerDialog( getActivity(), this, year, month, day );
}
public void onDateSet( DatePicker view, int selectedYear, int selectedMonth, int selectedDay ) {
int year = selectedYear;
int month = selectedMonth;
int day = selectedDay;
myEditText4 = (day + " / " + (month + 1) + " / " + year);
return;
}
}
}
After debugging the state of all variables, I was able to figure out the issue. Here is the solution
1) When I did Datebtn inside the onDateSet method, I was actually trying to get the Datebtn object from the Datepicker view. The Datebtn is not in this fragment and hence it gives null pointer exception
2) I then attempted to get the parent fragment from inside the onDateSet using fragment manager object and findFragmentByTag("AFragment"). This is also returned a null pointer because "AFragment" tag is not defined for the AFragment layout xml or AFragment class
3) Then I tried to get a valid AFragment object from fragment manager object using findFragmentByID (R.id.fragment_container). At this step, I got a valid AFragment object handle in DatePickerFragment class. I was then able to do setText on the Datebtn in AFragment class from DatePickerFragment class
Here is how the working code for DatePickerFragment's onDateSet looks
public void onDateSet(DatePicker view, int selectedYear,
int selectedMonth, int selectedDay) {
int year = selectedYear;
int month = selectedMonth;
int day = selectedDay;
myEditText4 = (day + " / " + (month + 1) + " / " + year);
FragmentManager fm = this.getFragmentManager();
Fragment parFragment = fm.findFragmentById(R.id.fragment_container);
Button dbtn = (Button) parFragment.getView().findViewById(R.id.datepickerbutton);
dbtn.setText(myEditText4);
return;
}
I am new to the Blackberry Field, I want to create a customized Horizontal scroll view which should exactly looks like in the below image. Any Help will be Apprreciated
I am using Blackberry Simulator 9900, Thanks in advance .
I guess Middle portion is ONLY scrollable, right ?
You must have one HorizontalFieldManager with HORIZONTAL_SCROLL ( Middle one )
e.g. HorizontalFieldManager hfm = new HorizontalFieldManager( HORIZONTAL_SCROLL );
add your custom field in this manager.
You must add hfm in Custom OuterManager.
For your reference I'm posting my own code here...
private class HScroll extends MainScreen{
public HScroll() {
super( USE_ALL_WIDTH );
OuterManager father = new OuterManager( );
LabelField ll = new LabelField("<");
father.add(ll);
HorizontalFieldManager hfm = new HorizontalFieldManager( HORIZONTAL_SCROLL );
for( int i=0; i<10; i++ ){
ButtonField btn = new ButtonField(" i " + i);
hfm.add(btn);
}
father.add(hfm);
LabelField ll1 = new LabelField(">");
father.add(ll1);
add(father);
}
private class OuterManager extends net.rim.device.api.ui.Manager{
public OuterManager() {
super(USE_ALL_WIDTH);
}
protected void sublayout(int width, int height) {
int x = 0;
Field ff = getField( 0 );
Field ff2 = getField( 2 );
setPositionChild(ff, x, 0);
layoutChild(ff, ff.getPreferredWidth(), ff.getPreferredHeight());
x = x + ff.getPreferredWidth();
Field ff1 = getField( 1 );
setPositionChild(ff1, x , 0);
layoutChild(ff1, width - ff.getPreferredWidth() - ff2.getPreferredWidth() , ff1.getPreferredHeight());
x = width - ff2.getPreferredWidth();
setPositionChild(ff2, x, 0);
layoutChild(ff2, ff2.getPreferredWidth(), ff2.getPreferredHeight());
setExtent(width, height);
}
}
}
I'm working on my own custom manager, and I've gotten it complete so far, but it setsMargins using a percentage of the screen resolution.
Here's how I call the following class:
LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0);
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));
Here's the class [I've marked in a comment where it returns 0 and where it returns 219. please tell me why this happens:
public class LabelIconCommandManager extends HorizontalFieldManager implements BCMSField
{
LabelIconCommandManager me = this;
EvenlySpacedHorizontalFieldManager buttonManager = new EvenlySpacedHorizontalFieldManager(0);
LabelField labelField;
int side = 0;
int HPADDING = 3;
int VPADDING = 4;
int screenWidth = Display.getWidth();
int labelField_width = 40;
public LabelIconCommandManager()
{
this("", 0);
}
public LabelIconCommandManager(String label, long style)
{
super(USE_ALL_WIDTH| FOCUSABLE);
this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
this.setMargin(1,10,1,10);
labelField = new LabelField(label,LabelField.ELLIPSIS)
{
public void layout(int width, int height)
{
// Done because otherwise ellipses dont work with labelfields
super.layout((int)(screenWidth * 0.61), getHeight());
setExtent((int)(screenWidth * 0.61), getHeight());
labelField_width = labelField.getWidth();
DisplayDialog.alert("labelField_width = " + labelField_width); // returns 219
}
};
// Top Right Bottom Left
labelField.setMargin(VPADDING, HPADDING, VPADDING, 0);
// super because we want this horizontalfieldManager to add it
super.add(labelField);
super.add(buttonManager);
}
public void alternateConstructor(Attributes atts)
{
labelField = new LabelField(atts.getValue("label"), 0);
}
public void onFocus(int direction)
{
this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit_select.png" )));
// uses the same color as listStyleButtonField selections
this.setBackground(BackgroundFactory.createSolidBackground(0x186DEF));
super.onFocus(direction);
}
//Invoked when a field loses the focus.
public void onUnfocus()
{
//top, right,bottom,left
this.setBorder(BorderFactory.createBitmapBorder(new XYEdges(15, 20, 15, 20),Bitmap.getBitmapResource( "border_edit.png" )));
this.setBackground(BackgroundFactory.createSolidTransparentBackground(Color.GRAY, 0));
super.onUnfocus();
invalidate();
}
// Overrride this managers add function
public void add(Field imageButton)
{
// Add a button to the evenly spaced manager
buttonManager.add(imageButton);
// Based on how many buttons there are, set the margin of where the manager holding the buttons start [offset from labelField]
if(buttonManager.getFieldCount() == 1)
{
//side = (int)(screenWidth * 0.1388);
side = screenWidth - labelField_width - 32 - 10 - 15;
DisplayDialog.alert("Screen Width = " + screenWidth);
DisplayDialog.alert("labelField_width2 = " + labelField_width); // returns 0
DisplayDialog.alert("Side = " + side);
}
else side = (int)(screenWidth * 0.05);
buttonManager.setMargin(0,0,0,side);
}
public int getLabelWidth()
{
return labelField_width;
}
}
Here's a picture just to be more clear:
Note: when I ran your code, I didn't actually see labelField_width set to 0. You initialize the value to 40 in the code you posted above. So, I do sometimes see it set to 40, or 219 (on a 360 px wide screen).
But, the problem is that I think you're trying to access the value of labelField_width too soon. The only place it's properly assigned is in the layout() method of your anonymous LabelField. Just because you declare and implement the layout() method in line with the instantiation, doesn't mean that it's called when the LabelField is created. This is actually one of the reasons I don't like anonymous classes.
Anyway, this code:
LabelIconCommandManager licm3 = new LabelIconCommandManager("Address blah bklahblah ", 0);
licm3.add(new ImageButtonField(b1, b2, b3, Field.FIELD_LEFT | ImageButtonField.CONSUME_CLICK));
Will first instantiate the LabelField (inside the LabelIconCommandManager constructor). As I said, that does not trigger the layout() method. The second line above (add()) will trigger your overridden method:
// Overrride this managers add function
public void add(Field imageButton)
{
which is where you see the bad value for labelField_width. That method gets called before layout(). That's the problem.
Since it looks like you only use that width to set the buttonManager margin, you could just wait a little longer to do that. If you wait until the LabelIconCommandManager sublayout() method is called, your LabelField will have had its layout() method called, and labelField_width assigned correctly:
protected void sublayout(int maxWidth, int maxHeight) {
// make sure to call superclass method first!
super.sublayout(maxWidth, maxHeight);
// now, we can reliably use the label width:
side = screenWidth - labelField_width - 32 - 10 - 15;
buttonManager.setMargin(0,0,0,side);
}
That method goes in the LabelIconCommandManager class. And then, you can remove the other place you call buttonManager.setMargin().
Some brief summary from Nate post.
When you construct manager and add fields don't expect that it will be layouted correctly. Manager doesn't know the context - where it will be placed. So layout method for field will be called only when you add his manager to the screen (when layout for manager will be also called). And this is correct.
Move the calculation of your side variable to layout method.
If you really need side value before you put manager to screen. You could precalculate it by using Field.getPrefferedWidth() which returns meaningful values for standard fields (getFont().getAdvance(text) for LabelField, probably also with borders please check yourself). But be careful with this values.
Please review code below. It's manager which has label and buttons. And it puts label at the left side and buttons at the right.
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.component.ButtonField;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.decor.Border;
import java.util.Vector;
public class TabFieldManager extends Manager {
public TabFieldManager(long style) {
super(style);
}
protected void sublayout(int width, int height) {
LabelField label = null;
Vector tabs = new Vector();
int tabsWidth = 0;
int tabHeight = 0;
int tabPaddingTop = 0;
int tabPaddingLeft = 0;
for (int i=0; i < getFieldCount(); i++) {
Field field = getField(i);
if (field instanceof LabelField) {
label = (LabelField) field;
} else if (field instanceof ButtonField){
tabs.addElement(field);
layoutChild(field, width, height);
int fieldwidth = field.getWidth() > 0 ? field.getWidth() : field.getPreferredWidth() ;
tabsWidth += fieldwidth + getBorderAndPaddingWidth(field);
int fieldHeight = field.getHeight() > 0 ? field.getHeight() : field.getPreferredHeight();
if (fieldHeight > tabHeight) {
tabHeight = getBorderAndPaddingHeight(field) + fieldHeight;
}
int fieldPaddingTop = field.getPaddingTop();
if (fieldPaddingTop > tabPaddingTop) {
tabPaddingTop = fieldPaddingTop;
}
int fieldPaddingLeft = field.getPaddingLeft();
if (fieldPaddingLeft > tabPaddingLeft) {
tabPaddingLeft = fieldPaddingLeft;
}
}
}
if (label != null) {
layoutChild(label, width - tabsWidth, height);
int y = tabHeight - label.getHeight() >> 1;
setPositionChild(label, tabPaddingLeft , y);
}
for (int i = 0; i < tabs.size(); i++) {
Field tabField = (Field) tabs.elementAt(i);
setPositionChild(tabField, width - tabsWidth, getBorderAndPaddingHeight(tabField));
tabsWidth -= tabField.getWidth() + getBorderAndPaddingWidth(tabField);
}
setExtent(width, tabHeight);
}
private int getBorderAndPaddingHeight( Field field ) {
int height = field.getPaddingTop() + field.getPaddingBottom();
Border border = field.getBorder();
if( border != null ) {
height += border.getTop() + border.getBottom();
}
return height;
}
private int getBorderAndPaddingWidth( Field field ){
int width = field.getPaddingLeft() + field.getPaddingRight();
Border border = field.getBorder();
if( border != null ) {
width += border.getLeft() + border.getRight();
}
return width;
}
protected int moveFocus(int amount, int status, int time) {
if ((status & Field.STATUS_MOVE_FOCUS_VERTICALLY) == Field.STATUS_MOVE_FOCUS_VERTICALLY && amount > 0) {
return amount;
} else
return super.moveFocus(amount, status, time);
}
protected int nextFocus(int amount, int axis) {
if (amount > 0 && axis == Field.AXIS_VERTICAL)
return -1;
else
return super.nextFocus(amount, axis);
}
}
Here is the sample code:
class MailBoxSampleListField extends MainScreen implements FolderListener, StoreListener {
private static final int COLUMN_WIDTH_STATUS = 10;
private static final int COLUMN_WIDTH_DATE = 150;
private static final int COLUMN_WIDTH_NAME = 150;
public ListField myList;
private ListCallback myCallback;
public Vector sampleList = new Vector();
public Vector sampleVector;
private class ListCallback implements ListFieldCallback {
public Vector myVector = new Vector();
public Bitmap LIST_IMAGE = Bitmap.getBitmapResource("New.PNG");
public void drawListRow (ListField list, Graphics g, int index, int y,int w) {
displayList(g,0,y,w,(( Message )myVector.elementAt( index )), LIST_IMAGE); // for drawing the list row
for( int ii = 0; ii < sampleVector.size(); ii++) {
String text = ( String )sampleVector.elementAt(ii);
int liney = y + ( ii * list.getFont().getHeight() );
g.drawText( text, LIST_IMAGE.getWidth() + 5, liney, Graphics.ELLIPSIS, w );
}
}
public Object get( ListField list, int index ) {
return myVector.elementAt(index);
}
public int indexOfList( ListField list,String p, int s ) {
return myVector.indexOf(p,s);
}
public int getPreferredWidth ( ListField list ) {
return Graphics.getScreenWidth();
}
public void insert(Message _message, int index) {
myVector.addElement(_message);
}
public void erase () {
myVector.removeAllElements();
}
}
MailBoxSampleListField() {
ListCallback myCallback = new ListCallback();
try {
Store store = null;
store = Session.getDefaultInstance().getStore();
store.addStoreListener( this );
// retrieve Folder object fow which we want to receive message notification
try {
Folder[] folders = store.list();
Folder[] f1 = store.findFolder( "inbox" );
Folder vinbox = f1[0];
for (int i =0; i < f1.length; i++) {
f1[i].addFolderListener( this );
}
Message[] vmessages = vinbox.getMessages();
for ( int j = 0; j < vmessages.length; ++j ) {
if(vmessages[j] != null){
sampleList.addElement( vmessages[j] );
}
}
myList = new ListField(); // initialize the ListField
for ( int k = 0; k < sampleList.size(); k++ ) {
myList.insert(k);
myCallback.insert(vmessages[k], k);
}
myList.setCallback( myCallback );
add( myList );
}
catch( Exception e ){
}
}
catch ( Exception se ) {
}
}
public void displayList( Graphics g, int x, int y, int width, Message _message, Bitmap LIST_IMAGE ) {
g.drawBitmap(0, y, LIST_IMAGE.getWidth(), LIST_IMAGE.getHeight(), LIST_IMAGE, 0, 0);
sampleVector = new Vector();
Date d = _message.getReceivedDate();
Calendar c = Calendar.getInstance();
c.setTime(d);
StringBuffer sb = new StringBuffer();
sb.append( c.get( Calendar.MONTH ) );
sb.append('-');
int digit = c.get( Calendar.DAY_OF_MONTH );
if ( digit < 10 ) sb.append(0);
sb.append( digit );
sb.append(' ');
sb.append( c.get( Calendar.HOUR_OF_DAY ) );
sb.append(':');
digit = c.get( Calendar.MINUTE );
if ( digit < 10 ) sb.append( 0 );
sb.append( digit );
sb.append( ' ');
x += LIST_IMAGE.getWidth()+5;
x += COLUMN_WIDTH_DATE;
try {
String name = "<noname>";
if ( _message.isInbound() ) {
Address a = _message.getFrom();
if ( a != null )
{
name = a.getName();
if ( name == null || name.length() == 0 ) name = a.getAddr();
}
}
else
{
//get the first Recipient address
Address[] set = _message.getRecipients(Message.RecipientType.TO);
if ( set != null && set.length > 0 )
{
name = set[0].getName();
if ( name == null || name.length() == 0 ) name = set[0].getAddr();
}
}
sampleVector.addElement(name +" " + sb.toString());
} catch (MessagingException e) {
System.err.println(e);
}
x += COLUMN_WIDTH_NAME;
int remainingColumnWidth = Graphics.getScreenWidth() - x;
//get the subject, or if that doesn't exist, the first line of the body
String textToDisplay = _message.getSubject();
if ( null == textToDisplay) //no subject! get the first line of the body if present
{
Object o = _message.getContent();
if ( o instanceof String )
{
textToDisplay = (String)o;
}
else if ( o instanceof Multipart )
{
Multipart mp = (Multipart)o;
int count = mp.getCount();
for (int i = 0; i < count; ++i)
{
BodyPart p = mp.getBodyPart(i);
if ( p instanceof TextBodyPart )
{
textToDisplay = (String)p.getContent();
}
}
}
}
sampleVector.addElement(textToDisplay);
} public void messagesAdded(FolderEvent e) {} public void messagesRemoved(FolderEvent e) { } public void batchOperation( StoreEvent se) { }
}
I'm not sure what you mean, could you please post a screenshot so that we can see the problem?
I'll try to help out the best I can. In my limited experience, I have noticed that in a listfield, if you have not set the row height (with setRowHeight()) to a big enough height, graphics (including text) that overflow over the size of the row will not be displayed. Have you tried setting the row height to 2 * list.getFont().getHeight() or more?
If not all rows are displayed, then I think you've missed to call myList.setSize(myVector.size());
I'm not sure what you mean by "wrapping not happening"...
The drawListRow() will be called repeatedly (for the amount of times set by the setSize() that I've suggested above).
In your current code you iterate through the whole myVector on each drawListRow() call - this is wrong.
You must use the value y which is declare in drawListRow (ListField list, Graphics g, int index, int y,int w)
like
g.drawText( text, LIST_IMAGE.getWidth() + 5, y+liney, Graphics.ELLIPSIS, w )
I am facing this issue for long time finally i got the solution.
As Alex say, you need to implement your own wrapper class, something that looks like:
TextWrapper theWrapper = new TextWrapper();
String[] wrappedText = theWrapper.textWrap(longText, wrappingWidth , 2);
//
// now draw text line by line
//
g.drawText(wrappedText[0], x, y, DrawStyle.LEFT, width);
if (wrappedText.length > 1) {
g.drawText(wrappedText[1], x, y + textFont.getHeight(), DrawStyle.LEFT | DrawStyle.ELLIPSIS, width);
}
where
public class TextWrapper {
... // put here methods used by textWrap method
//
// textWrap splits input String in lines having width as maxWidth
//
public String[] textWrap(String s, int maxWidth, int maxLines)
{
String[] result;
... // do here the wrap job on input string s
return result;
}
}