I am working on a Touch User interface in Swing. While I know this isn't optimal, I am on a short deadline and don't have time to Touch-screen specific GUI packages (if there are any).
I want my users to be able to 'swipe' their finger across the screen, and the view of a special JScrollPane I made moves with it. The code is very simple -
public class PanScrollPane extends JScrollPane implements MouseMotionListener{
public PanScrollPane() {
super();
this.addMouseMotionListener(this);
}
@Override
public void mouseDragged(MouseEvent arg0) {
System.out.println("Mouse Dragged!");
}
@Override
public void mouseMoved(MouseEvent arg0) {
System.out.println("Mouse Moved!");
}
The problem I'm having is that the JScrollPane is a container for all sorts of JComponents. When I first started working on this, I figured the MouseMovedEvent and MouseDraggedEvent would propagate up the 'GUI tree', untill they encountered a Component with a listener specifically for that event. Now it seems that any component I add to the panScrollPane blocks any of these MouseMotion events, leaving me unable to pan.
panScrollPane.add(new JButton("This thing blocks any mouse motion events"));
I figured propagating the MouseEvent by hand (adding listeners to every single component and then having them send the event to their parent) would work. This, however, is a very time-intensive undertaking and as I would rather spend my time working on other things, I was wondering if any of you know any work-around for this problem.
Thanks for reading, and hopefully thanks for answering! :)
edit: To make my intentions clearer. I only want the mousemotion events to be caught by the panPanel, any other event (like MouseClick, MouseRelease) should be processed normally
How about using a GlassPane? I think its meant to address exactly these types of situations.
Getting mouseEvents for a component and all its children is ... tricky to get right. You might consider to rely on stable (and extensively tested :-) code around. The jdk7 way of doing it is to use a JLayer (which internally registers an AWTEventListener as it has all priviledges). For earlier versions, you can use its predecessor JXLayer
This ad hoc approach leverages the existing
JScrollPane
actions that are usually used in key bindings. You'll have to tuneN
to your implementation ofScrollable
.