BlackBerry Forums Support Community

BlackBerry Forums Support Community (http://www.blackberryforums.com/index.php)
-   Developer Forum (http://www.blackberryforums.com/forumdisplay.php?f=15)
-   -   Painting a background on a MainScreen (http://www.blackberryforums.com/showthread.php?t=131014)

CELITE 05-20-2008 10:27 PM

Painting a background on a MainScreen
 
There is a thread with quite a few posts about this and I posted a solution there but it gets cumbersome trying to find the information.

I've posted it here again for easy reference.

How to create a MainScreen with a custom background, preserving scrolling and avoiding the use of padding field hacks:

Code:

class ExtendedCustomMainScreen extends CustomMainScreen {
    ExtendedCustomMainScreen() {   
        super();
        RichTextField rtf = new RichTextField( "This is a readonly textfield", Field.READONLY );
        LabelField helloWorld = new LabelField( "Hi jfisher!" );
        add( rtf );
        add( helloWorld );
    }
}

class CustomMainScreen extends MainScreen {
   
    private VerticalFieldManager _container;
   
    CustomMainScreen() {   
        super( Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR );
        setTitle( "Test" );
       
        VerticalFieldManager internalManager = new VerticalFieldManager( Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR ) {
            public void paintBackground( Graphics g )
            {
                g.setBackgroundColor( 0x99caf3 );
                g.clear();
            }
            protected void sublayout( int maxWidth, int maxHeight )
            {
                super.sublayout( maxWidth, maxHeight );
                XYRect extent = getExtent();
                int width = Math.max( extent.width, Display.getWidth() );
                int height = Math.max( extent.height, Display.getHeight() );
                setExtent( width, height );
            }
             
        };
        _container = new VerticalFieldManager( Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR );
        internalManager.add( _container );
        super.add( internalManager );
    }
   
    public void add( Field field ) {
        _container.add( field );
    }
   
}

class MainScreenWithBackgroundMain extends UiApplication {
   
    public static void main( String[] args ) {
        MainScreenWithBackgroundMain app = new MainScreenWithBackgroundMain();
        app.enterEventDispatcher();
    }
   
    MainScreenWithBackgroundMain() {   
        ExtendedCustomMainScreen mainScreen = new ExtendedCustomMainScreen();
        pushScreen( mainScreen );
    }
}


goulamass 09-02-2008 07:59 AM

Thanks a lot for this wondefull and helpfull post.

On the other topic I found a lot of explanation but it's a good idea to post a resume here.

Very good work and thanks again

Edit => Arff I spoke too fast. In fact when I use your customMainScreen and make my application extends it nothing appear.

For example my first screen display a picture
Code:

            //invoke the MainScreen constructor
            super();
            deleteAll();
            removeAllMenuItems();
           
            taillehorizon = Display.getWidth();
            taillevertical = Display.getHeight();

            deleteAll();
            bmp = new Bitmap(taillehorizon , taillevertical);
            picture = new BitmapField(bmp.getBitmapResource("Accueil.png"));
            add(picture);
            addMenuItem(menu1);
            addMenuItem(menu2);

So what's wrong???

My menuItems are present but not the picture. I have only a white screen

REdit => Maybe I should implement delete() and deleteAll() as you implement add()??

Edit again=> So when I implement delete() and deleteAll() it works fine for the first screen. But my program call other function and the background hasn't the color and fields don't appear.

In fact I use only one screen and I delete what I want and replace by new field to make my new screen.

Why the CustomMainScreen isn't used?? And how can I tell the program to keep it??

goulamass 09-03-2008 04:17 AM

No answer???

Dan East 09-03-2008 05:03 AM

getBitmapResource is a static method, so you don't have to create a Bitmap object to use it. I'm only recently getting back into java coding, so I'm very rusty on variable scope and garbage collection, but you're passing an object to BitmapField that you do not keep in scope, so perhaps it is being destroyed by the GC?

Instead of this:
bmp = new Bitmap(taillehorizon , taillevertical);
picture = new BitmapField(bmp.getBitmapResource("Accueil.png"));

Do this:
bmp = Bitmap.getBitmapResource("Accueil.png");
picture = new BitmapField(bmp);

And make sure bmp is static or a member of your class.

goulamass 09-03-2008 07:47 AM

Hum thanks for your answer but I think you have missunderstanding me.

I don't have any problem in displaying a picture.

The problem come from the background color.

I can change it only for the consctructor of my screen but when I call another function wich repaint all the screen I loose the color and I can't display anything on the screen

CELITE 09-03-2008 10:22 PM

When I call invalidate on the screen, add and remove fields etc., it seems to work fine. Can you explain further? I'm not sure I understand.

goulamass 09-04-2008 04:21 AM

Allright a quick exemple is better :

Code:

class MainScreenWithBackgroundMain extends UiApplication
{
   
    public static void main( String[] args )
    {
        MainScreenWithBackgroundMain app = new MainScreenWithBackgroundMain();
        app.enterEventDispatcher();
    }
   
    MainScreenWithBackgroundMain()
    {   
        ExtendedCustomMainScreen mainScreen = new ExtendedCustomMainScreen();
        pushScreen( mainScreen );
    }
}


class ExtendedCustomMainScreen extends CustomMainScreen
{
    ButtonField button1;
    ExtendedCustomMainScreen()
    {   
        super();
        RichTextField rtf = new RichTextField( "This is a readonly textfield", Field.NON_FOCUSABLE );
        LabelField helloWorld = new LabelField( "Hi jfisher!" );
        add( rtf );
        add( helloWorld );
        //deleteAll();
       
        Bitmap bmp = new Bitmap(20 , 20);
        BitmapField picture = new BitmapField(bmp.getBitmapResource("Logo1.png"));
        add(picture);
       
        button1 = new ButtonField("Change")
        {
            protected boolean trackwheelClick(int status, int time)
            {
                Next();
                return true;
            }         
        };
        add(button1);
    }
   
    public void Next()
    {
        delete(button1);
        System.out.println("fridibidihu");
        Bitmap bmp = new Bitmap(20 , 20);
        BitmapField picture = new BitmapField(bmp.getBitmapResource("Logo1.png"));
        add(picture);
    }
}

class CustomMainScreen extends MainScreen
{
   
    private VerticalFieldManager _container;
   
    CustomMainScreen()
    {   
        super( Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR );
        //setTitle( "Test" );
       
        VerticalFieldManager internalManager = new VerticalFieldManager( Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR )
        {
            public void paintBackground( Graphics g )
            {
                g.clear();
                int color = g.getColor();
                g.setColor( 0x99caf3 );
                g.fillRect( 0, 0, Display.getWidth(), Display.getHeight() );
                g.setColor( color );
            }
            protected void sublayout( int maxWidth, int maxHeight )
            {
                Field titleField = getMyTitleField();
                int titleFieldHeight = 0;
                if ( titleField != null )
                {
                    titleFieldHeight = titleField.getHeight();
                }
               
                int displayWidth = Display.getWidth();    // I would probably make these global
                int displayHeight = Display.getHeight();
   
                super.sublayout( displayWidth, displayHeight - titleFieldHeight );
                setExtent( displayWidth, displayHeight - titleFieldHeight );
            }
             
        };
        _container = new VerticalFieldManager( Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR );
        internalManager.add( _container );
        super.add( internalManager );
    }
   
    public void add( Field field )
    {
        _container.add( field );
    }
   
    public void delete( Field field )
    {
        _container.delete( field );
    }
    public void deleteAll()
    {
        _container.deleteAll();
    }
   
    private Field getMyTitleField()
    {
        Manager delegate = getDelegate();
        Field titleField = null;
        try
        {
            titleField = delegate.getField( 0 );
        }
        catch ( IndexOutOfBoundsException ioobe )
        {
            //
        }
        return titleField;
    }
}

So when Next() is called my screen becomes white and the picture isn't displayed (I can't add button or other.

So two questions.

Why my screen become white and no fields are added??

And how can I keep the backgroung color when calling next??

Dan East 09-04-2008 05:29 AM

This thread may help

Dan

goulamass 09-04-2008 07:22 AM

I read it already but when I read it again I understand some thing.

So correct me if I'm wrong but for each fonction I have to create a vertical manager with the properties I want and add it.

It's not so difficult so is it???

goulamass 09-04-2008 08:39 AM

Allright don't mind with it.

I found my solution.

Simply declare a verticalfield manager and add it to the screen and the I add fields to it.

Thanks for the time you spent on my problem

goulamass 09-04-2008 09:09 AM

Hum I speak too fast.

In fact I haven't problem when the verticalField is larger thant the screen but when it's smaller the background color just take it's size and not the whole screen.

How can I change this???

simon.hain 09-04-2008 09:36 AM

untested, by mreed over at the supportforums:
Code:

protected void paint( Graphics graphics ) {

    graphics.setBackgroundColor( 0xFF0000 );
    graphics.clear();

    // calling super.paint() will create the white background
    // so instead we will call subpaint() ourselves
    subpaint( graphics );
}


goulamass 09-04-2008 09:57 AM

No change with this. I paint only the background but not the entire screen

The problem come from that the verticalField hasn't the size of the screen.

When biggest no problem but when smallest...

CELITE 09-04-2008 10:01 PM

I edited the original post. It should fix your issue.

Couple comments:

You can't use the code simon references because the mainscreen does not paint past the display length (i.e. not the length of its delegate).

The only solution is to control the behavior of the delegate itself. However, you can't do that either so the next best thing is to make the delegate non-scrollable and then add a scrollable VerticalFieldManager to the delegate and ensure it is at least as big as the display.

I did employ simon's technique in paintBackground as it is a little faster.

goulamass 09-05-2008 10:20 AM

Really good job.

It's works very fine.

Thanks a lot for your helpfull answer

nyte3k 09-14-2008 01:26 PM

Everything works great...except...it seems that I cannot get anything aligned in the center (i.e. ...new VerticalFieldManager(VerticalFieldManager.FIELD_HC ENTER).

Seems like everything aligns from the left. When i remove the painted background screen subclass, it works fine.

CELITE 09-14-2008 03:44 PM

nyteek,

Could you post a code example of what you're trying to accomplish?

nyte3k 09-14-2008 08:38 PM

Quote:

Originally Posted by CELITE (Post 1100003)
nyteek,

Could you post a code example of what you're trying to accomplish?

Code:

public class PaintedBackgroundScreen extends MainScreen{
        private VerticalFieldManager container;
       
        public PaintedBackgroundScreen(){
                super( Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR);
        setTitle( "Test" );
       
        VerticalFieldManager internalManager = new VerticalFieldManager(Manager.NO_VERTICAL_SCROLL | Manager.NO_VERTICAL_SCROLLBAR) {
            public void paintBackground( Graphics g )
            {
                g.setBackgroundColor( 0x666666 );
                g.clear();
            }
            protected void sublayout( int maxWidth, int maxHeight )
            {
                    super.sublayout( maxWidth, maxHeight );
                XYRect extent = getExtent();
                int width = Math.max( extent.width, Display.getWidth() );
                int height = Math.max( extent.height, Display.getHeight() );
                setExtent( width, height );

            }
             
        };
        container = new VerticalFieldManager( Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
        internalManager.add(container);
        super.add( internalManager );
        }
       
        public void add( Field field ) {
                container.add( field );
        }


}

and I extend that class and use it normally...

Code:

public class AppMainScreen extends PaintedBackgroundScreen{
      private HorizontalFieldManager hfm = new HorizontalFieldManager(HorizontalFieldManager.FIELD_HCENTER);

public AppMainScreen(){
    hfm.add(new LabelField("SomeText"));
    add(hfm);
}
}

in that example... "SomeText" is still aligned left...i tried not using the paintedBG, and it works fine.... couldn't figure out what's going on.

goulamass 09-16-2008 10:11 AM

I'm thinking:

Is it possible by using the same method to use a picture in background???

nyte3k 09-18-2008 08:42 PM

Quote:

Originally Posted by goulamass (Post 1102429)
I'm thinking:

Is it possible by using the same method to use a picture in background???

Yes it is...

in your paintBackground() method you would have something like the following...

Code:

g.clear();
Bitmap bgImage = Bitmap.getBitmapResource("yourImage.png");
g.drawBitmap(0, 0, bgImage.getWidth(), bgImage.getHeight(), bgImage, 0, 0);



All times are GMT -5. The time now is 08:00 PM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.