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
rakesh86shankar
Posts: 1,003
Registered: ‎05-22-2009
My Device: Not Specified
Accepted Solution

How to handle touch Event in the field

Hi,

 

I have created custom Check Box Field,When am i handling touch Event for it,focus is gettting inside it ,and when i try to click any Other Components such as Native Check Box,afer unchecking the custom CheckBox ,custom check  box is getting clicked again.

 

 

 

 

how to handle this?

 

Thanks

Rakesh Shankar

Please use plain text.
Developer
rakesh86shankar
Posts: 1,003
Registered: ‎05-22-2009
My Device: Not Specified

Re: How to handle touch Event in the field

Besides I am not gettting the click event in touch Event,I am getting up and down event ,I am extending this from field

Please use plain text.
Developer
peter_strange
Posts: 19,603
Registered: ‎07-14-2008
My Device: Not Specified

Re: How to handle touch Event in the field

Please use plain text.
Developer
rakesh86shankar
Posts: 1,003
Registered: ‎05-22-2009
My Device: Not Specified

Re: How to handle touch Event in the field

Hi Peter,I am adding full code,I am doing in the touch event of field,I am not getting touch event click alone,If this component gets focused,it is not going outside it,Still not able to figure of it why?

 

package com.app.ui.controls;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.KeypadListener;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.component.Dialog;

import com.app.interfaces.ClickListener;

public class CheckBoxField extends Field  implements ClickListener
{
	
	private String checkBoxLabel ;
	private int width  = Display.getWidth()*3/4; 
	private int height = 10;
	private Bitmap CheckImage = Bitmap.getBitmapResource("checkbox.png");
	private Bitmap UnCheckImage = Bitmap.getBitmapResource("uncheckbox_grey.png");
	private boolean isClicked = false;
	private ClickListener _listener;
	private Bitmap selectedImage = UnCheckImage;
	CheckBoxField thisfield;
	public CheckBoxField(String label){
		super(Field.FOCUSABLE);
		thisfield = this;
		checkBoxLabel = label;
		height = Math.max(CheckImage.getHeight(), UnCheckImage.getHeight());
		height = Math.max(height,this.getFont().getHeight());
	}
	
	public CheckBoxField( ){
		super(Field.FOCUSABLE);
		thisfield = this;
		checkBoxLabel = "Check box";
		height = Math.max(CheckImage.getHeight(), UnCheckImage.getHeight());
		height = Math.max(height,this.getFont().getHeight());
	}
	
	public void setWidth(int Width){
		width = Width ; 
		
	}
	
	public void setLabel(String label){
		checkBoxLabel = label ;
		width =  this.getFont().getAdvance(checkBoxLabel) + selectedImage.getWidth() + 10 ;
	}
	
	public void setClickListener(ClickListener listener) {
		_listener=listener;
	}
	
	public void setChecked(boolean isChecked){
		isClicked = isChecked ;
	}
	
	public void setFont(Font fnt){
		super.setFont(fnt);
	}
	public boolean getChecked(){
		return isClicked;
	}

	protected boolean navigationClick(int status, int time) {
		if ((status & KeypadListener.STATUS_TRACKWHEEL) != KeypadListener.STATUS_TRACKWHEEL) {
			System.out.println("navigationClick Is Clicked Status CLICK>>>"+isClicked);
			System.out.println("Is Clicked Status>>>"+isClicked);
			if(!isClicked){//If False Comes here
				isClicked = true ;			
			}else{//If True Comes here
				isClicked = false ;
				this.FieldClicked(this);
				return super.navigationClick(status,  time);
			}
			 return true;
		}
		return super.navigationClick(status, time);
	}	
	

	
    protected boolean touchEvent(TouchEvent message)
    {
		 if (message.getEvent()== TouchEvent.UNCLICK)
		 {
		     	return true;
		 }
         if (message.getEvent()==TouchEvent.CLICK)
         {
        	 System.out.println("Touch Event Is Clicked Status CLICK>>>"+isClicked);
        	 if(!isClicked){//If False Comes here
					isClicked = true ;			
				}else{//If True Comes here
					isClicked = false ;
				}
        	 this.invalidate();
        	 FieldClicked(this);
		     return true;
         }
         return super.touchEvent(message);
   } 

	
	protected void layout(int arg0, int arg1) {
		// TODO Auto-generated method stub
		this.setExtent(width, height);
	}

