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: 239
Registered: ‎07-26-2010
My Device: Z10
My Carrier: Telkomsel

Background color won't change

I'm trying to write a custom field

 

import net.rim.device.api.system.Display;
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.container.VerticalFieldManager;

public class CustomItemField extends VerticalFieldManager {
	
	private int height = 40;
	private int bgColorFocused, bgColorUnfocused;
	
	public CustomItemField(){
		bgColorFocused = Color.RED;
		bgColorUnfocused = Color.GRAY;
	}

	protected void paintBackground(Graphics graphics) {
		if (isFocus()) graphics.setColor(bgColorFocused);
		else graphics.setColor(bgColorUnfocused);
		super.paintBackground(graphics);
	}
	
	protected void paint(Graphics graphics) {
		graphics.drawRect(0, 0, Display.getWidth(), 100);
		if (isFocus()) graphics.setBackgroundColor(bgColorFocused);
		else graphics.setBackgroundColor(bgColorUnfocused);
		super.paint(graphics);
	}
	
	protected void sublayout(int maxWidth, int maxHeight) {
		super.sublayout(maxWidth, height);
		setExtent(maxWidth, height);
	}
	
	public boolean isFocusable(){
		return true;
	}
}

 My expectation is when the field is being focused, the background color will be set to red. And while it's not, the background color is gray.

 

When I ran the code, the results are these:

Focused (red border)

focus.jpg

 

Unfocused (grey border)

unfocus.jpg

 

Only the border color changed. The background color of the field is still white. How to fix this?

 

Developer
Posts: 77
Registered: ‎04-01-2011
My Device: Bold 9700
My Carrier: Rogers

Re: Background color won't change

Someone else can explain the WHY , but this works for me .....

 

import net.rim.device.api.system.Display;
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.container.VerticalFieldManager;
import net.rim.device.api.ui.decor.Background;
import net.rim.device.api.ui.decor.BackgroundFactory;

public class CustomItemField extends VerticalFieldManager {
	
	private int height = 40;
	private int bgColorFocused, bgColorUnfocused;
	private Background bgFocused;
	private Background bgUnfocused;
	
	public CustomItemField(){
		bgColorFocused = Color.RED;
		bgColorUnfocused = Color.GRAY;

//Create backgrounds bgFocused = BackgroundFactory.createSolidBackground(bgColorFocused); bgUnfocused = BackgroundFactory.createSolidBackground(bgColorUnfocused); } protected void paintBackground(Graphics graphics) { if (isFocus()) graphics.setColor(bgColorFocused); else graphics.setColor(bgColorUnfocused); super.paintBackground(graphics); } protected void paint(Graphics graphics) { graphics.drawRect(0, 0, Display.getWidth(), 100);

//Code change below if (isFocus()) getManager().setBackground(bgFocused); else getManager().setBackground(bgUnfocused);
super.paint(graphics); } protected void sublayout(int maxWidth, int maxHeight) { super.sublayout(maxWidth, height); setExtent(maxWidth, height); } public boolean isFocusable(){ return true; } }

 

Developer
Posts: 239
Registered: ‎07-26-2010
My Device: Z10
My Carrier: Telkomsel

Re: Background color won't change

Hi eicheled,

 

1. How can I unfocus the field?

2. I have to remove the isFocusable part. Otherwise I'll get a NullPointerException.

Developer
Posts: 77
Registered: ‎04-01-2011
My Device: Bold 9700
My Carrier: Rogers

Re: Background color won't change

The code I submitted worked fine for me, for both focus and unfocus. I had added it to an existing project and it worked. To see if I could recreate your problem, I created a new app and just added your manager to a MainScreen and I was able to reproduce your error.

 

I made some changes to your class based on some other code that I have used and came up with the following. Hopefully this works for you and you can adapt it to your needs.

 

Maybe someone else can tell us both why the first solution doesn't always work!!

 

public class CustomItemField extends VerticalFieldManager {
	
	private int height = 40;
	private int bgColorFocused, bgColorUnfocused;
	private Background bgFocused;
	private Background bgUnfocused;
	private NullField nf;
	
	public CustomItemField(){
		bgColorFocused = Color.RED;
		bgColorUnfocused = Color.GRAY;
		bgFocused = BackgroundFactory.createSolidBackground(bgColorFocused);
		bgUnfocused = BackgroundFactory.createSolidBackground(bgColorUnfocused);
		
		nf = new NullField(NullField.FOCUSABLE) {
			  public void getFocusRect(XYRect rect) {
			    getManager().getExtent(rect);
			    rect.setLocation(0, 0);
			  }
			};
		add(nf);
	}

	protected void paintBackground(Graphics graphics) {
		if (nf.isFocus()) graphics.setColor(bgColorFocused);
		else graphics.setColor(bgColorUnfocused);
		super.paintBackground(graphics);
	}
	
	protected void paint(Graphics graphics) {
		graphics.drawRect(0, 0, Display.getWidth(), 100);
		if (nf.isFocus()) getManager().setBackground(bgFocused);
		else getManager().setBackground(bgUnfocused);;
		super.paint(graphics);
	}
	
	protected void sublayout(int maxWidth, int maxHeight) {
		super.sublayout(maxWidth, height);
		setExtent(maxWidth, height);
	}

}

 

Developer
Posts: 19,636
Registered: ‎07-14-2008
My Device: Not Specified

Re: Background color won't change

To quickly answer some of the questions:

 

a) paintBackground should actually pain the background, not just set a color.  If you are using paintBackground, then you are probably best setting the background color and then doing a clear.  Alternatively do a setColor to set the foreground color and then use a fillRect.  Either will do the job.  clear is preferred.

 

b) You should always make sure your processing has no side effects.  Looking at the original code,the paintBackground set the foreground color and so this was the side effect that caused the border to be painted in 'paint()'. 

 

This is how I would have coded paintBackground

int backcolor = graphics.getBackgroundColor();

try {

if (isFocus()) {

graphics.setBackgroundColor(bgColorFocused);

} else {

graphics.setBackgroundColor(bgColorUnfocused);

}

graphics.clear();

} finally {

graphics.setBackgroundColor(backColor);

}

 

c) I am old school, these sorts of things worked before Background was added as a class in OS 4.6.  Now you should use Background and use the supplied way of changing this based on the Ui status of the Field.  Look at the

setBackground(int visual, Background background)

method, and use this to control the background of your item.  Since this is all you really need to do, I suspect that you do not need to create a Manager for your CustomItem, you can probably do it directly with the actual Field and setBackground. 

 

d) Be careful with this sort of code:

 protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(maxWidth, height);
setExtent(maxWidth, height);
}

 

I would recommend that you try to be a bit more forgiving about this.  For example

 

 protected void sublayout(int maxWidth, int maxHeight) {

if ( maxHeight < height ) {

height = maxHeight;

}
super.sublayout(maxWidth, height);

if this.getHeight() > height ) {

height = this.getHeight();

} else {
setExtent(maxWidth, height);

}
}

 

If I haven't answered any questions let me know.