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: 92
Registered: ‎02-22-2011
My Device: Not Specified
Accepted Solution

Custom stylish EditField (textbox)

[ Edited ]

Hi!

 

I was wondering if there is any way of creating cute UI components for our applications. I would like to have something like this:

 

searchbox.png

 

But the BB EditField is very very ugly. I've tryed a custom EditField from (http://www.blackberryforums.com/developer-forum/218757-custom-text-edit-filed-vertical-scroll.html)

 

But it looks like this:

 

searchboxBB-3.png

 

It's completely styless and ugly, not decent for any application. For having it cute, we should override the paint method and draw a Bitmap simulating a cute EditField?

 

public void paint(Graphics g) {
	super.paint(g);
	g.drawBitmap(0, 0,50, 50, Bitmap.getBitmapResource("profile.png"), 10, 10);
	//g.drawRect(0, 0, getWidth(), getHeight());
}

 

 

If we paint a Bitmap with fixed width and height, will we see it very small or to big if the resolution is changed? For example, in Bold with 480x360 or in Curve with 320x240.

 

Thank you!

 

 

Highlighted
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Custom stylish EditField (textbox)

First - there are no built-in components like the one you want.

 

Second - the article you referred to has some very harmful code which you'd better avoid. I don't know what drunk monkey first put getManager().invalidate() inside paint, but that piece of code has found its way into more than one BlackBerry UI article on the 'Net. Avoid it like a plague.

 

Third - you need to paint the Bitmap first and then call super.paint. Otherwise your bitmap will paint over the letters!

 

Fourth - indeed, the image will look different on different screens. There is a drawTexturedPath method which allows all kinds of affine transformations as well as tiling of the original Bitmap. It is quite efficient, but might distort some Bitmaps. There is also drawShadedFilledPath, which creates some kind of gradient background. Finally, there are all kinds of useful classes in net.rim.device.api.ui.decor package (available since 4.6).

 

And finally, the response to your first question - yes, there is more than one way of creating cute UI components. Here is the full code of my experiment with rounded border text boxes (it comes out multi-line, vertically scrollable) - you can experiment there with colors and other stuff.

 

import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FocusChangeListener;
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.UiApplication;
import net.rim.device.api.ui.component.EditField;
import net.rim.device.api.ui.container.VerticalFieldManager;

public	class RoundBorderTextBoxField extends Manager implements FocusChangeListener {
	private int managerWidth;
	private int managerHeight;
	private int inactiveBorderColor = Color.BLACK;
	private int activeBorderColor = Color.BLACK;
	private int borderColor = inactiveBorderColor;
	private int backgroundColor = Color.WHITE;
	private int arcWidth;

	private VerticalFieldManager vfm = new VerticalScrollManager(VERTICAL_SCROLL | USE_ALL_WIDTH | USE_ALL_HEIGHT);
	private EditField editField;

	RoundBorderTextBoxField(int width, int height, long style) {
		super(style | NO_VERTICAL_SCROLL | NO_HORIZONTAL_SCROLL);
		managerWidth = width;
		managerHeight = height;
        long innerStyle = style & (READONLY | FOCUSABLE_MASK); // at least
        if (innerStyle == 0) {
        	innerStyle = FOCUSABLE;
        }
        editField = new EditField("", "", EditField.DEFAULT_MAXCHARS, innerStyle);
        editField.setFocusListener(this);
		arcWidth = editField.getFont().getHeight() & 0xFFFFFFFE; // make it even

		add(vfm);
		vfm.add(editField);
	}
	
	public void setFont(Font font) {
		super.setFont(font);
		editField.setFont(font);
		arcWidth = editField.getFont().getHeight() & 0xFFFFFFFE;
		updateLayout();
	}

	public void setBorderColors(int inactive, int active) {
		inactiveBorderColor = inactive;
		activeBorderColor = active;
		invalidate();
	}
	
	public void setBackgroundColor(int bgColor) {
		backgroundColor = bgColor;
		invalidate();
	}

	RoundBorderTextBoxField(int width, int height) {
		this(width, height, 0L);
	}

	public String getText() {
		return editField.getText();
	}
	
	public void setText(String newText) {
		editField.setText(newText);
	}
	
	public void append(String addedText) {
		String newText = editField.getText() + addedText;
		editField.setText(newText);
		editField.setCursorPosition(newText.length());
		UiApplication.getUiApplication().invokeLater(new Runnable() {
			public void run() {
				vfm.setVerticalScroll(Math.max(0, vfm.getVirtualHeight() - vfm.getVisibleHeight()));
			}
		});
	}

