09-13-2012 11:20 PM
hey,
i have a screen with several embedded managers, almost all with their paint and/or paintbackground and/or their layout overridden...
i also had a customisedfield(extending field) that is used to wordwrap text that it is set, and then use drawText to draw the text( i jump to a index in the text that is close to the screen width, then parse the text char by char, and put each line into a vector, then use
graph.setBackgroundColor(0x00ECEBEB);
graph.setFont(GujaratiLexicon.rekha6);
int arraySize = stringToDraw.size();
for (int index = 0; index < arraySize; index++) {
if (this.Type.startsWith("word")) {
graph.setColor(0x00660901);
if (index > 0) {
graph.drawText(stringToDraw.elementAt(index).toStr ing(), 10,27 * (index));
} else {
graph.drawText(stringToDraw.elementAt(index).toStr ing(), 10, 5);
}
} else {
graph.setColor(Color.BLACK);
if (index > 0) {
graph.drawText(stringToDraw.elementAt(index).toStr ing(), 5,27 * (index));
} else {
graph.drawText(stringToDraw.elementAt(index).toStr ing(), 5, 5);
}
}
} to draw the text( i had that in the paint method). I think this has been happening from the very beggening, but it is only after i had this code added on, that i finnally realised that every paint method of every manager gets executed one by one, in an infinite loop(i think). here are the various managers that i am using:
footerContainer = new VerticalFieldManager(VerticalFieldManager.FIELD_RIGHT | VerticalFieldManager.USE_ALL_WIDTH) { protected void paintBackground(Graphics graphics) { graphics.setBackgroundColor(0x00F3F3F3); graphics.clear(); super.paint(graphics); } }; ImageContainer = new HorizontalFieldManager(HorizontalFieldManager.USE_ ALL_WIDTH) { public void paint(Graphics graphics) { graphics.clear(); graphics.drawBitmap(4, 0, Display.getWidth(),Display.getHeight(), headrect_landscapeImg, 0, 0); super.paint(graphics); } }; searchiconContainer = new HorizontalFieldManager(); textBoxContainer = new VerticalFieldManager(VerticalFieldManager.FIELD_VC ENTER) { protected void paintBackground(Graphics graphics) { graphics.setColor(Color.WHITE); graphics.setBackgroundColor(0x00ECEBEB); } public void paint(Graphics g) { g.setColor(0x00ff8c00); g.drawRoundRect(0, 1, 392, 27, 10, 10); super.paint(g); } }; content = new HorizontalFieldManager(HorizontalFieldManager.USE_ ALL_WIDTH) { public void paint(Graphics graphics) { graphics.drawBitmap(0, 0, Display.getWidth(), getHeight(), brownhalfrect_landscapeImg, 0, 0); super.paint(graphics); } }; rectcontent = new VerticalFieldManager(VerticalFieldManager.USE_ALL_ WIDTH) { public void paint(Graphics graphics) { graphics.setBackgroundColor(0x00E1E1E1); graphics.setColor(0x00E1E1E1); graphics.fillRect(1, 0, 469,labelContainer.getHeight() + ftlContainer.getHeight() + 68); graphics.setColor(0x00660901); graphics.drawRoundRect(0, 0, 470, labelContainer.getHeight() + ftlContainer.getHeight() + 10, 0, 0); super.paint(graphics); } protected void sublayout(int width, int height) { super.sublayout(width, height); this.setExtent(470, labelContainer.getHeight() + ftlContainer.getHeight() + 11); } }; nextpreviousContainer = new HorizontalFieldManager(HorizontalFieldManager.USE_ ALL_WIDTH); nextContainer=new HorizontalFieldManager(); previousContainer=new HorizontalFieldManager(); buttonContainer = new HorizontalFieldManager(HorizontalFieldManager.USE_ ALL_WIDTH) { public void paint(Graphics graphics) { graphics.drawBitmap(0, 0, Display.getWidth(),Display.getHeight(), headerfooterlandscapeImg, 0, 0); } };
this repeated redrawing is adversely affecting my code performance, though its only now, with the application closing every 1-2 minutes due to lack of memory that i even realised this problem :-(
can someone tell mw why this is happening?(the repainting, not the lack of memory :-|)
the SCreen has 2 managers:
ContentContainer
FooterContainer.
ContentContainer contains:ImageContainer, RBGContainer, content, rectContent, npcContainer
ImageContainer contains: SearchiconContainer
rectContent contains:ftlContainer and labelContainer
ftlContainer contains FTContainer and MEaningFTContainer
LabelContainer contains the various customFields that has the wrapped text.
nextprevContainer contains nextContainer and prevContainer
09-14-2012 06:58 AM - edited 09-14-2012 07:00 AM
Just a quick look, this appears to be wrong:
protected void paintBackground(Graphics graphics) {
graphics.setBackgroundColor(0x00F3F3F3);
graphics.clear();
super.paint(graphics);
}
You may want to call super.paintBackground() but since you have cleared the area yourself that may just undo what you have done. So I would just remove that line.
Look for similar code in other places.
The other common cause of infinite loops is people updating the Field from within paint, like
this.setFont(..)
[Nite: <graphics..setFont() is fine]
or
this.setText( ).
Another one is calling invalidate() within paint().
09-14-2012 08:59 AM
hey,
thanks for the reply.
if i dont call that(super.paint), the fields of that manager dont get painted properly.
also, i have since found that, the paint methods are not getting called in an infinite loop- instead, they seem to be called 5-10 times everytime i scroll down.
But, the application still closes because of lack of memory...
do you have any suggestions to make my application more efficient?(use less memory?)
one final problem:
the paint method of my customfield appears to be called twice(right after the super.paint of the manager.)
why is that?
09-14-2012 10:43 AM
You shoud not call paint from paintBackground. If you have to do that then you have a bug.
Remember that pant will be called to update focus. So for example, the Manager's paint method might be called to paint when one Field looses focus and then paint again when the next Field gets focus. In addition remember that often paint is called with a very small context rectangle, say just the focus area. So even though it looks like your are painting everything all the time, in reality only a small bit of the screen will get updated.
To find your problem I suggest you use the profiler.
09-15-2012 01:33 AM
Hey peter,
am working with shreyas. this is our sample code for testing wordwrap. This code also call paint repeatedly.
public myscreen()
{
setTitle("wordwrap");
contentContainer = new VerticalFieldManager(
VerticalFieldManager.VERTICAL_SCROLL
| VerticalFieldManager.VERTICAL_SCROLLBAR
| VerticalFieldManager.USE_ALL_WIDTH
| VerticalFieldManager.USE_ALL_HEIGHT) {
protected void paint(Graphics graphics) {
graphics.setBackgroundColor(0x00F3F3F3);
graphics.clear();
super.paint(graphics);
}
};
lblField l=new lblField(440, "");
l.setText("When I stand before God at the end of my life, I would hope that I would not have a single bit of talent left, and could say, 'I used everything you gave me'.");
contentContainer.add(l);
add(contentContainer);
}
customized lblfield
package com.arnion.gujaratilexicon.field;
/*
* GridField.java
*
* © <your company here>, 2003-2005
* Confidential and proprietary.
*/
import java.util.Vector;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.UiApplication;
import com.arnion.gujaratilexicon.GujaratiLexicon;
import com.arnion.gujaratilexicon.util.Utility;
/**
*
*/
public class lblField extends Field
{
int WIDTH = 0;
int HEIGHT = 0;
int x = 0;
int y = 0;
String lblText="";
int iI=0;
String strToDraw="";
String strToTest="";
//String drawString[]={""};
int strWidth=0;
int SI=0;
String Type;
Vector stringToDraw=new Vector(1,1);
public lblField(int width,String text) {
this.WIDTH = width;
HEIGHT = 27;
this.Type=text;
stringToDraw.addElement("");
}
public int getPreferredWidth()
{
return WIDTH;
}
public int getPreferredHeight()
{
try {
return HEIGHT*stringToDraw.size();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return HEIGHT;
}
protected void layout(int arg0, int arg1)
{
setExtent(getPreferredWidth(), getPreferredHeight()+5);
}
protected void paint(Graphics g)
{
try {
g.setBackgroundColor(0x00ECEBEB);
g.setFont(GujaratiLexicon.rekha6);
int arraySize=stringToDraw.size();
for(int index=0;index<arraySize;index++){
if(this.Type.startsWith("word")){
g.setColor(0x00660901);
if(index>0){
g.drawText(stringToDraw.elementAt(index).toString
}else{
g.drawText(stringToDraw.elementAt(index).toString
}
}else{
g.setColor(Color.BLACK);
if(index>0){
g.drawText(stringToDraw.elementAt(index).toString
}else{
g.drawText(stringToDraw.elementAt(index).toString
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected int moveFocus(int amount, int status, int time) {
System.out.println("moveFocus -=======>");
return amount;
}
public void setText(String string) {
try {
SI=0;
iI=0;
strToDraw="";
strToTest="";
// drawString=null;
this.lblText=string;
int strSize=this.lblText.length();
int i=0;
boolean jump=true;
boolean multiLine=false;
boolean addedtoVector=false;
stringToDraw=new Vector(1,1);
for(i=0;i<strSize;i++)
{
if (lblText.length()>30) {
if (lblText.substring(SI).length() > 30) {
addedtoVector = false;
if (jump) {
strToTest = lblText.substring(i, i + 31);
i += 31;
jump = false;
}
char currentChar = 0;
try {
currentChar = this.lblText.charAt(i);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (currentChar == ' ' | currentChar == '.'
| currentChar == ',' | currentChar == ':'
| currentChar == '(' | currentChar == ')'
| currentChar == '[' | currentChar == ']'
| currentChar == ';' | currentChar == '&') {
iI = i;
}
strToTest = strToTest + currentChar;
strWidth = GujaratiLexicon.rekha6
.getAdvance(strToTest);
if (strWidth >= WIDTH - 20) {
jump = true;
try {
stringToDraw.addElement(lblText.substring(
SI, iI + 1));
addedtoVector = true;
/* = strToDraw + lblText.substring(SI, iI + 1) + "~";*/
} catch (Exception e) {
System.out
.println("Exception in lblField::"
+ e.getMessage());
e.printStackTrace();
}
SI = iI + 1;
i = SI - 1;
strToTest = "";
multiLine = true;
} else if (i == strSize - 1) {
stringToDraw.addElement(lblText.substring(SI,
strSize));
addedtoVector = true;
//strToDraw = strToDraw + lblText.substring(SI, strSize)+ "~";
jump = true;
}
} else {
stringToDraw.addElement(lblText.substring(iI));
addedtoVector = true;
i = lblText.length();
}
}else {
stringToDraw.addElement(lblText);
addedtoVector = true;
i = lblText.length();
}
}
if(lblText.length()==0){
stringToDraw.addElement(lblText);
}
//drawString=Utility.getInstance().split(strToDra
invalidate();
} catch (Exception e) {
e.printStackTrace();
}
}
public String getText() {
// TODO Auto-generated method stub
return stringToDraw.elementAt(0).toString();
}
}
09-15-2012 03:56 PM
I don't see anything in that latest code that would cause a paint loop. Are you positive it is from that class? If you take that field off the screen, are you still seeing an issue?
09-17-2012 04:11 AM
Yes this class calls the paint method repeatedly and make the stack overflow error. This one ridicules us. We tried different methods. but paint method calls repeatedly when we draw the text..
09-17-2012 07:02 AM