透明JFXPanel不会将事件转发到其下的组件

时间:2017-03-25 00:27:01

标签: swing events javafx transparency jfxpanel

我正在尝试在基于swing的UI上创建透明的JFXPanel。问题是事件不会通过"透明"转发。它们是正常摆动组件的方式。我在下面提供了一个简单的例子注意,有3层,swing,swing,然后是jfxpanel。如果您注释掉

addItemToLayeredPanel(panel, createFXOverlay(), 7);

你可以点击这两个按钮,即使它们的底部上方有jpanel。 (只是证明效果在挥杆中起作用,但不适用于JFXPanel)

public class Main {
public static void main(String[] args) {
    JFrame frame = new JFrame();
    JLayeredPane panel = new JLayeredPane();
    JButton button = new JButton("Push me");
    JPanel overlay = createOverlay();

    addItemToLayeredPanel(panel, button, 5);
    addItemToLayeredPanel(panel, overlay, 6);
    addItemToLayeredPanel(panel, createFXOverlay(), 7);

    frame.getContentPane().add(panel);
    frame.setSize(500, 500);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

private static JPanel createOverlay() {
    JPanel panel = new JPanel();
    panel.add(new JButton("on top"));
    panel.setOpaque(false);
    return panel;
}

private static JFXPanel createFXOverlay() {
    JFXPanel panel = new JFXPanel();
    BorderPane root = new BorderPane();
    root.setStyle("-fx-background-color:transparent;");
    root.setCenter(new Button("root"));
    Scene scene = new Scene(root);

    scene.setFill(javafx.scene.paint.Color.TRANSPARENT);
    panel.setScene(scene);
    panel.setOpaque(false);
    return panel;
}

private static void addItemToLayeredPanel(JLayeredPane panel, JComponent item, int layer) {
    item.setBounds(0,0,500,500);
    panel.add(item);
    panel.setLayer(item, layer);
}

}

想法?我尝试了几种将事件(通常)转发到下面的jcomponents的方法,但我无法让它工作。我确实找到了几个类似的问题,但没有解决方案herehere

1 个答案:

答案 0 :(得分:0)

Swings尝试查看是否有鼠标事件通过时,它使用JComponent方法

public boolean contains(int x, int y) {
    return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
}

问题是JFXPanel与其他Swing组件不同,没有定义ui ComponentUI。因此,检查将退回到super.contains(x,y),如果在对象范围内发生鼠标事件,则返回true。

解决方案是使用扩展JFXPanel并覆盖contains方法的类:

public class MyJFXPanel extends JFXPanel{
    @Override
    public boolean contains(int x, int y) { return false; }
}

false可以用更复杂的语句代替,例如像素透明度条件。

然后,鼠标事件将自动转发到MyJFXPanel下的元素。