3

I've been trying to implement a completely free bordered JButton :

  • Free shape as a border, as a solution is given in a previous thread : Rounded Swing JButton using Java
  • But the shape outside area can't be clicked
  • And the shape outside area is not drawn, even by the parent class (JButton)

Is there a simple way to do it in "plain" Swing (without any 3d party library) ? Otherwise, is there a good free (open-source is better of course) 3d party library in order to do this ?

As an example, think about a Red Circle ball : the best interaction I can give to users is that it can't click in the outside area, particularly if the Ball is really big.

Thank you in advance

(I've thought of a component written from scratch with Java2D, and using the Shape contains() method in order to see if the click is good. But I would have 2 main problems :

  • for giving the pressed apperance to the Shape, as well as the JButton does it => as someone noticed me below, that's not the most difficult, if I use two differents drawings/images

  • for handling events (ActionListeners) as well as the JButton does it => if i inherits from a JComponent, the most difficult will be to reject (return from) the handling if we have not clicked on the good area => what is the best way to detect this eventual intersection between mouse clicking point and the area ?)

Community
  • 1
  • 1
loloof64
  • 5,252
  • 12
  • 41
  • 78
  • 1
    should it be a button... can't you use a JLabel with a Mouse Listener. You add an image in the Jlabel in order to make it look like a round button and change the image on hover in order to simulate interaction. On mouse down and mouse up you set also a different image and on mouse pressed you implement your button click logic. If you use circle images it should look like a button... or did I misunderstood, what you are trying to achieve? – peshkira Oct 08 '11 at 11:30
  • In fact, JLabel custom component would still be rectangular => and that would be a big problem for event-handling ! Particularly if the component is big enough for the user to see the problem. But I am aware that this effect, can be very difficult, if not impossible, to implement. – loloof64 Oct 08 '11 at 11:39
  • 1
    See: http://stackoverflow.com/questions/3439112/java-custom-shape-panels for a simple example of creating a RoundButton. The code implements the "click detection" in 3 lines of code. – camickr Oct 09 '11 at 03:47
  • Thank you very much :) That's really better than the own method I related in an answer comment :) – loloof64 Oct 09 '11 at 10:04

1 Answers1

4

you have three choises

1) every Custom Look and Feels have implements Rounded JComponents, this is safiest way how to do that confortly and maybe correctly too, part of them brings excelent output to the Java Swing GUI and with long Bug history, I'd suggest to use Substance Look & Feel, but is very, so sensitive to EDT

2) you can override whole (Custom Look and Feels already did that) ButtonUI, but your UI_Delegate will be Look and Feel and Native_OS sensitive, meaning example that link I post, works on Windows platform with Metal Look and Feel, if you want to create an cross Platform and cross Look & Feel non-sensitive, then you must to overrive all possible Platforms and Look and Feels

3) create JComponent with Rounded Borders, fill area inside with for example GradientPaint, and then add MouseListener, MouseMotionListener, KeyListener or better write own KeyBindings and create own Model for avoiding the concurency betweens linstening Listeners, then will be your Custom JButton cross Platform and cross Look & Feel non-sensitive

everything .... up to you, much luck

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Thanks :) Finally I managed, using the third solution : inheriting from the JLabel subclass. But I also created a Ellipse2D.Float subclass to store the correct clicking area : that way I handle the events only if the MouseEvent#getPoint() is in the Shape area (contains() method of Shape). I think it is the most obvious way to do it. – loloof64 Oct 08 '11 at 12:11
  • 1
    +1 Good summary. This [article](http://today.java.net/pub/a/today/2007/02/22/how-to-write-custom-swing-component.html) shows how to add your own UI delegate. – trashgod Oct 08 '11 at 22:01
  • Thank you for this link : I'll have a look at it – loloof64 Oct 09 '11 at 10:10