If you are using Internet Explorer, please remove blackberry.com from your compatibility view settings.

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
Contributor
sergiotapia
Posts: 33
Registered: ‎10-01-2010
My Device: Not Specified

How can I create a Click event when a user taps anywhere inside?

I have the following code which is just a VerticalFieldManager that contains many HorizontalFieldManagers. Each of these HorizontalFieldManagers will act as a button.

 

 

final VerticalScrollManager vfm = new VerticalScrollManager() {
	protected void sublayout(int width, int height) {
		super.sublayout(width, 322);
	}
};

for (int i = 0; i < 150; i++) {
	HorizontalRoundBorderManager buttonArea = new HorizontalRoundBorderManager(
			USE_ALL_WIDTH);
	buttonArea.add(new LabelField("asdf"));
	buttonArea.setMargin(new XYEdges(10, 0, 0, 0));
	vfm.add(buttonArea);
}

Manager wrapper = new Manager(0) {
	protected void sublayout(int width, int height) {
		layoutChild(vfm, 360, 322);
		setPositionChild(vfm, 3, 5);
		setExtent(360, 322);
	}
};
wrapper.add(vfm);
add(wrapper);

 

 

 

How can I do something if a user taps his finger ANYWHERE on the HorizontalFieldManager?

 

Thanks!

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

Re: How can I create a Click event when a user taps anywhere inside?

Add this inside your HorizontalFieldManager:

 

protected boolean touchEvent(TouchEvent message) {
	if (message.getEvent() == TouchEvent.DOWN) {
		int x = message.getX(1);
		int y = message.getY(1);
		XYRect myArea = new XYRect();
		getExtent(myArea);
		myArea.setLocation(0, 0);
		if (myArea.contains(x, y)) {
			// set focus, paint it differently, etc.
		}
	}
	return super.touchEvent(message); // important to always do this!
}

 

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.
Contributor
sergiotapia
Posts: 33
Registered: ‎10-01-2010
My Device: Not Specified

Re: How can I create a Click event when a user taps anywhere inside?

Thanks for the help! I'm getting an error on the message.getX() getY() methods.

 

"The method getX(int) is undefined for the type EventInjector.TouchEvent"

 

 

for (int i = 0; i < 150; i++) {
	HorizontalRoundBorderManager buttonArea = new HorizontalRoundBorderManager(
			USE_ALL_WIDTH) {
		protected boolean touchEvent(TouchEvent message) {
			if (message.getEvent() == TouchEvent.DOWN) {
				int x = message.getX(1);
				int y = message.getY(1);
				XYRect myArea = new XYRect();
				getExtent(myArea);
				myArea.setLocation(0, 0);
				if (myArea.contains(x, y)) {
					Dialog.alert("Click successful!");
				}
			}
			return super.touchEvent(message);
		}
	};
	buttonArea.add(new LabelField("asdf"));
	buttonArea.setMargin(new XYEdges(10, 0, 0, 0));
	vfm.add(buttonArea);
}

 

 

I'm also getting an error on return super.touchEvent(message);

 

"The method touchEvent(TouchEvent) in the type Manager is not applicable for the arguments (EventInjector.TouchEvent)"

 

Thanks again for the help!

Please use plain text.
Contributor
sergiotapia
Posts: 33
Registered: ‎10-01-2010
My Device: Not Specified

Re: How can I create a Click event when a user taps anywhere inside?

Still having the errors. Any help?

Please use plain text.
Contributor
sergiotapia
Posts: 33
Registered: ‎10-01-2010
My Device: Not Specified

Re: How can I create a Click event when a user taps anywhere inside?

I thought this was a pretty standard problem. Any suggestions on how I can achieve this? I just want to handle a click when someone taps on my Manager.

Please use plain text.
Developer
vivart
Posts: 147
Registered: ‎08-27-2010
My Device: 9800
My Carrier: airtel

Re: How can I create a Click event when a user taps anywhere inside?

see your imports 

you have imported 

 

