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
Posts: 298
Registered: ‎05-02-2010
My Device: Bold 9700
My Carrier: Verizon
Accepted Solution

Adding a LabelField with custom layout & paint freezes App.

This is the absolute weirdest thing I've ran into thus far. After trial and error for a good hour, I've narrowed it down to the following statements.

 

I have a Class that extends MainScreen, I add the following statements to the Class constructor and the App freezes each & ever time. The label field draws the String value of the variable title twice to create a white color text with a slight black shadow.

 

That's it... nothing else.

 

However, it freezes the App.

 

Is there something blatantly obvious that I'm missing?

 

 

LabelField t = new LabelField() {
	int xy = 14;

	protected void layout(int width, int height) {
		setExtent(width, getPreferredHeight() + xy);
	}

	protected void paint(Graphics g) {
		g.setColor(Color.BLACK);
		g.drawText(title, xy, xy - 3);
		g.setColor(Color.WHITE);
		g.drawText(sportTitle, xy, xy - 2);
		invalidate();
		super.paint(g);
	}
};

Font font = Font.getDefault().derive(Font.BOLD | Font.SANS_SERIF_STYLE, 8, Ui.UNITS_pt);
t.setFont(font);
add(t);

 

 

--Todd

Windows 7 Enterprise 64-bit (6.1 Build 7600) | Java SE Runtime Environment (build 1.6.0_24-b07) | Eclipse Version: 3.6.2 [M20110210-1200] | BlackBerry Eclipse Plug-in: 1.3.0.201102031007-19 | Java Compiler level: 1.3 | Targeting devices running OS 5 | Simulators: JDE 5.0 packaged 9700, 9630, 9300
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Adding a LabelField with custom layout & paint freezes App.

My first instinct is to remove invalidate() from your paint() method.

 

I'm pretty sure it's more of a typo in your case; in general, however, this is an extremely wrong approach, made worse by the frequency with which all kinds of "gurus" use it in their articles and replies. The endless loop it creates is "soft", meaning some useful work will have a chance to be done, but you'll be safer without it.

 

However, there are other problems in your code:

 

Your layout() code is insufficient. When you extend a real (non-abstract) field, you really want to use super.layout there somewhere - otherwise your super.paint will not know where to paint! Either extend Field and do all painting yourself (and then you might restrict layout to just setExtent - but you really want to do more there, calculating widths, positions, etc.), or call super.layout somewhere.

 

Your exersizes with two drawText calls will be messed up by the subsequent super.paint call. Call super.paint first, then paint over it (in general, you should be careful with this approach, but here it makes sense).

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Developer
Posts: 298
Registered: ‎05-02-2010
My Device: Bold 9700
My Carrier: Verizon

Re: Adding a LabelField with custom layout & paint freezes App.

@

 

 

 

 

 

 

setExtent(width, getPreferredHeight() + xy);

 So, where is the proper place or best practice to layout AND paint text, bitmaps, etc. at a specific XY coordinate?

 

 

--Todd

Windows 7 Enterprise 64-bit (6.1 Build 7600) | Java SE Runtime Environment (build 1.6.0_24-b07) | Eclipse Version: 3.6.2 [M20110210-1200] | BlackBerry Eclipse Plug-in: 1.3.0.201102031007-19 | Java Compiler level: 1.3 | Targeting devices running OS 5 | Simulators: JDE 5.0 packaged 9700, 9630, 9300
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Adding a LabelField with custom layout & paint freezes App.

There are two logical places for that (layout AND paint):

 

1) layout (sublayout for managers) to calculate the positions. For example, imagine implementing word wrap: it makes sense to calculate the lines and their starting positions inside layout rather than paint which is called much more often and needs to be more efficient. For images, you might want to extract the one most fitting here since that's where you determine your field's dimensions.

2) paint (subpaint for managers) to actually draw text, lines, pictures, gradient-filled polygons etc. at the positions, calculated during layout and saved in your Field's (Manager's) class members.

 

A side note: width and height passed into your layout are maximum values available. So:

1) don't just use all of those, compute how much you actually need (if you place your custom LabelField, as written, in a HorizontalFieldManager, it will consume the whole remaining width, not leaving any room for all subsequent fields). Use image.getWidth(), font.getAdvance(text) etc. for such calculations.

2) honor those maximums - meaning write your setExtent call like this:

 

setExtent(Math.min(yourWidth, width), Math.min(yourHeight, height));

 

