If you are using Internet Explorer, please remove blackberry.com from your compatibility view settings.

Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Developer
anta40
Posts: 223
Registered: ‎07-26-2010
My Device: Z10
My Carrier: Telkomsel

StackOverflowError on sublayout?

I have this code:

public class InfoScreen extends MainScreen {

	private VerticalFieldManager vfm;
	private HorizontalFieldManager hfm;
	private CustomTextField tf;
	private String info;
	
	public InfoScreen(){
		super(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR | USE_ALL_HEIGHT | USE_ALL_WIDTH);
		vfm = new VerticalFieldManager(NO_VERTICAL_SCROLL | NO_VERTICAL_SCROLLBAR | USE_ALL_HEIGHT | USE_ALL_WIDTH);
   		vfm.setBackground(BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("background_vertical.png")));
   	
		//#ifdef GEMINI
		tf1= new CustomTextField(220,170);
		//#elseif MONZA
		tf1 = new CustomTextField(400, 340);
		//#endif
    	
		info = FileUtil.loadFromResource("info.txt");
		
		tf.setText(info);
		Font font = Font.getDefault().derive(Font.PLAIN, 7, Ui.UNITS_pt);
		tf.setFont(font);
		tf.setBorder(BorderFactory.createBevelBorder(new XYEdges(1, 1, 1, 1)));
		EmptyField e;
		
		//#ifdef GEMINI
		e = new EmptyField(20, 60);
		//#elseif MONZA
		ee = new EmptyField(40, 350);
		//#endif
		hfm = new HorizontalFieldManager();
		
		//#ifdef BB_GEMINI
		//hfm.add(new EmptyField(15, 5));
		//#endif
		
		hfm.add(new EmptyField(40, 10));
		hfm.add(tf);
		vfm.add(e);
		vfm.add(hfm);
		add(vfm);
	}
	
	//#ifndef MONZA
	protected void sublayout(int width, int height) {
		switch (Display.getOrientation()){
			case (Display.ORIENTATION_PORTRAIT):
				deleteAll();
				hfm.deleteAll();
				vfm.deleteAll();
				
				hfm.add(new EmptyField(40, 10));
				hfm.add(tf);
				vfm.add(new EmptyField(40, 350));
				vfm.add(hfm);
		    	
				vfm.setBackground(BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("background_vertical.png")));
				add(vfm);
								
				break;
			
			case (Display.ORIENTATION_LANDSCAPE):
				deleteAll();
				vfm.setBackground(BackgroundFactory.createBitmapBackground(Bitmap.getBitmapResource("background_horizontal.png")));
				break;
		}
		super.sublayout(width, height);
	}
	//#endif
}

 The purpose of the code is to be able to display the layout correctly boty in landspace and portrait mode.

When I run it on 9870 simulator, I got this:

App Error 104
Uncaught:smileyfrustrated:tackOverflowError


But if hfm.add(tf) is removed from sublayout(),  then the code runs fine. No exception triggered at all. Any idea why?

 

 

Please use plain text.
Developer
RexDoug
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: StackOverflowError on sublayout?

Any operation that causes another call to subLayout() will result in a recursive call, which results in another recorsive call, ad naseum.

 

This results in a stack overflow.

 

Please use plain text.
Trusted Contributor
omar123456789
Posts: 103
Registered: ‎11-07-2010
My Device: Not Specified

Re: StackOverflowError on sublayout?

inserting, adding and deleting fields to the screen make call to sublayout,

and you add fields inside sublayout so it will call sublayout again and so on you will enter in an infinite loop,

 

the solution is so simple,

add all you fields in a single manager and overide its sublayout to change the positions and layouts for its childs not to add them again, then add this manager on to the screen,

Please use plain text.
Developer
anta40
Posts: 223
Registered: ‎07-26-2010
My Device: Z10
My Carrier: Telkomsel

Re: StackOverflowError on sublayout?

I think I found the cause the error, the CustomTextField class

 

import net.rim.device.api.ui.Color;
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.Manager;
import net.rim.device.api.ui.Ui;
import net.rim.device.api.ui.component.TextField;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.BackgroundFactory;


public class CustomTextField extends VerticalFieldManager  {
	private int fieldWidth;
	private int fieldHeight;
	private TextField textField;
	    
	    
	    public CustomTextField(int width, int height) {

	        super(Manager.NO_VERTICAL_SCROLL);
	        fieldWidth = width;
	        fieldHeight = height;
	        
	        Font fnt = Font.getDefault().derive(Font.PLAIN,6,Ui.UNITS_pt);
	        Font fff = Font.getDefault();
	        VerticalFieldManager vfm = new VerticalFieldManager(Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);

	        textField = new TextField() {
	            public void paint(Graphics g) {
	                getManager().invalidate();
	             //   g.setGlobalAlpha(150);
	                g.setColor(Color.WHITE);
	                super.paint(g);
	            }
	        };

	        textField.setEditable(false);
	        
	        vfm.add(textField);

	        add(vfm);
	    }

