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
Trusted Contributor
Posts: 242
Registered: ‎03-16-2010
My Device: 9530
Accepted Solution

TouchEvent & FieldChangeListener both doesn't work

 

Hi,

 

    I have 2 bitmapfields and a buttonfield. I want all fields to trap click events. Initially I had added only fieldChangeListeners to all fields, but bitmap field didn't respond to them (despite making them Focusable). I added touchevent to handle click events  for all the fields, now all fields respond only touchEvents. Even buttonfield doesn't respond to fieldChange which it was responding before adding of touchEvent.

 

   Can anyone help me know the problem and the solution for the same. I want  all fields to respond to click events via touch or normal. Also in touchEvent, as navigationClick id added, so the menu doesn't come, but otherwise with the other click only menu comes which shouldn't and the fieldchangelistener should be handled.  Below is the code.

 

    private BitmapField  signOffBtn, profileBtn;
    private ButtonField btn;
    
    public LoggedUserScreen(UserBean user) {
        super();
        this.loggedUser = user;
        System.out.println("Into LoggedUserScreen : Got user");
        init();
        this.add(signOffBtn);
        this.add(profileBtn);
        this.add(btn);
    }
    
    private void init() {
        signOffBtn = new BitmapField (Bitmap.getBitmapResource("icon.png"),  BitmapField.FOCUSABLE ) {
            protected boolean navigationClick(int status, int time) {
                return true;    // handle click event
            }
        };
        profileBtn = new BitmapField (Bitmap.getBitmapResource("icon.png"),  BitmapField.FOCUSABLE ) {
            protected boolean navigationClick(int status, int time) {
                return true;    // handle click event
            }
        };
        btn = new ButtonField("button", BitmapField.HIGHLIGHT_SELECT |  BitmapField.FOCUSABLE);
        signOffBtn.setChangeListener(this);
        profileBtn.setChangeListener(this);
        btn.setChangeListener(this);
    }
    
    public void fieldChanged(Field field, int context) {
        if (field == signOffBtn) {
            System.out.println("********* SIGN OFF CLICKED");
        } else if (field == profileBtn) {
            System.out.println("********* PROFILE CLICKED");
        } else if (field == btn) {
            System.out.println("********* button CLICKED");
            System.exit(0);
        }
    }
    
   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;
  }
  
  protected boolean touchEvent(TouchEvent event) {
      
      switch(event.getEvent()) {
          case TouchEvent.DOWN:
            return true;
          case TouchEvent.MOVE:
            return true;
          case TouchEvent.UP:
            return true;
          case TouchEvent.CLICK:
            int index = getFieldAtLocation(event.getX(1), event.getY(1));
            // Ignore click events outside any fields
            if (index == -1)
                return true;
                
            Field field = getField(index);
            if (field == signOffBtn) {
                System.out.println("Touched SignOff");
            } else if (field == profileBtn) {
                System.out.println("Touched Profile");
            } else if (field == btn) {
                System.out.println("Touched Button");
            }
            return true;          
      }
      return false;
  }

 

 

 Thanks

 


--------------------------------------------------------------------------------
For any helpful answers give kudo's (star) to the helper.
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: TouchEvent & FieldChangeListener both doesn't work

A couple of thoughts:

1) You don't need to create your own int getFieldAtLocation(int, int) - any Manager already has that.

2) Don't process event.CLICK - process event.DOWN by setting focus to the touched field (which is the default action but you seem to have some custom Manager, so I'm not sure in your case). Something like this:

          case TouchEvent.DOWN:
            int index = getFieldAtLocation(event.getX(1), event.getY(1));
            // Ignore click events outside any fields
            if (index == -1)
                return super.touchEvent(event);
                
            Field field = getField(index);
            if (field.isFocusable()) field.setFocus();

3) See that return super.touchEvent(...)? That is the right way to do it - don't return true from touchEvent except from complex events like MOVE and GESTURE.  By returning true from DOWN you disrupt the processing of complex events.

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Trusted Contributor
Posts: 242
Registered: ‎03-16-2010
My Device: 9530

Re: TouchEvent & FieldChangeListener both doesn't work

 

arkadyz,

 

    I am just creating a banner that can be used for all screens in the application. But ya, this will be definetely part of other screens.

 

    I tried your idea i.e. removed from Click & imeplemented in Down as you have showed. I also got added an ImageButton from http://supportforums.blackberry.com/t5/Java-Development/issue-with-using-image-as-button/td-p/393157

 

My filedChanged code is :

    public void fieldChanged(Field field, int context) {
        if (field == signOffBtn) {
            System.out.println("********* SIGN OFF CLICKED");
        } else if (field == profileBtn) {
            System.out.println("********* PROFILE CLICKED");
        } else if (field == btn) {
            System.out.println("********* button CLICKED");
            System.exit(0);
        } else if (field == imageBtn) {
            System.out.println("************ IMAGE BTN CLICKED");
        }
    }

 

