JavaFX:如何使节点部分鼠标透明? [英] JavaFX: How to make a Node partially mouse transparent?

查看:216
本文介绍了JavaFX:如何使节点部分鼠标透明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将另一个节点B的一个节点A设置为对MouseEvents半透明,因此事件将达到底层节点B。两个节点的大小相同,但节点A具有半透明背景图像,所以节点B的一半可见。

Make one Node "A" that is on top of another Node "B" to be half transparent to MouseEvents, so the Events will reach the underlying Node "B". Both Nodes are of equal size but Node "A" has a half transparent background image so one half of Node "B" is visible.

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

I have a menu of tabs. Each tab can be dragged to expand the corresponding menu layer. Therefore each tab layer is a Pane with a partially transparent background (basically a polygon) of which the transparent part should be also transparent to MouseEvents.

该图(我无法发布,请参阅链接:标签的插图,深绿色的线条是绿色窗格的边框)显示了基本原则:只想象只有标签是可见的,层本身可以向右拉以查看其内容。

The illustration (which I can't post yet, see link: Illustration of tabs, the dark green line is the border of the green Pane) shows the basic principle: just imagine only the tabs are visible and the layer itself can be pulled to the right to view it's content.

所以问题是,如何使一个Node的区域透明到MouseEvents而不使整个Node透明?

So the question is, how do I make a region of a Node transparent to MouseEvents without making the whole Node transparent?

感谢您的帮助!

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

To clarify the simple problem here is the corresponding code:

//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..

希望这有帮助。 p>

Hope this helps.

推荐答案

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

Consider the pickOnBounds property, it may help in your situation, but it is not clear to me without seeing your code attempt which fails for the simplified problem.

node.setPickOnBounds(true)


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

If pickOnBounds is true, then picking is computed by intersecting with the bounds of this node, else picking is computed by intersecting with the geometric shape of this node.

下面的代码演示了如何通过创建一个由 ImageView 覆盖的方块图像其中包含透明像素。如果ImageView将 pickOnBounds 设置为true,那么即使您单击图像中的透明像素,ImageView将会收到mouseClick事件。如果ImageView将 pickOnBounds 设置为false,那么即使您单击图像中的透明像素,ImageView也不会处理点击,点击事件将会由图像后面的节点接收。

The code below demonstrates how this may be used by creating a square overlaid by an ImageView for an Image which contains tranparent pixels. If pickOnBounds is set to true for the ImageView, then, even if you click on the transparent pixels in the image, the ImageView will receive the mouseClick event. If pickOnBounds is set to false for the ImageView, then, even if you click on the transparent pixels in the image, the ImageView will not process the click and the click event will be received by the node behind the image.

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

这篇关于JavaFX:如何使节点部分鼠标透明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