Reputation: 12018
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();
}
});
}
});
}
Upvotes: 13
Views: 2856
Reputation: 9118
You can use JNA to parse the messages from Windows.
Some documentation on the multi touch events from Microsoft: https://learn.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)
Upvotes: 1
Reputation: 539
For the pinch-to-zoom:
Try the GestureMagnificationListener by guigarage.com. It provides a method:
public void magnify(GestureMagnificationEvent me){...}
Upvotes: 0
Reputation: 76
hmm... this is a tough one, but there is a chance.
What I would do is make multiple MouseListener
classes (relative to the number of mouse events you want to pick up), and than create some sort of system to detect certain adjustments, eg. (zoom)
1st listener:
public void mousePressed(MouseEvent e){
//Set click to true
clk = true;
//set first mouse position
firstPos = window.getMousePosition();
}
public void mouseReleased(MouseEvent e){
//set second mouse position
secondPos = window.getMousePosition();
}
Second Listener
public void mousePressed(MouseEvent e){
//set clicked to true
clk = true;
//set first mouse position (listener 2)
firstPos = window.getMousePosition();
}
public void mouseReleased(MouseEvent e){
//set second mouse position
secondPos = window.getMousePosition();
}
Main handler
if(Listener1.get1stMousePos() < Listener1.get2ndMousePos() && Listener2.get1stMousePos() < Listener2.get2ndMousePos() && Listener1.clk && Listener2.clk){
zoomMethod((Listener1.get1stMousePos - Listener1.get2ndMousePos()) + (Listener1.get1stListener2.get2ndMousePos());
}
And than just do this to add it to the window:
window.addMouseListener(Listener1);
window.addMouseListener(Listener2);
Hope you find a way.
Upvotes: 0