	protected void drawFocus(Graphics graphics, boolean on) {
		// TODO Auto-generated method stub
		super.drawFocus(graphics, on);
	}
	protected void paint(Graphics g) {
		// TODO Auto-generated method stub
		int posx = 0 ;
		if(isClicked)
			selectedImage = CheckImage ;
		else
			selectedImage = UnCheckImage ;
		g.drawBitmap(0, 0, selectedImage.getWidth(), selectedImage.getHeight(), selectedImage, 0, 0);
		posx = posx + selectedImage.getWidth() + 10 ;
		g.drawText(checkBoxLabel, posx, 0, DrawStyle.ELLIPSIS);
		
	}

	public void FieldClicked(Field fld) {
		// TODO Auto-generated method stub
		if (this._listener!=null)
      		 this._listener.FieldClicked(this); 
	}
}

 

 

Thanks

Rakesh 

Please use plain text.
Developer
peter_strange
Posts: 19,603
Registered: ‎07-14-2008
My Device: Not Specified

Re: How to handle touch Event in the field

I haven't time to test this right now but can you please change two things:

 

1) This is wrong I think:

   if(!isClicked){//If False Comes here
isClicked = true ;
}else{//If True Comes here
isClicked = false ;
this.FieldClicked(this);
return super.navigationClick(status,  time);
}

 

I would code the following - specifically do not call super in here.

   if(!isClicked){//If False Comes here
isClicked = true ;
}else{//If True Comes here
isClicked = false ;
 }

this.FieldClicked(this);

 

2.  You do not check the bounds of the touch event to make sure it applicable to your Field.  Look at the sample I referenced previously, you need to add code like that in your touchEvent processing. 

 

Can you fix up both of these and try - if it doesn't resolve, then please report. 

 

Please use plain text.
Developer
arkadyz
Posts: 2,268
Registered: ‎07-08-2009
My Device: various
My Carrier: various

Re: How to handle touch Event in the field

There are some fundamentals which one needs to understand to effectively handle touch events:

 

1) touch events are sent to the currently focused Field and all the enveloping Managers including the active Screen;

 

2) the system's default reaction to the DOWN event is to shift focus to the field at the touch position if there is a focusable one there. If there is no focusable field at the point of the touch, the currently focused Field is unchanged. There no "unfocus everything" method in BlackBerry (there might be, but it's not easily available - there is a protected focusRemove method, but it is supposed to be used in conjunction with a subsequent protected focusAdd in cases when the field changes its focus rectangle - a classic example is any text entry or display field such as EditField or RichTextField)

 

3) The default action of TouchEvent.CLICK is to invoke trackwheelClick (which, by default, invokes navigationClick) which is a great way to ensure consistency between screen "clicks" and touchpad clicks. The same is true for unclicks which eventually get handled by navigationUnclick.

 

If you want to disable the default click if the touch is outside of any focusable fields and do not want to disrupt the rest of the system actions, just return true if the event is CLICK but the touch coordinates are outside of the field, and super.touchEvent otherwise. And keep your return true; on all UNCLICK events - it is a good idea if you don't want to see the context menu popping up each time or the Field's click reaction invoked twice.

 

The example Peter cited was written when I already understood most of it, but now I realize that you can do it much easier. See the highlighted part of the previos paragraph.

 

Good luck!

----------------------------------------------------------
please click 'Accept Solution' on posts that provide the solution to the question you've posted. Don't say "Thanks", press 'Like' button instead!
Please use plain text.
Developer
rakesh86shankar
Posts: 1,003
Registered: ‎05-22-2009
My Device: Not Specified

Re: How to handle touch Event in the field

Hi,

 

Thanks Arkadyz and Peter Strange for your inputs,I am adding Updated CheckBox Field,As suggested by you,I made changes it works,Plz tell me if I made any mistakes,

 

I added the conditon to make it uneditable,That wa reason i opted for checkBox field.

package com.app.ui.controls;

import net.rim.device.api.system.Bitmap;
import net.rim.device.api.system.Display;
import net.rim.device.api.system.KeypadListener;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.TouchEvent;

import com.app.interfaces.ClickListener;

public class CheckBoxField extends Field  implements ClickListener
{
	
