将触控手势添加到传统的Swing应用程序

13

我有一个遗留的Swing应用程序,需要添加触摸手势,特别是捏合缩放和触摸拖拽。

我尝试了JDK 8的SwingNode,可以在那里运行Swing应用程序,但显示性能降低了50%以上,这不可行。 MT4J中的SwingTextureRenderer也存在同样的问题,而且甚至没有尝试将触摸事件转发为鼠标事件。

我考虑使用JavaFX层的玻璃板方法,在顶部捕获触摸事件,并尝试将其作为鼠标事件分派到下面的Swing应用程序。

是否有其他替代方法?目标平台是Windows 8。

Stackoverflow开启奖励后,我将提供悬赏。 我需要尽快解决这个问题。

编辑:

这是我使用SwingNode尝试过的内容(鼠标重派无效)。 如果您有更好的主意以将触摸引入Swing,则SwingNode可能会分散注意力:

@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();
                }
            });
        }
    });
}

2
请提供一个最小化示例,演示使用SwingNode时的性能降低,并提供相应的代码。 - jewelsea
1
我更新了问题,并尝试使用SwingNode。 - davidethell
1
@jewelsea建议提供一个MCTaRE(最小完整测试和可读性示例)。请点击链接并了解相关内容。这不是“无法编译的代码片段”,而且准备一个MCTaRE非常有用。 - Andrew Thompson
是的,我理解这个概念,通常情况下我不介意,但你认为SwingNode/redispatch的概念真的可行吗?除非你们中的一些人真的认为它是一个高性能的选项,否则我不想继续走这条路。 - davidethell
3个回答

1

0

嗯...这是一个棘手的问题,但有机会解决。

我会创建多个MouseListener类(与您想要捕获的鼠标事件数量相关),然后创建某种系统来检测特定的调整,例如(缩放)。

第一个监听器:

    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();
    }

第二个监听器

    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();
    }

主处理程序

    if(Listener1.get1stMousePos() < Listener1.get2ndMousePos() &&    Listener2.get1stMousePos() < Listener2.get2ndMousePos() && Listener1.clk && Listener2.clk){
    zoomMethod((Listener1.get1stMousePos - Listener1.get2ndMousePos()) +           (Listener1.get1stListener2.get2ndMousePos());

    }

然后只需执行以下操作将其添加到窗口中:

    window.addMouseListener(Listener1);
    window.addMouseListener(Listener2);

希望你能找到一种方法。


每个鼠标监听器都会获取到每个手指的事件吗? - Charlie

0

对于捏合缩放:

尝试使用Guigarage.com的GestureMagnificationListener。它提供了一个方法:

public void magnify(GestureMagnificationEvent me){...}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接