我正在实现一个可以从JavaFX窗口分离的TabPane。当选项卡窗格被拖到它所在的窗口之外时,我希望创建一个新窗口并将该选项卡放置在该窗口中。
我已经实现了一些使用拖动手势在现有窗口之间拖动选项卡的方法。但是,当鼠标移到JavaFX场景之外时,我无法接收任何鼠标事件或拖动事件。这有可能吗?
最佳答案
您可以在适当的节点上侦听鼠标释放事件(例如,标签的图形)。使用MouseEvent.getScreenX()
和MouseEvent.getScreenY()
检查屏幕坐标,并查看它们是否位于当前窗口之外。如果是这样,则创建一个新的窗口,场景和选项卡窗格;从当前选项卡窗格中删除该选项卡,并将其放置在新的选项卡窗格中。
这是一个基本示例,没有多余的装饰(例如,没有用户提示正在发生拖动的事实),但是它将为您提供一个想法:
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);
}
}