Loading...
Important Notice - Forums is archived

To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Product icon
TUTORIAL

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.

Defining a clickable area for a UI component

Aladdin Özenir
1 decade ago Apr 21, 2010 1:19pm

I am using the Button component with an Icon (ThemeResource with trasparent image parts).
In my application, I have many such buttons.
The Icon is not (as the button) a square. Lets say, it is a circle.
I layout these buttons using a custom layout and absolute positioning with CSS, which works very good.

I have one problem though.
When I click one button (on the icon directly), I want exactly that button to handle the event.
Because the button is a square element, but it "looks" like it is a circle, the user does not always click the correct button.

Do you see my problem?
(See also the attached file)

The boundaries of one button overlapps with the other other buttons. So, when I click a button (or I think I click that button), it can be the other button as well. Sounds weird, I know. But, because of the overlapping components and the fact that they are squares, this behavior is normal.

Still, is there any way to define clickable areas for a button. Or is there another component, which can do that?
Important is, I must be able to configure a ThemeResource and I must also be able to handle the click event.

I've also tried with the Embeddable component. It is also square. (of course) ;)
I don't want to use an ImageMaps. I think there is no such component with such functionality, is there?
Using the Z-Index, it gets better, but the problem is not solved.

Last updated on Apr, 21st 2010
Johan Anas
1 decade ago Apr 22, 2010 6:25am

Hi!

I don't want to use an ImageMaps. I think there is no such component with such functionality, is there?

Could maybe this component still suit your needs? At least you can define clickable areas that generate events when clicked.

// Johan

Aladdin Özenir
1 decade ago Apr 22, 2010 6:32am

Johan Anas: Could maybe this component still suit your needs? At least you can define clickable areas that generate events when clicked.

This widget is great. For my purpose not suitable though.

I can not use one big image, that has these clickable areas.
I must put the small parts dynamically together, like a puzzle.
These small parts (the content of my buttons) are coming from a database and they need to change, depending on their state independently.

Charles Anthony
1 decade ago Apr 22, 2010 7:19am

Hi,

Realistically, you are going to have to dynamically generate an image and image map : HTML & CSS can only cope with rectangular elements. There is an example of how to make a an irregularly shaped HTML Anchor here - I don't know about you, but that makes me shudder with utter horror. Ultimately, it's just building up the irregular shape through the use of rectangular elements, and detecting the click on them.

Even using image map could not be exact - as you would need to use a polygon as a target area, and hence it would not be precisely circular/ovoid (although, with lots of points, you could make it pretty close).

If the button image is always the same (an ellipse or a circle) then you could develop a widget that captures the mouseclick on the whole widget, does a "collision detection" routine to find out whether the click is within the circle/ellipse/polygon (see comp.graphics FAQ for point-polygon detection (Section 2.03) and here for an example of point-circle collision.

Without knowing a lot more about what you are trying to do, it's tricky to offer more advice - but it sounds more like you are trying to detect clicks on shapes. If you can *draw* the buttons, as opposed to using images/sprites, perhaps the gwt-graphics GWT Widget could be useful. It has the ability to draw vector graphics, and detect clicks on them very easily. Note - you can draw an image/bitmap, but the click_handler will obviously only detect clicks within the bounding rectangle; as far as I can find out, there is no way to get the colour of the pixel under the mouse pointer in javascript => there is no way to do exact point/sprite collision detection.

So, in conclusion, if the images you need to detect can be drawn using vector graphics, I would suggest using gwt-graphics (or a similar javascript library such as raphael). If the images must be sprites/bitmaps, the only way forward is to define an imagemap for each indidual image/sprite, and develop a widget (or use Henri's) to combine the image/imagemap. If the image/sprites are infintely variable (e.g. the users supply the images, they are not predetermined), then you can only do rectangular bounds detection.

Sorry I can't give you an exact steer, but hope that helps - and thanks for giving me a trip down memory lane, by making me thing about "proper" computer science stuff, instead of business computing!

Cheers,

Charles.

Johan Anas
1 decade ago Apr 22, 2010 7:21am

Layouts also generate clickEvents.

ClickEvent.getClientX() and getClientY() would return the mouse cursor position relative to the client browser area...

What if you made an AbsoluteLayout, added embedded objects (your images) to it like you do and create your own collisionDetect()-method? If the coordinates (and shapes) comes from the database, you can check if the click hit within your defined bounds.

Disclaimer: I haven't tested myself, but if you try, tell me if it worked out :)

// Johan

Last updated on Apr, 22nd 2010
Aladdin Özenir
1 decade ago Apr 22, 2010 7:35am

Yeah, thanks to you all.
Now I need to isolate myself from the real world and get into some thinking and find out, how to implement my requirement. ;)

I will keep you updated, if I find out something.

Jouni Koivuviita
1 decade ago Apr 22, 2010 7:49am

I'm a bit afraid that basic HTML doesn't provide any means to accomplish non-rectangular elements. But I'd try and use border-radius and see if it has any effect on the actual elements active area. And yes, you can specify elliptical shapes using border-radius.

Border-radius is of course not supported by all browsers, and implementation differences are probably more of a rule than an exception, so this might not be a viable solution even if the clickable area would be affected by it.

A more robust solution would IMO be to use the GWT Graphics add-on and render the buttons using that. It uses SVG to do the rendering, and although I don't know exactly about the event system involved, I'd guess it would only capture events on the actual visible area of a shape.

That would then of course mean that you'd have to somehow convert your theme resources to vectors that could be rendered using the GWT Graphics add-on. I don't know if it can render plain bitmaps, but that could work, too.

Henri Kerola
1 decade ago Apr 22, 2010 9:50am

Jouni Koivuviita: A more robust solution would IMO be to use the GWT Graphics add-on and render the buttons using that. It uses SVG to do the rendering, and although I don't know exactly about the event system involved, I'd guess it would only capture events on the actual visible area of a shape.

Yes, if you create your non-rectangular buttons with a component, which uses GWT Graphics, you can easily get a click event from the non-rectangular shape. However, if you wanna use GWT Graphics you have to create your own component and do client-side coding.

A simple example about getting a click event from an ellipse with GWT Graphics:

Ellipse ellipse = new Ellipse(100, 100, 100, 50);
ellipse.setFillColor("blue");
ellipse.setStrokeColor("blue");
ellipse.addClickHandler(new ClickHandler() {

	@Override
	public void onClick(ClickEvent event) {
		Window.alert("Hello world!");
	}
});

-Henri