My touchevent is :

 protected boolean touchEvent(TouchEvent event) {
      
      switch(event.getEvent()) {
          case TouchEvent.DOWN:
          
            int index = getFieldAtLocation(event.getX(1), event.getY(1));
            if (index == -1)
                return super.touchEvent(event);
                
            Field field = getField(index);
            System.out.println("Down Event Field = " + field);
            if (field.isFocusable())
                field.setFocus();
                
            return true;
          
          case TouchEvent.MOVE:
            return true;
          case TouchEvent.UP:
            return true;
          case TouchEvent.CLICK:
          /*
            int index = getFieldAtLocation(event.getX(1), event.getY(1));
            // Ignore click events outside any fields
            if (index == -1)
                return true;
                
            Field field = getField(index);
            if (field == signOffBtn) {
                System.out.println("Touched SignOff");
            } else if (field == profileBtn) {
                System.out.println("Touched Profile");
            } else if (field == btn) {
                System.out.println("Touched Button");
            } else if (field == imageBtn) {
                System.out.println("Touched Image Button");
            }
            return true;       
              */
      }
      return false;
  }

 

If I activate the TouchEvent.Down, I press left click or right click I can see only "Down Event Field = ...." except for ButtonField, for left click System.exit(0) is executed.

If I disable Down & activate Click event, on left click I get to see "Touched ...." SOP's and on right click, no action. Plus fieldChange for buttonField is also never acticvated (System.exit(0))

 

What to do ??

 


--------------------------------------------------------------------------------
For any helpful answers give kudo's (star) to the helper.
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: TouchEvent & FieldChangeListener both doesn't work

Don't ever return true; from touchEvent for such simple events as DOWN (haven't I said that in my previous post?). Use return super.touchEvent(...)!

 

Also, if you return true; from CLICK, fieldChanged() will not be called - the BlackBerry framework calls that only if it gets to process the event, which you just don't allow.

 

What are you trying to achieve? It seems that you are adding too much complexity to some really simple stuff. Could you just override navigationClick() on your Manager and branch according to your getFieldWithFocus()?

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Trusted Contributor
Posts: 242
Registered: ‎03-16-2010
My Device: 9530

Re: TouchEvent & FieldChangeListener both doesn't work

 

Hi,

   All I want am trying to do is, handle touch and click events for each buttons. Code FieldChangeListener handles cliekc events and touchEvent for touch clicks. As Simulator says "use left mouse button to click the screen and right mouse button to touch". Looking at this I belive on left click, fieldChanged() will be executed & on right click, touchEvent() will be executed. I have already added navigationClick() for 2 bitmapFields. With the below code, with left mouse clikc I get following results but don't get any results on right mouse click :

Touched SignOff

Touched Profile

Touched Image Button

Touched Button

********* button CLICKED

/*
 * LoggedUserScreen.java
  */

package gd;

import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.ui.decor.*;
import net.rim.device.api.system.Bitmap;
import backend.UserBean;

public class LoggedUserScreen extends MainScreen implements FieldChangeListener {
    private UserBean loggedUser = null;
    
    private BitmapField  signOffBtn, profileBtn;
    private ButtonField btn;
    private ImageButton imageBtn;
    
    public LoggedUserScreen(UserBean user) {
        super();
        this.loggedUser = user;
        System.out.println("Into LoggedUserScreen : Got user");
        init();
        this.add(signOffBtn);
        this.add(profileBtn);
        this.add(btn);
        this.add(imageBtn);
    }
    
    private void init() {
        signOffBtn = new BitmapField (Bitmap.getBitmapResource("icon.png"),  BitmapField.FOCUSABLE | ButtonField.FIELD_LEFT) {
            protected boolean navigationClick(int status, int time) {
                return true;    // handle click event
            }
        };
        profileBtn = new BitmapField (Bitmap.getBitmapResource("icon.png"),  BitmapField.FOCUSABLE | ButtonField.FIELD_RIGHT ) {
            protected boolean navigationClick(int status, int time) {
                return true;    // handle click event
            }
        };
        imageBtn = new ImageButton(Bitmap.getBitmapResource("icon.png"), Bitmap.getBitmapResource("icon.png")); 
        btn = new ButtonField("button", BitmapField.HIGHLIGHT_SELECT |  BitmapField.FOCUSABLE | ButtonField.FIELD_RIGHT);
        signOffBtn.setChangeListener(this);
        profileBtn.setChangeListener(this);
        imageBtn.setChangeListener(this);
        btn.setChangeListener(this);
    }
    
