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: 26
Registered: ‎06-19-2009
My Device: Not Specified
Accepted Solution

navigationClick() invoked when clicking outside of a field.

I have the following code below for the Blackberry Storm.  Its purpose is to make a menu screen with initially 4 BitmapFields which can be clicked.  The buttons all function correctly and regester and respond to the navigationClick() event.  However, if I click outside of any field - the navigationClick() event is invoked on whichever field has focus - even though the click is outside of this field.

 

Any help is appreciated 

 

 

public class MainMenu extends MainScreen {

    private MenuScreenLayoutManager menuScreen ;
    protected MenuItem soundOn , soundOff , resume ;
    protected UiApplication addix;
    
    public MainMenu ( UiApplication addix ) {
        super(MainScreen.FOCUSABLE | MainScreen.NO_VERTICAL_SCROLL);
        this.addix = addix ;
        LabelField title = new LabelField("Addix",  LabelField.HCENTER | LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);
        setTitle ( title ) ;   
        
        
        getMainManager().setBackground( BackgroundFactory.createBitmapBackground( Bitmap.getBitmapResource("menu_background.png") ) ) ;
        

        MenuItem play =   new MenuItem( MenuItem.PLAY ,      Bitmap.getBitmapResource( "play_button.png"     ) , Field.FOCUSABLE , this );
        MenuItem stats =  new MenuItem( MenuItem.STATS ,     Bitmap.getBitmapResource( "stats_button.png"    ) , Field.FOCUSABLE , this);
        MenuItem help =   new MenuItem( MenuItem.HELP ,      Bitmap.getBitmapResource( "help_button.png"     ) , Field.FOCUSABLE , this);
        resume = new MenuItem( MenuItem.RESUME ,    Bitmap.getBitmapResource( "resume_button.png"   ) , Field.FOCUSABLE , this);
        soundOn =new MenuItem( MenuItem.SOUND_ON ,  Bitmap.getBitmapResource( "sound_on_button.png" ) , Field.FOCUSABLE , this);
        soundOff=new MenuItem( MenuItem.SOUND_OFF , Bitmap.getBitmapResource( "sound_off_button.png") , Field.FOCUSABLE , this);
        
        menuScreen = new MenuScreenLayoutManager() ;
        menuScreen.add( play ) ;
        menuScreen.add( stats ) ;
        menuScreen.add( help ) ;
        menuScreen.add( soundOn ) ;
        
        add ( menuScreen ) ;
    }
    
    private void addResume(){
        menuScreen.add( resume ) ;
    }
    
    private void removeResume(){
        menuScreen.delete( resume ) ;
    }
}


class MenuItem extends BitmapField{
    
    public static final int PLAY = 0 ;
    public static final int RESUME = 1 ;
    public static final int STATS = 2 ;
    public static final int HELP = 3 ;
    public static final int SOUND_ON = 4 ;
    public static final int SOUND_OFF = 5 ;
    protected int type;
    private MainMenu mainMenu;
    

    public MenuItem( int type, Bitmap bm , long style , MainMenu mainMenu ){
        super( bm , style) ;
        this.type = type ;
        this.mainMenu = mainMenu ;
    }
    
    protected boolean navigationClick( int status, int time ){
        System.out.println("Type " + type);
        Field field ;
        switch( type ){
            case 0:
                System.out.println("Play" );
                    synchronized (UiApplication.getEventLock()) {
                        mainMenu.addix.pushScreen( new GameScreen( mainMenu.addix , mainMenu ) );
                    }
            break ;
            case 1:
                System.out.println("resume" );
            break ;
            case 2:
                System.out.println("Stats" );
            break ;
            case 3:
                System.out.println("help" );
            break ;
            case 4:
                System.out.println("sound-on" );
                this.getManager().replace ( this ,   mainMenu.soundOff ) ;
            break ;
            case 5:
                System.out.println("sound off" );
                this.getManager().replace ( this ,   mainMenu.soundOn ) ;
                
            break ;
            
        }
        return true ;
    }

    protected void drawFocus(Graphics _g, boolean _on) {  /* do nothing */ }  
}



class MenuScreenLayoutManager extends VerticalFieldManager {
    
    private MenuItem field;
    private static final int menuItemsStartPos = 260 ;
    private static final int menuItemHeight = 41 ;
    private static final int menuItemWidth = 142 ;
    private final int screenWidth = getWidth();
    
    public MenuScreenLayoutManager(){
        super(Manager.RIGHTMOST | Manager.VERTICAL_SCROLL | Manager.VERTICAL_SCROLLBAR);
    }
        
