02-14-2013 06:17 AM
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
Solved! Go to Solution.
02-14-2013 07:40 AM
Besides I am not gettting the click event in touch Event,I am getting up and down event ,I am extending this from field
02-14-2013 10:08 AM
Are you checking that the touch is inside your Field?
02-15-2013 03:13 AM
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
02-15-2013 06:04 AM
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.
02-15-2013 11:31 AM
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!
03-12-2013 09:23 AM
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