    public void fieldChanged(Field field, int context) {
        if (field == signOffBtn) {
            System.out.println("********* SIGN OFF CLICKED");
            SignOff();
        } else if (field == profileBtn) {
            System.out.println("********* PROFILE CLICKED");
        } else if (field == btn) {
            System.out.println("********* button CLICKED");
            System.exit(0);
        } else if (field == imageBtn) {
            System.out.println("************ IMAGE BTN CLICKED");
        }
    }
    
    private void disposeAll() {
        loggedUser = null;
        return;
    }
    
    private void SignOff() {
        int response = Dialog.ask(Dialog.D_YES_NO, "Sure Sign Off ?"); 
            if (response == -1) {   // No
            } else{                 // Yes
                //SaveUserInfo();
                disposeAll();
                System.exit(0);
            }
    }
    
   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;
  }
  
  protected boolean touchEvent(TouchEvent event) {
      boolean returnValue = super.touchEvent(event);
      switch(event.getEvent()) {
          case TouchEvent.DOWN:
            return true;
          case TouchEvent.MOVE:
            return true;
          case TouchEvent.UP:
            return true;
          case TouchEvent.CLICK:
          
            int index = getFieldAtLocation(event.getX(1), event.getY(1));
            // Ignore click events outside any fields
            if (index == -1)
                return returnValue;
                
            Field field = getField(index);
            if (field == signOffBtn) {
                System.out.println("Touched SignOff");  
                //SignOff();
            } else if (field == profileBtn) {
                System.out.println("Touched Profile");
            } else if (field == btn) {
                System.out.println("Touched Button");
                fieldChanged(field, 0);
            } else if (field == imageBtn) {
                System.out.println("Touched Image Button");
            }
            return returnValue; 
      }
      return returnValue;
  }
} 

 

/*
 * ImageButton.java
 *
 * Code is taken from : http://supportforums.blackberry.com/t5/Java-Development/issue-with-using-image-as-button/td-p/393157
 * 
 */

package gd;


import net.rim.device.api.system.Bitmap;
import net.rim.device.api.ui.FieldChangeListener;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Color;
import net.rim.device.api.system.EncodedImage;
import net.rim.device.api.system.Characters;
import net.rim.device.api.ui.component.BitmapField;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.container.VerticalFieldManager;
import net.rim.device.api.ui.Manager;

public class ImageButton extends Field 
{

    private Bitmap _currentPicture;
    private Bitmap _onPicture;
    private Bitmap _offPicture;
    private int id;
    
    
    public ImageButton (Bitmap  onImage, Bitmap offImage)
    {
       super(Field.FOCUSABLE);
       _offPicture = offImage;
       _onPicture = onImage;
       _currentPicture = _onPicture;
    }
    
    public void setButtonId(int id)
    {
        this.id = id;
    }
    public int getButtonId()
    {
        return this.id;
    }    
    
    public int getPreferredHeight()
    {
        return _onPicture.getHeight();
    }
    
    
    public int getPreferredWidth()
    {
        return _onPicture.getWidth();
    }
    
    protected void onFocus(int direction)
    {
        _currentPicture = _offPicture;
        invalidate();
    }
    
    protected void onUnfocus()
    {
        _currentPicture = _onPicture;
        invalidate();
    }
    
    protected void drawFocus(Graphics g, boolean on)
    {        
        g.setBackgroundColor(Color.BLACK);
    }
    
    protected void layout(int width, int height) 
    {
        setExtent(Math.min( width, getPreferredWidth()), Math.min( 
                            height, getPreferredHeight()));
    }

    protected void paint(Graphics graphics) 
    {
        graphics.setBackgroundColor(Color.BLACK);
        graphics.clear();
        graphics.fillRect(0, 0, getWidth(), getHeight());
        graphics.drawBitmap(0, 0, getWidth(), getHeight(), 
                             _currentPicture, 0, 0);
    }

    protected boolean navigationClick(int status, int time)
    {
        fieldChangeNotify(0);
        return true;
    }
    
    public boolean keyChar(char key, int status, int time)
    {
        if (key == Characters.ENTER)
        {
            fieldChangeNotify(0);
            return true;
        }
        return false;
    }
}

 

Shouldn't both the clicks respond in click & touch event ? Where am I going wrong to manage the normal click (fieldChanged) after adding touchEvent ? Should I have to call fieldChanged(field, 0) for other buttons also in touchEvent as added for btn and is working also ? fieldChangeNotify(0) is already added in ImageButton, but that also doesn't work.

 

Also, if I am wrong in understanding the click and touch click hanadled by left & right mouse click kindly let me know for better understanding.

 

 

Thanks,

 

 