	public int getPreferredWidth() {
		return managerWidth;
	}

	public int getPreferredHeight() {
		return managerHeight;
	}

	protected void sublayout(int w, int h) {
		if (managerWidth == 0) {
			managerWidth = w;
		}
		if (managerHeight == 0) {
			managerHeight = h;
		}
		int actWidth = Math.min(managerWidth, w);
		int actHeight = Math.min(managerHeight, h);
		layoutChild(vfm, actWidth - arcWidth, actHeight - arcWidth); // Leave room for border
		setPositionChild(vfm, arcWidth / 2, arcWidth / 2);	// again, careful not to stomp over the border
		setExtent(actWidth, actHeight);
	}

	protected void paint(Graphics g) {
		int prevColor = g.getColor();
		int myWidth = getWidth();
		int myHeight = getHeight();
		g.setColor(backgroundColor);
		g.fillRoundRect(0, 0, myWidth, myHeight, arcWidth, arcWidth);
		g.setColor(borderColor);
		boolean aaLines = g.isDrawingStyleSet(Graphics.DRAWSTYLE_AAPOLYGONS);
		g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, true);
		g.drawRoundRect(0, 0, myWidth, myHeight, arcWidth, arcWidth);
		g.drawRoundRect(1, 1, myWidth - 2, myHeight - 2, arcWidth - 2, arcWidth - 2);
		g.setDrawingStyle(Graphics.DRAWSTYLE_AAPOLYGONS, aaLines);
		g.setColor(prevColor);
		super.paint(g);
	}

	public void focusChanged(Field field, int eventType) {
		if (field == editField) {
			switch (eventType) {
			case FOCUS_GAINED:
			case FOCUS_LOST:
				adjustBorderColor();
				break;
			default:
				break;
			}
		}
	}
	
	private void adjustBorderColor() {
		int nextColor;
		if (editField.isFocus()) {
			nextColor = activeBorderColor;
		} else {
			nextColor = inactiveBorderColor;
		}
		if (borderColor != nextColor) {
			borderColor = nextColor;
			invalidate();
		}
	}
}

 

 

----------------------------------------------------------
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: 92
Registered: ‎02-22-2011
My Device: Not Specified

Re: Custom stylish EditField (textbox)

Uoo! Thanks you very much!

 

If someone needs it too, here is the code of the VerticalScrollManager (http://supportforums.blackberry.com/t5/Java-Development/Implementing-a-standard-style-scrollbar-on-a...)

 

I hope that in newer SDK versions the RIM people adds decent UI components, it makes no sense to write so much code to get some UI component when in Android and iPhone you can do them in 1 code line...

Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Custom stylish EditField (textbox)

As an author, I'm glad you liked that article Smiley Wink. Don't forget to check the comments for even cooler scrollbar design (semi-transparent, getting almost opaque on scroll, slowly fading when stabilized). There are a few suggestions there in the comments as well.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Regular Contributor
Posts: 81
Registered: ‎09-09-2010
My Device: Not Specified

Re: Custom stylish EditField (textbox)

HI, arkadyz

      Thank you for your code, it is userfual for me too  and I have a problem to use it in 9650 phone

like this

9650.JPG 

    

       as you can see, the font is so strange

 

       but in 9550 anything is ok

9550.JPG

 

      how do I solve this problem

Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Custom stylish EditField (textbox)

Unfortunately, I still can't see your images (a "feature" of these forums - pictures posted in certain way do not "appear" immediately for some users). However, the fonts you see depend on the system default font which you, as the user, can change.

In addition, my code contains a properly implemented setFont method. Choose your preferred BB font family, create a font, derive the one you want to see (size, style, etc.) and use setFont.

 

Good luck!

----------------------------------------------------------
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: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: Custom stylish EditField (textbox)

I saw the images immediately after posting my reply (another forum "feature"?). I recommend you check the default font and give height taking that font size into account (give more - see my sublayout code for all small "additions" to the font size).  It is obvious that you gave a height parameter (in pixels) which is too small for the current font.

Font.getDefault() will return you the font which will be used by your fields, well... by default. Either check that or indeed setFont to something smaller.

 

If you wish to continue discussing it, I recommend starting a new topic - this one is marked solved and it's not a good idea to post more and more in solved threads.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!