我正在尝试在基于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的方法,但我无法让它工作。我确实找到了几个类似的问题,但没有解决方案here和here
答案 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下的元素。