I wrote my custom ObjectChoiceField.
In order to stretch the full width of ComboBox screen.
The class is presented below:
public class ComboBox extends ObjectChoiceField {
private final int PADDING_HEIGHT = 20;
private final int width;
private final int height;
public ComboBox(Object[] choices, int width) {
super("", choices, 0, FIELD_LEFT);
this.width = width;
this.height = getFont().getHeight() + PADDING_HEIGHT;
this.setMinimalWidth(width);
}
public int getPreferredHeight() {
return height;
}
public int getPreferredWidth() {
return width;
}
protected void layout(int w, int h) {
setExtent(width, height);
}
public void getFocusRect(XYRect rect) {
rect.set(getFont().getAdvance(getLabel()), 0, width, height);
}
}
It is works on simulator 9700, but does not work on 9800. I see throws next stacktrace:
C3CD62E3320B498 time: Wed Mar 23 15:10:29 2011 severity:1 type:3 app:Java Exception data:
IllegalArgumentException
No detail message
net_rim_cldc-13(4C48DD41)
Graphics
<private>
0x2726
net_rim_cldc-13(4C48DD41)
Graphics
tileRop
0x1C92
net_rim_cldc-19(4C48DD41)
BitmapBackground
draw
0xC4F
net_rim_cldc-16(4C48DD41)
ChoiceBox
draw
0x42AE
net_rim_cldc-16(4C48DD41)
ChoiceField
paint
0x55B0
net_rim_cldc-12(4C48DD41)
Field
paintSelf
0x6CF5
net_rim_cldc-13(4C48DD41)
Manager
paintChild
0x7040
net_rim_cldc-19(4C48DD41)
VerticalFieldManager
subpaint
0xC6F0
net_rim_cldc-13(4C48DD41)
Manager
<private>
0x91C8
net_rim_cldc-13(4C48DD41)
Manager
paint
0x7BA3
net_rim_cldc-12(4C48DD41)
Field
paintSelf
0x6CF5
net_rim_cldc-13(4C48DD41)
Manager
paintSelf
0x7C14
net_rim_cldc-13(4C48DD41)
Manager
paintChild
0x7040
net_rim_cldc-19(4C48DD41)
VerticalFieldManager
subpaint
0xC6F0
net_rim_cldc-13(4C48DD41)
Manager
<private>
0x91C8
net_rim_cldc-13(4C48DD41)
Manager
paint
0x7BA3
net_rim_cldc-12(4C48DD41)
Field
paintSelf
0x6CF5
net_rim_cldc-13(4C48DD41)
Manager
paintSelf
0x7C14
net_rim_cldc-13(4C48DD41)
Manager
paintChild
0x7040
net_rim_cldc-13(4C48DD41)
Manager
subpaint
0x72C2
net_rim_cldc-13(4C48DD41)
Manager
<private>
0x91C8
net_rim_cldc-13(4C48DD41)
Manager
paint
0x7BA3
net_rim_cldc-12(4C48DD41)
Field
paintSelf
0x6CF5
net_rim_cldc-13(4C48DD41)
Manager
paintSelf
0x7C14
net_rim_cldc-13(4C48DD41)
Manager
paintChild
0x7040
net_rim_cldc-13(4C48DD41)
Manager
subpaint
0x72C2
net_rim_cldc-13(4C48DD41)
Manager
<private>
0x91C8
net_rim_cldc-13(4C48DD41)
Manager
paint
0x7BA3
net_rim_cldc-12(4C48DD41)
Field
paintSelf
0x6CF5
net_rim_cldc-13(4C48DD41)
Manager
paintSelf
0x7C14
net_rim_cldc-13(4C48DD41)
Manager
paintChild
0x7040
net_rim_cldc-14(4C48DD41)
Screen
paint
0x3725
net_rim_cldc-12(4C48DD41)
Field
paintSelf
0x
Perhaps this is due to the fact that I use to build the project bb tools...
Do you have ideas how to fix?
You need to call super.layout(w,h) from your layout method, so the ObjectChoiceField can set its internal state correctly. After super.layout, you can then make any adjustments you need.
layout is causing the problem. If you remove it, it works.
Maybe you can set width but I am not sure for height.
Related
I would like to make a simple thing in XNA where the background would move when the character moves to the right.
Any ideas how to do it?
thanks
I think you mean like in the game Mario!
Using Scrolling.
Create the game class.
Load resources as described in the procedures of Drawing a Sprite.
Load the background texture.
private ScrollingBackground myBackground;
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
myBackground = new ScrollingBackground();
Texture2D background = Content.Load<Texture2D>("starfield");
myBackground.Load(GraphicsDevice, background);
}
Determine the size of the background texture and the size of the screen.
The texture size is determined using the Height and Width properties, and the screen size is determined using the Viewport property on the graphics device.
Using the texture and screen information, set the origin of the texture to the center of the top edge of the texture, and the initial screen position to the center of the screen.
// class ScrollingBackground
private Vector2 screenpos, origin, texturesize;
private Texture2D mytexture;
private int screenheight;
public void Load( GraphicsDevice device, Texture2D backgroundTexture )
{
mytexture = backgroundTexture;
screenheight = device.Viewport.Height;
int screenwidth = device.Viewport.Width;
// Set the origin so that we're drawing from the
// center of the top edge.
origin = new Vector2( mytexture.Width / 2, 0 );
// Set the screen position to the center of the screen.
screenpos = new Vector2( screenwidth / 2, screenheight / 2 );
// Offset to draw the second texture, when necessary.
texturesize = new Vector2( 0, mytexture.Height );
}
To scroll the background, change the screen position of the background texture in your Update method.
This example moves the background down 100 pixels per second by increasing the screen position's Y value.
protected override void Update(GameTime gameTime)
{
...
// The time since Update was called last.
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// TODO: Add your game logic here.
myBackground.Update(elapsed * 100);
base.Update(gameTime);
}
The Y value is kept no larger than the texture height, making the background scroll from the bottom of the screen back to the top.
public void Update( float deltaY )
{
screenpos.Y += deltaY;
screenpos.Y = screenpos.Y % mytexture.Height;
}
// ScrollingBackground.Draw
Draw the background using the origin and screen position calculated in LoadContent and Update.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
myBackground.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
In case the texture doesn't cover the screen, another texture is drawn. This subtracts the texture height from the screen position using the texturesize vector created at load time. This creates the illusion of a loop.
public void Draw( SpriteBatch batch )
{
// Draw the texture, if it is still onscreen.
if (screenpos.Y < screenheight)
{
batch.Draw( mytexture, screenpos, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}
// Draw the texture a second time, behind the first,
// to create the scrolling illusion.
batch.Draw( mytexture, screenpos - texturesize, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}
I was able to add the background only to the fields that were added in the screen with the below code:
VerticalFieldManager manager = new VerticalFieldManager();
Bitmap image = Bitmap.getBitmapResource("Penguins.jpg");
Background bg = BackgroundFactory.createBitmapBackground(image);
manager.setBackground(bg);
manager.add(new LabelField("HEll"));
add(manager);</code>
the output screen is like below:
How will get the image filled with whole screen, with the fields visible on top of it. Thank you
Bitmap background = Bitmap.getBitmapResource("background.png");
VerticalFieldManager vfm = new VerticalFieldManager(USE_ALL_HEIGHT | USE_ALL_WIDTH) {
public void paint(Graphics g) {
g.drawBitmap(0, 0, "Device Width", "Device Height",
background, 0, 0);
super.paint(g);
}
};
vfm.add(new LabelField("HEll"));
add(vfm);
You can also use this code to set the background image in Blackberry, But this works only 5.0 or above.
Background bg = BackgroundFactory.createBitmapBackground(Bitmap bitmap);
// OR
Background bg = BackgroundFactory.createBitmapBackground(Bitmap bitmap, int positionX, int positionY, int repeat);
this.getMainManager().setBackground(bg);
Could someone tell me how to catch this event?
Because when I rotated the phone to landscape mode, the app could not display correctly.
Thanks,
Duy
When this happens then BB UI framework definitelly calls layout(int width, int height) for your screen. This is because MainScreen is also a Manager, so it should layout all its child fields before BB UI framework starts painting.
So in layout() you could track current orientation state (with net.rim.device.api.system.Display.getOrientation()) and compare with the previous one. If it is changed, then the device has just been rotated.
I've come up with a method different to the suggested by Arhimed and it seems to work well (I use it to draw a custom Field differently - when the device is tilted). I have a method
protected void myOrientation() {
// portrait is true when dh > dw
boolean portrait = (Display.getOrientation() == Display.ORIENTATION_PORTRAIT);
// dw and dh = real horizontal and vertical dimensions of display - regardless of device orientation
int dw = portrait ? Math.min(Display.getWidth(), Display.getHeight()) : Math.max(Display.getWidth(), Display.getHeight());
int dh = portrait ? Math.max(Display.getWidth(), Display.getHeight()) : Math.min(Display.getWidth(), Display.getHeight());
// here I draw my custom Field
invalidate();
}
and call it once in the constructor and after that it is called on every Accelerometer event:
public class MyScreen extends MainScreen implements AccelerometerListener {
private MyScreen() {
if (AccelerometerSensor.isSupported()) {
orientationChannel = AccelerometerSensor.openOrientationDataChannel( Application.getApplication() );
orientationChannel.addAccelerometerListener(this);
}
....
}
public void onData(AccelerometerData accData) {
if (old != accData.getOrientation()) {
myField.myOrientation();
}
}
Maybe this helps you and yes - you have to check, if the keyboard is slided out on Torch
Regards
Alex
I've just started learning to develop blackberry apps and I've hit a bit of a snag. I'm unsure how I could move around a background image that is large than the field/manager it is being applied to. Here's an image to illustrate what I mean:
So far I have tried adding a Bitmap to a BitmapField inside a AbsolutePositionManager thinking I would be able to set the size of the absolute manager and just move the bitmapfield around inside it. That isn't the case, the manage just takes the size of the content inside it :(
I come from a frontend web dev background so what I'm looking for is something that behaves similar to the 'background-position' attribute in css or some sort of image mask.
Thanks in advance!
-- update --
This is a code sample of where I have got to. I now have a custom sized manager that displays a chunk of a larger BitmapField. I just need a way to move that BitmapField around.
package mypackage;
import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.container.AbsoluteFieldManager;
public class MyImage extends AbsoluteFieldManager {
protected void sublayout(int maxWidth, int maxHeight){
int displayWidth = 326;
int displayHeight = 79;
super.sublayout(displayWidth, displayHeight);
setExtent(displayWidth, displayHeight);
}
public MyImage(){
Bitmap _image = Bitmap.getBitmapResource("img.jpg");
BitmapField image = new BitmapField(_image);
add(image);
}
}
Rather than adding it as a Field, just store a reference to it somewhere in your Manager and then paint it yourself. Here's an untested example:
public class MyManager extends VerticalFieldManager() {
Bitmap _bg;
public MyManager() {
_bg = Bitmap.getBitmapResource("img.jpg");
}
protected void paint(Graphics graphics) {
graphics.drawBitmap(x_offset, y_offset, _bg.getWidth(), _bg.getHeight(), _bg, 0, 0);
super.paint(graphics);
}
}
Now you can just set x_offset and y_offset to whatever you want and it'll be shifted. If you need to mess with the size of the Manager to fit the Bitmap, add:
protected void sublayout(int width, int height) {
super.sublayout(width, height);
setExtent(Math.min(width, Math.max(getWidth(), _bg.getWidth())), Math.min(height, Math.max(getHeight(), _bg.getHeight()));
}
Hope this helps!
how i set background image in java blackberry simulator ?
backgroundBitmap = Bitmap.getBitmapResource("background.png");
MainScreen mainScreen = new MainScreen();
HorizontalFieldManager horizontalFieldManager =
new HorizontalFieldManager(
HorizontalFieldManager.USE_ALL_WIDTH |
HorizontalFieldManager.USE_ALL_HEIGHT){
//Override the paint method to draw the background image.
public void paint(Graphics graphics) {
//Draw the background image and then call paint.
graphics.drawBitmap(0, 0, 240, 240, backgroundBitmap, 0, 0);
super.paint(graphics);
}
};
try this blog post:
How to set Background Image in Blackberry
Or this support forum thread:
drawing bitmap in Mainscreen background
Bitmap bitmapOrig = Bitmap.getBitmapResource("ICON.png");
// Create a Bitmap of arbitrary size
int scaledX = 360;
int scaledY = 415;
Bitmap bitmapScaled = new Bitmap(scaledX, scaledY);
bitmapOrig.scaleInto(bitmapScaled , Bitmap.FILTER_LANCZOS);
bitmapOrig.scaleInto(bitmapScaled , Bitmap.FILTER_BILINEAR, Bitmap.SCALE_TO_FILL);
BitmapField bitmapFieldScaled2 = new BitmapField(bitmapScaled , Field.FOCUSABLE);
homeScreen.add(bitmapFieldScaled2);
HorizontalFieldManager horizontalFieldManager = new HorizontalFieldManager(
HorizontalFieldManager.USE_ALL_WIDTH |
HorizontalFieldManager.USE_ALL_HEIGHT){
//Override the paint method to draw the background image.
public void paint(Graphics graphics) {
//Draw the background image and then call paint.
graphics.drawBitmap(0, 0, 240, 240, backgroundBitmap, 0, 0);
super.paint(graphics);
}
protected void sublayout(int maxWidth, int maxHeight){
super.sublayout(240,240);
setExtent(240,240);
}
};