import net.rim.device.api.system.EventInjector.TouchEvent;

 

 

instead of

 

import net.rim.device.api.ui.TouchEvent;

 

 

Please use plain text.
Contributor
sergiotapia
Posts: 33
Registered: ‎10-01-2010
My Device: Not Specified

Re: How can I create a Click event when a user taps anywhere inside?

Thanks for the help. I'm having some issues though, when I use a plain old return true, instead of the super.touchevent() method, the dialog.alert works and shows that its in fact clicking. But now I cannot click any other control on the screen. I have two other completely seperate DateFields and they are no longer clickable.

 

Then, if I do use the super.touchevent() method, the dialog.alert() shows, but I immediately get a runtime error:

 

JVM Error 104: Uncaught RuntimeException.

 

 

Any suggestions? Here's my code:

 

 

for (int i = 0; i < 1; i++) {
			HorizontalRoundBorderManager buttonArea = new HorizontalRoundBorderManager(
					USE_ALL_WIDTH) {
				protected boolean touchEvent(TouchEvent message) {
					if (message.getEvent() == TouchEvent.DOWN) {
						int x = message.getX(1);
						int y = message.getY(1);
						XYRect myArea = new XYRect();
						getExtent(myArea);
						myArea.setLocation(0, 0);
						if (myArea.contains(x, y)) {
							Dialog.alert("Message!");
						}
					}

					return true;
					// return super.touchEvent(message); // important to always
					// do
				}
			};
			buttonArea.add(new LabelField("asdf"));
			buttonArea.setMargin(new XYEdges(10, 0, 0, 0));
			vfm.add(buttonArea);
		}

 

 

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

Re: How can I create a Click event when a user taps anywhere inside?

Dialog.alert(...) is a blocking call, so you prevent a UI event processing from completing.

 

Wrap your debugging in invokeLater() - like this:

 

	if (myArea.contains(x, y)) {
		UiApplication.getUiApplication().invokeLater(new Runnable() {
			public void run() {
				Dialog.alert("Message!");
			}
		});
	}

 This invokeLater will ensure that you first finish processing your touch event and only then display the Dialog.

 

----------------------------------------------------------
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.
Contributor
sergiotapia
Posts: 33
Registered: ‎10-01-2010
My Device: Not Specified

Re: How can I create a Click event when a user taps anywhere inside?

[ Edited ]

Edit: Nevermind, it's work now! :smileyvery-happy:

 

There is a slight problem though. These managers are set inside of a VerticalFieldManager, to act as a scrollbar container. This manager lists all the buttons I'm creating.

 

The problem is, left clicking the buttons works, but right clicking inside the general area to scroll up and down invokes the Click event as well. How can I differentiate from the two?

 

When a user click I want the Click event to fire, but when he drags, I want the area to scroll.

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

Re: How can I create a Click event when a user taps anywhere inside?

Let's make it clear - do you want something to happen on touch or on click? If you want that on touch but actually click the screen, you need to realize that in that case DOWN event is generated twice by the BB framework on Storm (don't ask me why, that's just something I found out the hard way). Two such events both pushing a modal screen in very short succession might be a little too much for your phone.

 

If what you want is actually some action on click, override navigationClick() to invoke that action somehow and use the DOWN processing in touchEvent() to setFocus() on the field of your choice inside your Manager, for example.

 

I've done something similar to it at some point, when someone on the forums asked whether there are any multi-line buttons in BlackBerry. One of the things I had to implement was grabbing the focus on touch. The subsequent click event would be sent to this Manager because the focus would be there already, thanks to the DOWN events included in CLICK.

 

Here is my full code of MultiLineButtonField for reference. Add a field change listener there (to detect the clicks) or override a navigationClick event to include your click processing.

 

import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.FocusChangeListener;
import net.rim.device.api.ui.Graphics;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.TouchEvent;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.NullField;
import net.rim.device.api.ui.component.RichTextField;