--------------------------------------------------------------------------------
For any helpful answers give kudo's (star) to the helper.
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: TouchEvent & FieldChangeListener both doesn't work

Well - your overriding of navigationClick in ImageButton is correct. And since it is entirely sufficient to invoke your fieldChanged(), you don't have to override touchEvent() at all!  When you press and click a focusable field on a touch screen, the default BB framework reaction is to first set focus to that field (thanks to DOWN event always preceding CLICK event) and then to invoke navigationClick (and later navigationUnclick - that's where BB framework often performs its own stuff).

 

Now, if you absolutely need to perform some additional stuff on touch, you can do that.  By the way, I think that invoking super.touchEvent(...) before your own processing is not the best approach - just put break; in each case and in the end, after the switch statement, return super.touchEvent(...).

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Trusted Contributor
Posts: 242
Registered: ‎03-16-2010
My Device: 9530

Re: TouchEvent & FieldChangeListener both doesn't work

 

Ok, modified the touchEvent replacing return statements in switch with break & removed handling for imageBtn.

 

On click on imageBtn, its fieldChanged() get fired. But then the focus stays on it only. I mean if I click somewhere else then also, "IMAGE BTN CLICKED" is displayed. So the focus doesn't go away after event is fired. I guess in fieldChanged(), after all activities are done the focus should be removed from it.

How to remove the focus from ImageButton once fieldChanged is fired ?

 

Also, if you have idea to access files from local web server, can you have a look at http://supportforums.blackberry.com/t5/Java-Development/Access-Web-Service-java-net/m-p/613026#M1275...

and help me if possible.

 

Thanks a lot. Just now Image Btn should lose its focus on completing its work.

 


--------------------------------------------------------------------------------
For any helpful answers give kudo's (star) to the helper.
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: TouchEvent & FieldChangeListener both doesn't work

You cannot call removeFocus - it is hidden deep in BlackBerry framework. However, you can call somethingElse.setFocus() if you wish...

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Trusted Contributor
Posts: 242
Registered: ‎03-16-2010
My Device: 9530

Re: TouchEvent & FieldChangeListener both doesn't work

 

Ya I already looked for it, their is nothing like removeFocus or setFocus(false) or so. But yes, your something.setFocus gave me the idea to setFocus to the screen itself so the focus is removed from the button also and not on any component that can trap the event.

 

So, if I add fieldChangeNotify(0); in navigationclick of signOffBtn, profileBtn & btn, then I totally don't need to implement touchEvent ?

 

    private void init() {
        signOffBtn = new BitmapField (Bitmap.getBitmapResource("icon.png"),  BitmapField.FOCUSABLE | ButtonField.FIELD_LEFT) {
            protected boolean navigationClick(int status, int time) {
                fieldChangeNotify(0);
                return super.navigationClick(status, time);    // handle click event
            }
        };
        profileBtn = new BitmapField (Bitmap.getBitmapResource("icon.png"),  BitmapField.FOCUSABLE | ButtonField.FIELD_RIGHT ) {
            protected boolean navigationClick(int status, int time) {
                fieldChangeNotify(0);
                return super.navigationClick(status, time);    // handle click event
            }
        };
        imageBtn = new ImageButton(Bitmap.getBitmapResource("icon.png"), Bitmap.getBitmapResource("icon.png")); 
        btn = new ButtonField("button", BitmapField.HIGHLIGHT_SELECT |  BitmapField.FOCUSABLE | ButtonField.FIELD_RIGHT) {
            protected boolean navigationClick(int status, int time) {
                fieldChangeNotify(0);
                return super.navigationClick(status, time);    // handle click event
            }
        };
        
        signOffBtn.setChangeListener(this);
        profileBtn.setChangeListener(this);
        imageBtn.setChangeListener(this);
        btn.setChangeListener(this);
    }

 

touchEvent is totally removed & navigationClick is implemented for each button.

 

Thanks. Just want to confirm, with this, will my all componetns work for touchscreen & non-touch screen properly. in 9530 Simulator touch screen (left mouse click) is responding but non-touch i.e. a click (right muose clisk) doesn't respond anything. So wondering.....

 


--------------------------------------------------------------------------------
For any helpful answers give kudo's (star) to the helper.
Developer
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: TouchEvent & FieldChangeListener both doesn't work

 


trupti wrote:

 

So, if I add fieldChangeNotify(0); in navigationclick of signOffBtn, profileBtn & btn, then I totally don't need to implement touchEvent ? 


That's the idea - to let the framework do its job.  I wouldn't bother too much about simulator not working properly - check on a real phone and see.  Simulators do a good job mimicking the real UI interactions, but sometimes they fail.

 

Once you are satisfied with the results, can you mark this thread as solved?

 

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