我正在尝试在基于swing的UI上创建一个透明的JFXPanel。问题是事件不会像普通swing组件那样通过“透明”部分转发。我在下面包含了一个简单的例子。注意有3层,swing,swing,然后是jfxpanel。如果您注释掉
addItemToLayeredPanel(panel, createFXOverlay(), 7);您可以同时单击这两个按钮,即使它们的jpanel层位于底部按钮之上。(仅在swing中演示效果并不适用于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,但我无法让它工作。我确实发现了几个类似的问题,但没有解决方案here和here
发布于 2020-04-03 17:24:27
当Swings尝试查看鼠标事件是否通过时,它使用JComponent方法
public boolean contains(int x, int y) {
return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
}问题是,与其他Swing组件不同,JFXPanel没有定义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下的元素。
https://stackoverflow.com/questions/43011157
复制相似问题