java - 如何拖动 JavaFX 节点并检测 JavaFX Windows 之外的放置事件?

标签 java javafx javafx-8

我正在实现一个可以从 JavaFX 窗口分离的 TabPane。当Tab Pane被拖出来自其来自的窗口外,我想创建一个新窗口,并将其放在该窗口中。

我已经实现了一些使用拖动手势在现有窗口之间拖动选项卡的方法。但是,当鼠标移出 JavaFX 场景时,我无法接收任何鼠标事件或拖动事件。这有可能吗?

最佳答案

您可以在适当的节点(例如选项卡的图形)上监听鼠标释放事件。使用 MouseEvent.getScreenX()MouseEvent.getScreenY() 检查屏幕坐标,看看它们是否位于当前窗口之外。如果是,则创建一个新窗口、场景和选项卡 Pane ;从当前选项卡 Pane 中删除选项卡并将其放入新 Pane 中。

这是一个没有多余装饰的基本示例(例如,没有关于正在发生拖动的用户提示),但它会给你一个想法:

import javafx.application.Application;
import javafx.collections.ListChangeListener.Change;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.stage.Window;

public class DetachableTabExample extends Application {

    private int tabCount = 0 ;

    @Override
    public void start(Stage primaryStage) {
        TabPane tabPane = new TabPane();
        Button newTabButton = new Button("New Tab");
        newTabButton.setOnAction(event -> {
            Tab tab = new Tab();
            Label tabLabel = new Label("Tab "+(++tabCount));
            tab.setGraphic(tabLabel);
            tab.setContent(new TextArea());
            tabPane.getTabs().add(tab);

            tabLabel.setOnMouseReleased(me -> {
                Point2D mouseLoc = new Point2D(me.getScreenX(), me.getScreenY());
                Window window = tabPane.getScene().getWindow();
                Rectangle2D windowBounds 
                    = new Rectangle2D(window.getX(), window.getY(),
                                      window.getWidth(), window.getHeight());
                if (! windowBounds.contains(mouseLoc)) {
                    tabPane.getTabs().remove(tab);
                    Stage newStage = new Stage();
                    TabPane newTabPane = new TabPane();
                    newTabPane.getTabs().add(tab);
                    Scene scene = new Scene(new BorderPane(newTabPane));
                    newStage.setScene(scene);
                    newStage.setX(me.getScreenX());
                    newStage.setY(me.getScreenY());
                    newStage.setWidth(window.getWidth());
                    newStage.setHeight(window.getHeight());
                    newStage.show();
                }
            });

        });


        BorderPane root = new BorderPane(tabPane, newTabButton, null, null, null);
        Scene scene = new Scene(root, 600, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

关于java - 如何拖动 JavaFX 节点并检测 JavaFX Windows 之外的放置事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26610660/

相关文章:

java - 警告 "unknown addresses are found in partition table"

java - 如何在javafx中删除图像中的空格

Pane 中的 JavaFX Canvas 大小

呈现对象时的 javaFX 事件

tableview - JavaFX 自定义 MasterDetail Pane

java - 选择在哪个监视器中打开 JavaFX 窗口

java - Maven Javadoc 插件 - 覆盖默认 CSS 的特定部分

java - 单选按钮 If 语句

javafx - 每个声明都需要 @FXML 吗?

java - 在 Java 中模拟 wget --no-check-certificate --secure-protocol=TLSv1