	    protected void paintBackground(Graphics arg0) {
	    	arg0.setGlobalAlpha(200);
	    	arg0.setBackgroundColor(Color.BLACK);
	    	arg0.clear();
	    	super.paintBackground(arg0);
	    }
	    
	    public void paint(Graphics g) {
	        // draw the border of the text area;
	        int color = g.getColor();
	        g.setColor(Color.BLACK);
	       // g.drawRect(0, 0, fieldWidth, fieldHeight);
	        g.setColor(color);
	        super.paint(g);
	    }

	    public void sublayout(int width, int height) {
	        if (fieldWidth == 0) {
	            fieldWidth = width;
	        }
	        if (fieldHeight == 0) {
	            fieldHeight = height;
	        }
	        super.sublayout(fieldWidth, fieldHeight);
	        setExtent(fieldWidth,fieldHeight);
	    }

	    public String getText() {
	        return textField.getText();
	    }
	    public void setText(String text) {
	        textField.setText(text);
	    }
}

 

If its sublayout() method is empty, indeed the application runs smoothly (no crash at all), but the result will be a black vertical field manager (the text it not shown).

Please use plain text.
Developer
peter_strange
Posts: 19,601
Registered: ‎07-14-2008
My Device: Not Specified

Re: StackOverflowError on sublayout?

[ Edited ]

I don't like some of the code you have there, but there is nothing immediately obvious to me.  I'm not the best person around and I don't have time to test.  But here are some comments and questions

 

The biggest thing is that I am really not clear what you are trying to do here.  It seems you want to set the size of a textField, without actually knowing how much data you are displaying.  This seems wrong to me on a number of counts. not least because you probably want this to be flexible based on the font used and the input device's screen size.  Can you describe what you are trying to achieve.  I think you can probably create something that does the job much more effectively than this will. 

 

Now the question

When this fails, are you specifying a width and height for the CustomTextField?

 

Now more comments.

 

You play round with global alpha and color.  This means your paint and paintBackground have side effects,  if you change these you should change them back.  I find the following structure really useful in paint and paintBackground

 

int currentColor = g.getColor()

int currentGA = g.getGlobalAlpha();

try {

...

super.....

...

} finally {

g.setGlobalAlpha(currentGA);

g.setColor(currentColor);

}

 

Not sure this will compile, but you get the idea...

 

Unless you know what you are doing, never call invalidate() from paint or paintBackground - it can be recursive...

So remove this line.  Now.

getManager().invalidate();

If this breaks something we should be able to fix it properly. 

 

You have multiple Managers in use here that seem redundant.  Why extend VFM and then create a VFM that you add to the VFM you are extending?  You should be able to achieve what you want adding a TextField to the CustomTextField (which is a Manager). 

 

In sublayout the height and width passed in are the maximum values you can use.  Period.  You should always check these.  Regardless of width and height you have requested, if your sublayout is passed in a width and height that is less than you want, you will NOT be given extra screen space.  So live in the boundaries you have been given.

 

So this:

super.sublayout(fieldWidth, fieldHeight);

should be

super.sublayout(Math.min(width,fieldWidth(, Math.min(height,fieldHeight));

 

If you call sublayout, then respect what it gives you.  Otherwise you will confuse the processing.  You asked it to lay out the fields and set the size it needs, then you should not change this.

 

There are cases when I do actually change it myself, but I do this on special occasions and only to add space.  So again, in this case if you really wanted to set the size, then you could replace this:

setExtent(fieldWidth,fieldHeight);

with

setExtent(Math.max(this.getWidth(),fieldWidth),Math.max(this.getHeight(),fieldHeight));

 

ANyway, fix up the issues here, rework your code, and if it is still not resolved, then post back the fixed code and we can investigate again. 

 

Please use plain text.
Developer
anta40
Posts: 223
Registered: ‎07-26-2010
My Device: Z10
My Carrier: Telkomsel

Re: StackOverflowError on sublayout?

Sorry for the bad code. I'll fix it ASAP after the top priorites are done.

 

What I want to achieve is a "sizeable transparent text field", like this.info_screen.png

 

Being able to be resized is very important, so the layout of the textfield still looks good wether in portrait or landscape orientation.

Initally I was going to put those 3 social media buttons in horizontal allignment, right under the text, but then I changed my mind.

Please use plain text.