	private String checkBoxLabel ;
	private int width  = Display.getWidth()*3/4; 
	private int height = 10;
	private Bitmap CheckImage = Bitmap.getBitmapResource("checkbox.png");
	private Bitmap UnCheckImage = Bitmap.getBitmapResource("uncheckbox_grey.png");
	private boolean isClicked = false;
	private boolean setEditable = true;
	private ClickListener _listener;
	private Bitmap selectedImage = UnCheckImage;
	CheckBoxField thisfield;
	
	public CheckBoxField(String label){
		super(Field.FOCUSABLE);
		thisfield = this;
		checkBoxLabel = label;
		height = Math.max(CheckImage.getHeight(), UnCheckImage.getHeight());
		height = Math.max(height,this.getFont().getHeight());
	}
	
	public CheckBoxField( ){
		super(Field.FOCUSABLE);
		thisfield = this;
		checkBoxLabel = "Check box";
		height = Math.max(CheckImage.getHeight(), UnCheckImage.getHeight());
		height = Math.max(height,this.getFont().getHeight());
	}
	
	public void setWidth(int Width){
		width = Width ; 
		
	}
	
	public void setLabel(String label){
		checkBoxLabel = label ;
		width =  this.getFont().getAdvance(checkBoxLabel) + selectedImage.getWidth() + 10 ;
	}
	
	public void setClickListener(ClickListener listener) {
		_listener=listener;
	}
	
	public void setChecked(boolean isChecked){
		isClicked = isChecked ;
	}
	
	public void setFont(Font fnt){
		super.setFont(fnt);
	}
	public boolean getChecked(){
		return isClicked;
	}

	protected boolean navigationClick(int status, int time) {
		
		if ((status & KeypadListener.STATUS_TRACKWHEEL) != KeypadListener.STATUS_TRACKWHEEL) {
			System.out.println("navigationClick Is Clicked Status CLICK>>>"+isClicked);
			System.out.println("Is Clicked Status>>>"+isClicked);
			if(!setEditable){
				  return true;
			  }
			if(!isClicked){//If False Comes here
				isClicked = true ;			
			}else{//If True Comes here
				isClicked = false ;
								
			}
			return true;
		}
		return super.navigationClick(status, time);
	}	
	
	public void setEditable(boolean editable) {
		// TODO Auto-generated method stub
		this.setEditable  = editable;
		selectedImage = UnCheckImage ;
		this.invalidate();
	}
    protected boolean touchEvent(TouchEvent message)
    {
    	
    	int x = message.getX(1);
    	int y = message.getY(1);

    	if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
    	  // the user t ouched your field - do something
    	  if (message.getEvent() == TouchEvent.CLICK) { // don't forget to check the event type!
    		  if(!setEditable){
    			  return true;
    		  }
    		   if(!isClicked){//If False Comes here
 					isClicked = true ;			
 			   }else{//If True Comes here
 					isClicked = false ;
 			   }
         	 this.invalidate();
    		 FieldClicked(this);	
    	    return true;
    	  } // can add else if for other events if needed
    	}
    	return super.touchEvent(message); // This is extremely important!
   } 

	
	protected void layout(int arg0, int arg1) {
		// TODO Auto-generated method stub
		this.setExtent(width, height);
	}

	protected void drawFocus(Graphics graphics, boolean on) {
		// TODO Auto-generated method stub
		super.drawFocus(graphics, on);
	}
	protected void paint(Graphics g) {
		// TODO Auto-generated method stub
		int posx = 0 ;
		if(isClicked)
			selectedImage = CheckImage ;
		else
			selectedImage = UnCheckImage ;
		g.drawBitmap(0, 0, selectedImage.getWidth(), selectedImage.getHeight(), selectedImage, 0, 0);
		posx = posx + selectedImage.getWidth() + 10 ;
		g.drawText(checkBoxLabel, posx, 0, DrawStyle.ELLIPSIS);
		
	}

	public void FieldClicked(Field fld) {
		// TODO Auto-generated method stub
		if (this._listener!=null)
      		 this._listener.FieldClicked(this); 
	}
}

 

Main other issue which i was facing is,I was not getting TouchEvent Click,I found out the reason behind it ,HorizontalFieldManager in which i am adding  this checkbox field is getting Touch Event Click and it was setting true for that field,So as a result,I am unable to get the touch Event click for this field so i returned false,it worked,

 

 

 

 

Thanks

Rakesh

 

 

Please use plain text.