public class MultiLineButtonField extends Manager  implements FocusChangeListener {
	private final static int MAX_LABEL_PADDING = 8; // pixels
	private final static int MIN_LABEL_PADDING = 2; // pixels again
	private final static int NON_FOCUS_COLOR = Color.DARKBLUE;
	private final static int FOCUS_COLOR = Color.BLUE;
	private final static int DISABLED_COLOR = Color.GRAY;
	private final static int FONT_COLOR = Color.WHITE;
	private RichTextField _label;
	private NullField _focusAnchor;
	private int _width;
	private int _padding;

	public MultiLineButtonField(String labelText, int width, long style) {
		super(style & (FIELD_HALIGN_MASK | FIELD_VALIGN_MASK | USE_ALL_WIDTH | USE_ALL_HEIGHT));
		_label = new RichTextField(style & SPELLCHECKABLE_MASK | READONLY | NON_FOCUSABLE | RichTextField.TEXT_ALIGN_HCENTER);
		_label.setText(labelText);
		add(_label);
		_focusAnchor = new NullField(style & FOCUSABLE_MASK);
		_focusAnchor.setFocusListener(this);
		add(_focusAnchor);
		_width = width;
		if (_width < 2 * MIN_LABEL_PADDING) {
			throw new IllegalArgumentException("Not enough width to lay out MultiLineButtonField");
		}
	}

	protected int nextFocus(int direction, int axis) {
		invalidate();
		return -1;
	}

	protected void sublayout(int width, int height) {
		XYRect childRect;
		if ((width < 2 * MIN_LABEL_PADDING) || (height < 2 * MIN_LABEL_PADDING)) {
			throw new IllegalArgumentException("Not enough room to lay out MultiLineButtonField");
		}
		layoutChild(_label, Math.min(_width, width) - 2 * MIN_LABEL_PADDING, height - 2 * MIN_LABEL_PADDING);
		childRect = _label.getExtent();
		int myWidth = width;
		int myHeight = height;
		if (!isStyle(USE_ALL_WIDTH)) {
			myWidth = Math.min(width, childRect.width + 2 * MAX_LABEL_PADDING);
		}
		if (!isStyle(USE_ALL_HEIGHT)) {
			myHeight = Math.min(height, childRect.height + 2 * MAX_LABEL_PADDING);
		}
		_padding = Math.min((myWidth - childRect.width), (myHeight - childRect.height)) / 2;
		setPositionChild(_label, _padding, _padding);
		layoutChild(_focusAnchor, 0, 0);
		setPositionChild(_focusAnchor, 0, 0);
		setExtent(myWidth, myHeight);
	}

	protected void paintBackground(Graphics g) {
		int prevColor = g.getColor();
		int bgColor;
		if (_focusAnchor.isFocusable()) {
			if (_focusAnchor.isFocus()) {
				bgColor = FOCUS_COLOR;
			} else {
				bgColor = NON_FOCUS_COLOR;
			}
		} else {
			bgColor = DISABLED_COLOR;
		}
		g.setColor(bgColor);
		g.fillRoundRect(0, 0, getWidth(), getHeight(), 2* _padding, 2 * _padding);
		g.setColor(prevColor);
	}
	
	protected boolean touchEvent(TouchEvent message) {
		if (message.getEvent() == TouchEvent.DOWN) {
			int x = message.getX(1);
			int y = message.getY(1);
			XYRect myArea = new XYRect();
			getExtent(myArea); // UiUtils.getFieldExtent(this);
			myArea.setLocation(0, 0);
			if (myArea.contains(x, y)) {
				_focusAnchor.setFocus();
			}
		}
		return super.touchEvent(message);
	}

	protected void paint(Graphics g) {
		int prevColor = g.getColor();
		g.setColor(FONT_COLOR);
		super.paint(g);
		g.setColor(prevColor);
	}

	public void focusChanged(Field field, int eventType) {
		if (field == _focusAnchor) {
			invalidate();
		}
		
	}
}

 

 

----------------------------------------------------------
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.