【问题标题】:How to make overlay Vbox nodes clickable?如何使覆盖 Vbox 节点可点击?
【发布时间】:2018-09-04 15:57:58
【问题描述】:

我正在尝试构建一个 javafx 修剪器,我已经完成了,但是当我在 ImageViews 上添加 setOnMouseClicked 时,我制作的修剪器隐藏了这些节点,因此不处理该操作。

我已经设置了 Rectangle -50 以便将修剪器覆盖到 ImageView,不幸的是,这使得事件不起作用。

Rectangle rectangle = new Rectangle(0, -50, 80, 40);

流动的控制器构建的是框架

package app.controller;

import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ScrollPane;
import javafx.scene.effect.DropShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;

public class Trimmer2 implements Initializable {
    private Node selectedNode;
    @FXML
    private HBox hboxStream;

    @FXML
    private HBox hboxStreamTrim;

    @FXML
    private Label lblTime;

    public void initialize(URL arg0, ResourceBundle arg1) {
        buidTrimmer();
    }

    private void buidTrimmer() {
        ImageView pic = null;
        HBox hbox = new HBox();
        DropShadow shadow = new DropShadow();
        ClassLoader classLoader = getClass().getClassLoader();
        File path = new File(classLoader.getResource("streams/sub_stream").getPath());
        File [] files = path.listFiles();

        Image[] images = new Image[files.length];
        ImageView[] pics = new ImageView[files.length];

        for (int i = 0; i < files.length; i++) {
            final Image image = images[i] =
                new Image(files[i].toURI().toString(), 80, 40, false, false);
            pic = pics[i] =
                new ImageView(image);
            pic.setEffect(shadow);
            pic.setOnMouseClicked((MouseEvent me) -> {
               System.out.println("do action");
        });
            hbox.getChildren().add(pics[i]);
        }



        Rectangle rectangle = new Rectangle(0, -50, 80, 40);
        rectangle.setFill(Color.rgb(33, 150, 243, 0.5));
        Pane pane = new Pane( rectangle );

        makeSelectable(rectangle, pane);

        VBox vbox = new VBox(); 
        vbox.setSpacing(10);
        vbox.getChildren().addAll(hbox,pane);
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setContent(vbox);
        scrollPane.setId("my_scrollPane");

        hboxStream.getChildren().add(scrollPane);
    }

    private void makeSelectable(Node node, Pane root) {

            node.setOnMouseClicked(event -> {
                if (selectedNode != node) {
                    root.getChildren().removeIf(candidate -> candidate instanceof ResizingControl);
                    selectedNode = node;

                    node.toFront();
                    ResizingControl resizingControl = new ResizingControl(node);
                    root.getChildren().add(resizingControl);
                }
                System.out.println("here");
                event.consume();
            });

    }
}

【问题讨论】:

  • 您是否只想在 HBox 中选择一个 ImageView? ListView 不是更好的方法(当然是水平方向)?
  • 是的,我只想在 hbox 中选择单击的 imageView,我认为这是 Vbox 覆盖的问题,因为当我删除 rect tirmmer setOnMouseClicked 工作正常

标签: java javafx lambda


【解决方案1】:

尝试在窗格中添加 Hbox 和矩形,但窗格必须为空。希望对你有帮助:)

    Rectangle rectangle = new Rectangle(0, 0, imgWidth, imgHeight);
    rectangle.setFill(Color.rgb(33, 150, 243, 0.35));
    Pane pane = new Pane();
    VBox vbox = new VBox(); 
    vbox.getChildren().addAll(pane);
    pane.getChildren().addAll(hbox,rectangle);

【讨论】:

    【解决方案2】:

    鼠标事件转到不透明鼠标的最顶层节点。只需将属性设置为true,鼠标事件将在通常的节点处处理。可以让您的生活更轻松的另一件事是,您还可以将节点放置在不受父布局算法影响且不影响大小计算的布局中。只需将managed 设置为false。这使您可以像这样实现选择:

    private Node selectedNode;
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        HBox container = new HBox();
    
        File directory = new File("someDirectory");
    
        Rectangle selection = new Rectangle(80, 40, Color.rgb(100, 100, 255, 0.5));
        selection.setStrokeType(StrokeType.INSIDE);
        selection.setStrokeWidth(4);
        selection.setStroke(Color.WHITE);
        selection.setVisible(false);
        selection.setMouseTransparent(true);
        selection.setManaged(false);
    
        for (File file : directory.listFiles(f -> f.getName().endsWith(".jpg"))) {
            Image image = new Image(file.toURI().toURL().toExternalForm(), 80, 40, false, false);
            ImageView imageView = new ImageView(image);
            container.getChildren().add(imageView);
            imageView.setOnMouseClicked(evt -> {
                if (selectedNode == imageView) {
                    selection.setVisible(false);
                    selectedNode = null;
                } else {
                    selection.setVisible(true);
                    selection.setLayoutX(imageView.getLayoutX());
                    selectedNode = imageView;
                }
            });
        }
    
        container.getChildren().add(selection);
    
        Scene scene = new Scene(new ScrollPane(container), 400, 400);
    
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    

    注意:我还删除了 getResource 的使用,这是有充分理由的。不保证资源可以作为文件使用。例如。如果您使用.jar 文件,您将无法通过File 访问它们。要么存储在类路径之外的目录中,要么将可用资源列表作为文本资源,以允许您使用多个资源,而无需对每个资源进行硬编码。 (不要在后一种方法中使用File。)

    【讨论】:

    • 这个解释很重要,也很重要,感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    相关资源
    最近更新 更多