    protected void sublayout(int width, int height) {
    
                int numberOfFields = getFieldCount();
                int menuXloc = 360-menuItemWidth ;
                for ( int i=0 ; i < numberOfFields ; i++ ){
                    field = (MenuItem) getField(i);
                    switch( field.type ){
                    
                        case 0:
                            setPositionChild( field , menuXloc , menuItemsStartPos+ ( menuItemHeight + 3 )  );    
                            layoutChild( field , width , height);
                        break ;
                        
                        case 1:
                            setPositionChild( field , menuXloc , menuItemsStartPos );    
                            layoutChild( field , width , height);
                        break ;
                        
                        case 2:
                            setPositionChild( field , menuXloc ,  menuItemsStartPos+ 2 * ( menuItemHeight + 3 ) );   
                            layoutChild( field , width , height);
                        break ;
                        
                        case 3:
                            setPositionChild( field , menuXloc ,  menuItemsStartPos+ 3 * ( menuItemHeight + 3 ) );    
                            layoutChild( field , width , height);
                        break ;                    
                        
                        case 4:
                        case 5:
                            setPositionChild( field , 70 , menuItemsStartPos+ 3 * ( menuItemHeight + 3 )  );      
                            layoutChild( field , width , height);
    
                    }
                    
                }
                    setExtent( 360, 460 );
            }
        }

Developer
Posts: 984
Registered: ‎02-10-2009
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

[ Edited ]

Try with changing the line super(MainScreen.FOCUSABLE | MainScreen.NO_VERTICAL_SCROLL); with

//super(MainScreen.NON_FOCUSABLE | MainScreen.NO_VERTICAL_SCROLL);

super(MainScreen.NO_VERTICAL_SCROLL);

Regards

Bikas

Message Edited by bikas on 06-27-2009 04:07 AM
Developer
Posts: 26
Registered: ‎06-19-2009
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

I tried that - no dice.

 

I also followed the below thread:

 

http://supportforums.blackberry.com/rim/board/message?board.id=java_dev&message.id=23111&query.id=68...  

 

I have the same problem, but this solution does not seem to work for me 

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

This sounds like expected behavior to me. The click will always register for the field that has the focus.

 

What were you expecting in this situation?

 

 

Developer
Posts: 26
Registered: ‎06-19-2009
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

I expect that if I click INSIDEa field that:

 

1.  It will gain focus

2.  It trigger the navigationClick( ) method.

 

I expect that if I click OUTSIDE a field that:

 

1.  focus remains on the last field to have focus

2.  No navigationClick( ) event is triggered (since I did not click any field)

Developer
Posts: 4,764
Registered: ‎07-21-2008
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

Are you doing this on the simulator?

 

Developer
Developer
Posts: 1,123
Registered: ‎02-10-2009
My Device: 8130 / 8350 / 9530 / 9550 / 9850 / PlayBook
My Carrier: Verizon

Re: navigationClick() invoked when clicking outside of a field.

If you are using the Storm, why are you using navigationClick and not touchEvent? Also, try returning super.navigationClick and not true. It seems like the screen is not delegating the focus correctly.
Developer
Posts: 304
Registered: ‎08-01-2008
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

This is one of the many design flaws (IMO) of the touch event on blackberry. What you are getting is by design.

 

If you click anywhere on the screen where there is no field under the point of click, the click event will be dispatched to the field currently with focus. You have to override the touchEvent and write a "isWithinBounds" method which simply checks that the x and y coordinates are lesser than the width and height of the field.

 

If the touch event is within the bounds of the field on which it is called, you handle it, otherwise you ignore it. 

Highlighted
New Developer
Posts: 11
Registered: ‎05-05-2009
My Device: Not Specified

Re: navigationClick() invoked when clicking outside of a field.

Thanks for your advice it helped me too.

I have tweaked the code to do it the other way. I added a function to the Manager, that it should ignore all clicks outside of fields. That way you do not have to override each individual field.

Here is the code, just add it as is to your manager.

 

protected boolean touchEvent(TouchEvent message)
{
 int event = message.getEvent();
 if (event == TouchEvent.CLICK || event == TouchEvent.UNCLICK)
 {
  // Ignore clcik events that happen outside any fields
  if (getFieldAtLocation(message.getX(1), message.getY(1)) == -1)
   return true;    // kill the event
 }
 return super.touchEvent(message);
}

// The regular getFieldAtLocation returns wrong values in open spaces in complex managers, so we override it
public int getFieldAtLocation(int x, int y)
{
 XYRect rect = new XYRect();
 int index = getFieldCount() -1;
 while (index >= 0)
 {
  getField(index).getExtent(rect);
  if (rect.contains(x, y))
   break;
  --index;
 }
 return index;
}

 

Hope this helps, 

Lionscribe

Regular Contributor
Posts: 96
Registered: ‎06-09-2011
My Device: sdk 9800
My Carrier: java development

Re: navigationClick() invoked when clicking outside of a field.

Thank u very much lionscribe....it works for me............

Press the Kudos button (star) on the left side to thank and
please mark the Thread as solved if its solved...


Thanks and Regards
Nagarjuna