7

简化问题:

使位于另一个节点“B”之上的一个节点“A”对 MouseEvents 是半透明的,因此事件将到达底层节点“B”。两个节点大小相同,但节点“A”有一个半透明的背景图像,因此节点“B”的一半是可见的。

真正的问题:

我有一个标签菜单。每个选项卡都可以拖动展开相应的菜单层。因此,每个选项卡层都是一个具有部分透明背景(基本上是多边形)的窗格,其中透明部分对 MouseEvents 也应该是透明的。

插图(我还不能发布,请参见链接:选项卡插图,深绿色线是绿色窗格的边框)显示了基本原理:想象一下只有选项卡是可见的,并且可以将图层本身拉到查看其内容的权利。

所以问题是,如何在不使整个节点透明的情况下使节点的一个区域对 MouseEvents 透明?

感谢您的帮助!

更新:

为了澄清这个简单的问题,这里是相应的代码:

//Create parent group
Group root = new Group();

//Create linear gradient, so one side is transparent
Stop[] stops = new Stop[] { new Stop(0, Color.rgb(0, 255, 0, 0.0)), new Stop(1, Color.rgb(0, 255, 0, 1.0))};
LinearGradient lg1 = new LinearGradient(0, 0, 1, 0, true, CycleMethod.NO_CYCLE, stops);

//Create the rectangles
Rectangle A = new Rectangle(100, 50, lg1);
Rectangle B = new Rectangle(100,50, Color.RED);

//Add eventHandlers
A.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent e) {
        System.out.println("Clicked A");
    }
});
B.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent e) {
        System.out.println("Clicked B");
    }
});
root.getChildren().addAll(B, A);

//Add to Scene..

希望这可以帮助。

4

1 回答 1

11

考虑该pickOnBounds属性,它可能对您的情况有所帮助,但如果没有看到您的代码尝试因简化问题而失败,我不清楚。

node.setPickOnBounds(true)

如果 pickOnBounds 为真,则通过与该节点的边界相交来计算拾取,否则通过与该节点的几何形状相交来计算拾取。

下面的代码演示了如何通过创建一个由包含透明像素的ImageViewfor覆盖的正方形来使用它。Image如果pickOnBoundsImageView设置为true,那么即使点击图片中的透明像素,ImageView也会收到mouseClick事件。如果pickOnBoundsImageView设置为false,那么即使点击图片中的透明像素,ImageView也不会处理点击,点击事件会被图片后面的节点接收。

鼠标挑

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class PickOnBoundsDemo extends Application {
  public static void main(String[] args) { Application.launch(args); }
  @Override public void start(Stage stage) {
    final Rectangle back  = new Rectangle(128, 128);
    back.setFill(Color.FORESTGREEN);
    final ImageView front = new ImageView("http://icons.iconarchive.com/icons/aha-soft/free-large-boss/128/Wizard-icon.png");
    // icon: Linkware (Backlink to http://www.aha-soft.com required)

    final StackPane pickArea = new StackPane();
    pickArea.getChildren().addAll(
      back, 
      front
    );

    final ToggleButton pickTypeSelection = new ToggleButton("Pick On Bounds");
    final Label pickResult = new Label();

    Bindings.bindBidirectional(front.pickOnBoundsProperty(), pickTypeSelection.selectedProperty());

    front.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent t) {
        pickResult.setText("Front clicked");
      }
    });

    back.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override public void handle(MouseEvent t) {
        pickResult.setText("Back clicked");
      }
    });

    VBox layout = new VBox(10);
    layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;");
    layout.getChildren().setAll(
      pickArea,
      new Label("Click inside the above area to test mouse picking."),
      pickTypeSelection,
      pickResult
    );
    layout.setAlignment(Pos.CENTER);

    stage.setScene(new Scene(layout));
    stage.show();
  }
}
于 2013-03-20T21:07:46.997 回答