JavaFX容器可拖动
我在JavaFX中有一个可拖动的容器。此容器在弹出窗口中实现。我可以拖动容器,但是如果我拖动它,鼠标事件没有恒定的坐标。鼠标位置在两个固定位置之间快速切换 这是我的密码:JavaFX容器可拖动,java,javafx,mouseevent,draggable,Java,Javafx,Mouseevent,Draggable,我在JavaFX中有一个可拖动的容器。此容器在弹出窗口中实现。我可以拖动容器,但是如果我拖动它,鼠标事件没有恒定的坐标。鼠标位置在两个固定位置之间快速切换 这是我的密码: container.setOnMouseDragged(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent me) { // TODO Au
container.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
// TODO Auto-generated method stub
if(dragAct==true){
//Set the Position of the PopUp to the Position of the Mouse
setX(me.getX());
setY(me.getY());
}
}
});
container.setonMouseDrawed(新的EventHandler(){
@凌驾
公共无效句柄(MouseEvent me){
//TODO自动生成的方法存根
如果(dragAct==true){
//将弹出窗口的位置设置为鼠标的位置
setX(me.getX());
setY(me.getY());
}
}
});
容器是一个VBox。Main类是PopUp类的扩展版本
JavaFX Container Draggable
您调用的setX和setY方法在屏幕坐标中设置弹出窗口的位置。对me.getX()和me.getY()的调用提供了鼠标相对于容器的坐标。移动弹出窗口时,容器也会移动,因此鼠标相对于容器的位置发生了更改。因此,从一个拖动事件到下一个拖动事件,您的计算将不一致
修正是计算相对于固定物体的位置。由于您正在移动弹出窗口(窗口),因此固定坐标系为屏幕坐标系。MouseEvent有getScreenX和getScreenY方法,您可以使用这些方法轻松获取这些内容
我喜欢通过保存最后一个鼠标位置,然后计算拖动时移动的距离来实现拖动。有其他(可能不太详细)的方法可以做到这一点,但对我来说,这是最清楚的:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Popup;
import javafx.stage.Stage;
public class DraggingPopup extends Application {
@Override
public void start(Stage primaryStage) {
Button button = new Button("Show popup");
button.setOnAction(event -> showDraggablePopup(primaryStage));
StackPane root = new StackPane(button);
Scene scene = new Scene(root, 250, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
private void showDraggablePopup(Stage owner) {
Popup popup = new Popup();
Button closeButton = new Button("Close");
closeButton.setOnAction(event -> popup.hide());
StackPane container = new StackPane(closeButton);
container.setStyle("-fx-background-color: steelblue;");
container.setMinWidth(300);
container.setMinHeight(125);
// Dragging implementation:
ObjectProperty<Point2D> mouseLocation = new SimpleObjectProperty<>();
container.setOnMousePressed(event ->
mouseLocation.set(new Point2D(event.getScreenX(), event.getScreenY())));
container.setOnMouseDragged(event -> {
if (mouseLocation.get() != null) {
double x = event.getScreenX();
double deltaX = x - mouseLocation.get().getX() ;
double y = event.getScreenY();
double deltaY = y - mouseLocation.get().getY() ;
//in case of 2 or more computer screens this help me to avoid get stuck on 1 screen
if(Math.abs(popup.getX()-x)>popup.getWidth()){
popup.setX(x);
popup.setY(y);
}else {
popup.setX(popup.getX() + deltaX);
popup.setY(popup.getY() + deltaY);
}
mouseLocation.set(new Point2D(x, y));
}
});
container.setOnMouseReleased(event -> mouseLocation.set(null));
popup.getScene().setRoot(container);
popup.show(owner);
}
public static void main(String[] args) {
launch(args);
}
}
导入javafx.application.application;
导入javafx.beans.property.ObjectProperty;
导入javafx.beans.property.SimpleObject属性;
导入javafx.geometry.Point2D;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.layout.StackPane;
导入javafx.stage.Popup;
导入javafx.stage.stage;
公共类DraggingPopup扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
按钮按钮=新按钮(“显示弹出窗口”);
按钮。设置操作(事件->ShowDragablePopup(primaryStage));
StackPane根=新建StackPane(按钮);
场景=新场景(根,250,75);
初级阶段。场景(场景);
primaryStage.show();
}
私有void showDraggablePopup(后台所有者){
Popup Popup=新的Popup();
按钮关闭按钮=新按钮(“关闭”);
closeButton.setOnAction(事件->弹出窗口.hide());
StackPane容器=新的StackPane(关闭按钮);
container.setStyle(“-fx背景色:钢蓝;”);
容器。设置最小宽度(300);
容器。设置最小高度(125);
//拖动实现:
ObjectProperty mouseLocation=新的SimpleObjectProperty();
container.setOnMousePressed(事件->
set(新的Point2D(event.getScreenX(),event.getScreenY());
container.setOnMouseDrawed(事件->{
if(mouseLocation.get()!=null){
double x=event.getScreenX();
double deltaX=x-mouseLocation.get().getX();
double y=event.getScreenY();
double deltaY=y-mouseLocation.get().getY();
//如果有两个或两个以上的电脑屏幕,这有助于我避免卡在一个屏幕上
if(Math.abs(popup.getX()-x)>popup.getWidth()){
popup.setX(x);
setY(y);
}否则{
popup.setX(popup.getX()+deltaX);
popup.setY(popup.getY()+deltaY);
}
mouseLocation.set(新点2d(x,y));
}
});
container.setOnMouseReleased(事件->鼠标定位.set(null));
popup.getScene().setRoot(容器);
弹出显示(所有者);
}
公共静态void main(字符串[]args){
发射(args);
}
}
它工作得很好,我还有一个关于弹出窗口的问题。目前,弹出窗口可能会离开主舞台。。。是否可以在主阶段绑定弹出窗口。它不应该被允许离开主舞台的窗口。。。有没有解决办法,我试了很多次,但我不知道如何解决这个问题,只需在移动前检查主舞台的位置、宽度和高度以及弹出窗口的宽度和高度。谢谢你的回答,没有集成自动功能?我必须用数学来解决这个问题?它不会比调用Math.min(…)
和Math.max(…)