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: 343
Registered: ‎02-23-2009
My Device: 8700 | 8310 | BOLD | STORM
Accepted Solution

updateDisplay() Question

[ Edited ]

The API for UIEngine.updateDisplay says:

Updates the display with pending graphics operations. This method flushes any queued graphics operations and updates the contents of the front buffer with the back buffer, making the contents of the back buffer to appear on the handheld's physical display. This technique allows applications to perform multiple operations on the back buffer and then flush all changes at once to the front buffer. This is done automatically after a paint, but an application may choose to do it explicitly when performing animations. Drawing on the back buffer is done with methods on the Graphics object returned from Screen.getGraphics(), and these will be clipped to the extent of the screen. Note that Screen.getGraphics() may in some circumstances return an off-screen buffer.

 

 

So can I call updateDisplay() instead of invalidate() to refresh the screen after I draw everything to the back buffer first? 

 

Thanks

Message Edited by RLord321 on 04-20-2009 01:06 AM
Developer
Posts: 558
Registered: ‎11-25-2008
My Device: Not Specified

Re: updateDisplay() Question

You can if you are in the correct thread at the correct time. This is why we normally use invalidate. When you call invalidate(), the screen gets updated automatically for you when you re-enter the Event Dispatcher.

 

You call enterEventDispatcher() usually after you pushscreen early on. Then you exit it to run a listener when some action happens like a key is pressed or  some other action happens. In the listener you may draw something or whatever, call invalidate() and exit. When this exit happens, we re-enter the Event dispatcher and the update will happen.

 

Calling updateDisplay() in the wrong place can cause an exception or can result in nothing happening, or worse still could cause a hanging of your application as the call to updateDisplay may assume you are in the Event Dispatcher and calling it from a listener might not exit the function as it's waiting for you to exit the listener before running parts of it's internals.

 

So, I'd recommend you try to do what you can with invalidate if possible.

 

Good Luck.

-Donald

 

 

Developer
Posts: 343
Registered: ‎02-23-2009
My Device: 8700 | 8310 | BOLD | STORM

Re: updateDisplay() Question

webmasterpdx,

 

Thanks for the reply.  I do normally use invalidate and yes it works fine but I was trying to do tile scrolling using the blackberry API (the GameCanvas of the java microedition API's and the Off Screen Buffers work so much better in my opinion but I'm trying to use the RIM API's...).   Again, usually I do all the drawing in the paint() method but when I tried to draw 16x16 tiles on a 320x240 screen, you could tell that it painted them directly to the screen instead of the offscreen buffer first and then flipping the back to the front like its supposed to do automatically.  So when you look at it, you see the graphics tearing and you can see artificats when it's doing the drawing and it doesn't look nice at all.

 

All I want is to draw everything to an offscreen buffer, and then draw the offscreen buffer to the front all at once.  I also tried drawing to an offscreen bitmap in the paint method first and then drawing that offscreen bitmap to the graphics object of the paint method but it still produced artifacts while drawing which is strange to me.

Developer
Posts: 558
Registered: ‎11-25-2008
My Device: Not Specified

Re: updateDisplay() Question

My understanding is that you derive your main class from a GameCanvas. You can use getGraphics to get the Graphics object for it's offscreen context.

You can then draw in that offscreen buffer using that Graphics object using Sprites or whatever. Then, when you are ready to display it, you call flushGraphics to dump that offscreen buffer to the display.

 

Look at the top of the javadocs for the GameCanvas for an example of such a loop.

 

 I hope that is of some use.

 

-Donald

Developer
Posts: 343
Registered: ‎02-23-2009
My Device: 8700 | 8310 | BOLD | STORM

Re: updateDisplay() Question

Thanks.  I know how to do this in the GameCanvas class but I was trying not to use that since you can't take full advantage of the Blackberry device.

 

I did find away to do it using the RIM API's, though.  I'm doing the same code, drawing to an offscreen Graphics object and then drawing that bitmap from that object to the graphics object in the paint method.  The only difference is that when I am drawing everything to the offscreen graphics object, I do it and make the system wait until its done by using invokeAndWait().  This stopped the flickering and/or tearing of the graphics.

 

Thanks

Developer
Posts: 558
Registered: ‎11-25-2008
My Device: Not Specified

Re: updateDisplay() Question

I'm curious, how do you use InvokeAndWait here? Do you call this from the Application class? What object do you pass in?

 

......just curious....

 

Also, FYI, it's not normal to give the Kudos to yourself :-) .....at least I don't think that even works....

 

Glad you got it working.

-Donald

Developer
Posts: 558
Registered: ‎11-25-2008
My Device: Not Specified

Re: updateDisplay() Question

This is what you were doing right? .....if I'm not mistaken....

 

http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800332/800505/800256/...

 

 

Thx

-D

Developer
Posts: 343
Registered: ‎02-23-2009
My Device: 8700 | 8310 | BOLD | STORM

Re: updateDisplay() Question

No. Not invokeLater()...It's baby brother, invokeAndWait()  :smileyhappy:

 

Here is my sample code:

public void run()

{

input();

process();

 

UiApplication.getUiApplication().invokeAndWait(new Runnable() { public void run() { drawStuff(); } }); invalidate();

}

 

public void drawStuff()

{

int xx = 0;
   int yy = 0;
       
   for(int row = m_nStartRow; row < m_nStartRow + 8 + 1; row++)
   {
       for(int col = m_nStartCol; col < m_nStartCol + 8 + 1; col++)
       {
            xx = (col - m_nStartCol) * 32;
            yy = (row - m_nStartRow) * 32;
               
            xx -= m_xScrollOffset;
            yy -= m_yScrollOffset;
            m_backGraphics.drawBitmap( xx, yy, 32, 32, m_tilesBitmap, getFrame( m_scrollTiles[row][col]), 1);               
   
        }
    }

}

 

protected void paint(Graphics graphics)
{      
      graphics.drawBitmap(40, 0, 240, 240, m_backBitmap, 0, 0);
     

// Black on sides to make this thing fit on the Pearls too
graphics.setColor( Color.BLACK);     

graphics.fillRect( 0, 0, 40, 240);

      graphics.fillRect( 280, 0, 40, 240);
}

 

 

If I just call drawStuff() without the invokeAndWait() method, the screen flickers.  I guess the blackberry is trying to handle other events at this time but I force it to wait until it's fully done repainting the back buffer.

 

So this code pretty much gets you scrolling tiles... RPG Game anyone???  I'm making a zelda-like game now :smileyhappy: