B
Brian J. Sayatovic
I'd like to make two JButtons rollver in sync. That is, when I mouse over
one JButton and it rolls over, I'd like the second one to also rollover.
Likewise, whenI mouse over the second button, they both shoudl again
rollover.
My first thought was to listen to the button for events it broadcasts when
it rolls over and use that to set the other button's state. However, I
found no method for adding sucha listener to a JButton, and I also found no
way to force a JButton into the rolled-over state. Did I miss it?
My second plan is more basic, but I've implemented it and it partially
works. I add a special mouse listener to each JButton that sends a nearly
identical MouseEvent (I change the source) to the other JButton. I also
realized the hard way that I need to detect a "forwarded" MouseEvent and not
forward it again lest I end up in an infinitely recursive call. Here's the
important part of the code:
class DelegatedMouseEvent extends MouseEvent {
public DelegatedMouseEvent(Component delegate, MouseEvent
delegatedEvent) {
super(
delegate,
delegatedEvent.getID(),
delegatedEvent.getWhen(),
delegatedEvent.getModifiers(),
delegatedEvent.getX(),
delegatedEvent.getY(),
delegatedEvent.getClickCount(),
delegatedEvent.isPopupTrigger(),
delegatedEvent.getButton()
);
}
}
class DelegatingMouseListener extends MouseAdapter {
private final Component
delegate;
public DelegatingMouseListener(Component delegate) {
this.delegate = delegate;
}
public void mouseEntered(MouseEvent event) {
System.out.println("Mouse entered " + event.getSource());
if(!(event instanceof DelegatedMouseEvent)) {
this.enqueueEventForDelegate(event);
}
}
public void mouseExited(MouseEvent event) {
System.out.println("Mouse exited " + event.getSource());
if(!(event instanceof DelegatedMouseEvent)) {
this.enqueueEventForDelegate(event);
}
}
private void enqueueEventForDelegate(MouseEvent event) {
EventQueue queue = delegate.getToolkit().getSystemEventQueue();
queue.postEvent(new DelegatedMouseEvent(this.delegate, event));
}
}
This works except when I have the buttons right next to each other. As the
mouse exits one, it enters the other. Because of the ordering of the
events, it ends up like this:
1. LeftButton: mouse exited (post a copy of the event to RightButton... #3)
2. RightButton: mouse entered (post a copy of the event to LeftButton... #4)
3. RightButton: mouse exited
4. LeftButton: mouse entered
Does anyone have a better solution to this, or if not, a graceful way to
handle the problem case in my above implementation?
Regards,
Brian.
one JButton and it rolls over, I'd like the second one to also rollover.
Likewise, whenI mouse over the second button, they both shoudl again
rollover.
My first thought was to listen to the button for events it broadcasts when
it rolls over and use that to set the other button's state. However, I
found no method for adding sucha listener to a JButton, and I also found no
way to force a JButton into the rolled-over state. Did I miss it?
My second plan is more basic, but I've implemented it and it partially
works. I add a special mouse listener to each JButton that sends a nearly
identical MouseEvent (I change the source) to the other JButton. I also
realized the hard way that I need to detect a "forwarded" MouseEvent and not
forward it again lest I end up in an infinitely recursive call. Here's the
important part of the code:
class DelegatedMouseEvent extends MouseEvent {
public DelegatedMouseEvent(Component delegate, MouseEvent
delegatedEvent) {
super(
delegate,
delegatedEvent.getID(),
delegatedEvent.getWhen(),
delegatedEvent.getModifiers(),
delegatedEvent.getX(),
delegatedEvent.getY(),
delegatedEvent.getClickCount(),
delegatedEvent.isPopupTrigger(),
delegatedEvent.getButton()
);
}
}
class DelegatingMouseListener extends MouseAdapter {
private final Component
delegate;
public DelegatingMouseListener(Component delegate) {
this.delegate = delegate;
}
public void mouseEntered(MouseEvent event) {
System.out.println("Mouse entered " + event.getSource());
if(!(event instanceof DelegatedMouseEvent)) {
this.enqueueEventForDelegate(event);
}
}
public void mouseExited(MouseEvent event) {
System.out.println("Mouse exited " + event.getSource());
if(!(event instanceof DelegatedMouseEvent)) {
this.enqueueEventForDelegate(event);
}
}
private void enqueueEventForDelegate(MouseEvent event) {
EventQueue queue = delegate.getToolkit().getSystemEventQueue();
queue.postEvent(new DelegatedMouseEvent(this.delegate, event));
}
}
This works except when I have the buttons right next to each other. As the
mouse exits one, it enters the other. Because of the ordering of the
events, it ends up like this:
1. LeftButton: mouse exited (post a copy of the event to RightButton... #3)
2. RightButton: mouse entered (post a copy of the event to LeftButton... #4)
3. RightButton: mouse exited
4. LeftButton: mouse entered
Does anyone have a better solution to this, or if not, a graceful way to
handle the problem case in my above implementation?
Regards,
Brian.