I developed a Swing application in which I now need to implement a customized multi-touch gesture.
After some research, the easiest approach seemes to be the use of JavaFX, because it can be embedded in Swing and provides events for every finger on the touch screen seperately. I then tried to implement touch handling according to the following examples:
http://docs.oracle.com/javafx/2/swing/swing-fx-interoperability.htm
http://docs.oracle.com/javafx/2/events/touch_events.htm
I decided to create a transparent JFXPanel above a JPanel catching all mouse and touch events. It works perfectly for JavaFX mouse events, but I don't recieve any touch events.
I tested my application on different touchable Windows 7 and Window 8 devices. I'm currently using Java JDK 1.8.0_45.
So my question is Why do I not recieve any touch events?
I reduced my problem to following two classes:
The GUI class:
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestWindow extends JFrame {
private static final long serialVersionUID = 1L;
private static final JFXPanel jfxPanel = new JFXPanel();
private static Scene jfxScene;
private static TestController controller;
private boolean enableJFXPanel;
/**
* Create the Frame
* @param tc The Application's controller
*/
public TestWindow(TestController tc) {
this.setBounds(200,200,400,400);
this.setResizable(false);
this.setTitle("JavaFX in Swing Test");
getContentPane().setLayout(null);
controller = tc;
// Create the swing panel
JPanel jPanel = new JPanel();
jPanel.setBounds(0, 0, this.getWidth(), this.getHeight());
jPanel.addMouseListener(controller);
// Create the button
JButton button = new JButton("show / hide JavaFX panel");
button.setBounds((jPanel.getWidth()/2)-100, (jPanel.getHeight()/2)-25, 200, 50);
button.addActionListener(controller);
jPanel.add(button);
// Create the JavaFX panel
jfxPanel.setBounds(0, 0, 0, 0);
enableJFXPanel = false;
jPanel.add(jfxPanel);
getContentPane().add(jPanel);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initAndShowGUI();
}
});
this.setVisible(true);
}
/**
* Initialize and Show JavaFX
*/
private static void initAndShowGUI() {
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX();
}
});
}
/**
* Initialize the JavaFX {@code Scene} and set touch controller.
*/
private static void initFX() {
Group jfx_root = new Group();
jfxScene = new Scene(jfx_root);
jfxScene.setFill(Color.AQUA);
// Register touch event listener (DOESN'T WORK !!!)
jfxScene.setOnTouchMoved(controller);
jfxScene.setOnTouchPressed(controller);
jfxScene.setOnTouchReleased(controller);
jfxScene.setOnTouchStationary(controller);
// Test catching JavaFX mouse events (WORKS PERFECTLY !!!)
jfxScene.setOnMouseClicked(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent event) {
System.out.println("MOUSE CLICKED ON JAVA FX PANEL");
}
});
jfxPanel.setScene(jfxScene);
}
/**
* Show / hide the JavaFX panel
*/
public void switchJFXPanel() {
if (enableJFXPanel) {
jfxPanel.setBounds(0, 0, 0, 0);
enableJFXPanel = false;
} else {
jfxPanel.setBounds(0, 0, this.getWidth(), this.getHeight());
enableJFXPanel = true;
}
}
}
The controller class:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javafx.scene.input.TouchEvent;
public class TestController implements MouseListener, ActionListener, javafx.event.EventHandler<TouchEvent> {
private TestWindow testWindow;
public TestController() {
testWindow = new TestWindow(this);
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("MOUSE CLICKED ON JPANEL");
}
@Override
public void mousePressed(MouseEvent e) {}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void actionPerformed(ActionEvent e) {
testWindow.switchJFXPanel();
}
@Override
public void handle(TouchEvent event) {
// OCCURING JAVA FX TOUCH EVENT SHALL BE WRITTEN TO CONSOLE
System.out.println("JAVA FX TOUCH EVENT: " + event.toString());
}
public static void main(String arg[]) {
TestController test = new TestController();
}
}
Thanks for any help.