Good luck - you have the skill and the will to learn, so luck is the only remaining thing you need!

 

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Developer
Posts: 298
Registered: ‎05-02-2010
My Device: Bold 9700
My Carrier: Verizon

Re: Adding a LabelField with custom layout & paint freezes App.

OK, I'm close. I have to be.

 

I've updated the statements to the following and now I just need to figure out how to use the method setPosition within the layout method. The String value of title always begins at 0,0 not 14,14.

 

I called the method updateLayout within the layout method and that blew-up.

 

How do I properly use setPosition in this instance where I want my LabelField to be layed out at the 14,14 coordinate?

 

 

LabelField t = new LabelField() {
	int xy = 14;

	protected void layout(int width, int height) {
		Font f = Font.getDefault();
		int myWidth = f.getAdvance(title)
				+ Math.abs(f.getAdvance(title) / 2);
		int myHeight = f.getHeight();

		super.layout(Math.min(myWidth, width),
				Math.min(myHeight, height));
		setPosition(xy, xy);
		setExtent(Math.min(myWidth, width), Math.min(myHeight, height));

	}

	protected void paint(Graphics g) {
		super.paint(g);
		g.setColor(Color.BLACK);
		g.drawText(title, 0, -1);
		g.setColor(Color.WHITE);
		g.drawText(title, 0, 0);
	}
};

 

 

--Todd

Windows 7 Enterprise 64-bit (6.1 Build 7600) | Java SE Runtime Environment (build 1.6.0_24-b07) | Eclipse Version: 3.6.2 [M20110210-1200] | BlackBerry Eclipse Plug-in: 1.3.0.201102031007-19 | Java Compiler level: 1.3 | Targeting devices running OS 5 | Simulators: JDE 5.0 packaged 9700, 9630, 9300
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Adding a LabelField with custom layout & paint freezes App.

Actually, setPosition is a very, very unpredictable call:

setPosition from within a Field's layout will compete with setPositionChild from the parent Manager's sublayout - and you don't know what is the parent's order of actions!  It might first call either layoutChild, invoking your Field's layout, or setPositionChild. If it first calls layoutChild, your setPosition will be overwritten by the subsequent parent Manager's setPositonChild.

 

If you want specific locations for your fields, your best bet is a custom layout Manager. There are quite a few examples. The following knowledge base article has some very basic stuff, but can give you enough ideas:

Create a custom layout manager for a screen

 

In the following post I discussed the approach to creating your own AbsoluteFieldManager (necessary if you want to have it on pre-OS6.0 phones):

AbsoluteFieldManager on OS prior to 5.0

There should be enough details to get you started.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Developer
Posts: 298
Registered: ‎05-02-2010
My Device: Bold 9700
My Carrier: Verizon

Re: Adding a LabelField with custom layout & paint freezes App.

This is a lot clearer now. Thank you!

 

 

LabelField t = new LabelField() {
	protected void layout(int width, int height) {
		Font f = Font.getDefault();
		int myWidth = f.getAdvance(title)
				+ Math.abs(f.getAdvance(title) / 2);
		int myHeight = f.getHeight();

		super.layout(Math.min(myWidth, width),
				Math.min(myHeight, height));
		setExtent(Math.min(myWidth, width), Math.min(myHeight, height));
	}

	protected void paint(Graphics g) {
		super.paint(g);
		g.setColor(Color.BLACK);
		g.drawText(title, 0, -1);
		g.setColor(Color.WHITE);
		g.drawText(title, 0, 0);
	}
};

HorizontalFieldManager hfm = new HorizontalFieldManager(
		Manager.NO_HORIZONTAL_SCROLL | Manager.NO_HORIZONTAL_SCROLLBAR) {

	protected void sublayout(int width, int height) {
		Field f = getField(0);
		int myWidth = Display.getWidth();
		int myHeight = 45;

		super.sublayout(Math.min(myWidth, width),
				Math.min(myHeight, height));
		setExtent(Math.min(myWidth, width), Math.min(myHeight, height));
		setPositionChild(f, 10, 14);
	}
};

hfm.add(t);
add(hfm);

 

 

--Todd

Windows 7 Enterprise 64-bit (6.1 Build 7600) | Java SE Runtime Environment (build 1.6.0_24-b07) | Eclipse Version: 3.6.2 [M20110210-1200] | BlackBerry Eclipse Plug-in: 1.3.0.201102031007-19 | Java Compiler level: 1.3 | Targeting devices running OS 5 | Simulators: JDE 5.0 packaged 9700, 9630, 9300