Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add touch gestures to legacy swing application

I have a legacy swing application that I need to add touch gestures to,specifically pinch to zoom and touch and drag.

I tried the SwingNode of JDK 8 and I can run the swing application there, but the display performance was cut by more than 50% which won't work. SwingTextureRenderer in MT4J has the same issue and that is without even trying to redispatch touch events as mouse events.

I thought about a glass pane approach using a JavaFX layer on top and capturing the touch events and attempting to dispatch them as mouse events to the Swing app underneath.

Does anyone have an alternative approach? The target platform is windows 8.

Bounty coming as soon as Stackoverflow opens it up. I need this one pretty rapidly.

EDIT:

Here is what I tried with SwingNode (the mouse redispatch didn't work). The SwingNode stuff might be a distraction from the best solution so ignore this if you have a better idea for getting touch into swing:

@Override
public void start(Stage stage) {
    final SwingNode swingNode = new SwingNode();
    createAndSetSwingContent(swingNode);

    StackPane pane = new StackPane();
    pane.getChildren().add(swingNode);

    stage.setScene(new Scene(pane, 640, 480));
    stage.show();
}

private void createAndSetSwingContent(final SwingNode swingNode) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            UILib.setPlatformLookAndFeel();

            // create GraphViewTouch
            String datafile = null;
            String label = "label";

            final JPanel frame = GraphView.demoFrameless(datafile, label);
            swingNode.setContent(frame);
            swingNode.setOnZoom(new EventHandler<ZoomEvent>() {
                @Override public void handle(ZoomEvent event) {
                    MouseWheelEvent me = new MouseWheelEvent(frame, 1, System.currentTimeMillis(), 0, (int)Math.round(event.getSceneX()), (int)Math.round(event.getSceneY()), (int)Math.round(event.getScreenX()), (int)Math.round(event.getScreenY()), (int)Math.round(event.getZoomFactor()), false, MouseWheelEvent.WHEEL_UNIT_SCROLL, (int)Math.round(event.getZoomFactor()), (int)Math.round(event.getZoomFactor()), event.getZoomFactor());
                    frame.dispatchEvent(me);
                    System.out.println("GraphView: Zoom event" +
                        ", inertia: " + event.isInertia() + 
                        ", direct: " + event.isDirect());

                    event.consume();
                }
            });
        }
    });
}
like image 688
davidethell Avatar asked Feb 06 '14 05:02

davidethell


1 Answers

You can use JNA to parse the messages from Windows.

Some documentation on the multi touch events from Microsoft: https://docs.microsoft.com/en-us/windows/desktop/wintouch/wm-touchdown

Some documentation on how to do it in Java and sample code: https://github.com/fmsbeekmans/jest/wiki/Native-Multitouch-for-AWT-component-(Windows)

like image 100
Charlie Avatar answered Sep 21 '22 13:09

Charlie