如何使用JavaFX将可移动对象保持在窗口内?

如何使用JavaFX将可移动对象保持在窗口内?,javafx,shapes,Javafx,Shapes,我有一个圆圈和四个按钮来移动它;上(伊洛斯),下(唉),左(瓦塞马利)和右(奥基亚尔)。当然,我想让我的圆圈保持在窗口内,但一旦我为按钮事件添加了一个条件,阻止圆圈在窗口外移动,它就会完全停止向该方向移动 圆的半径为100,从中间(?)开始,表示坐标(200200) 下面是我的代码,我相信你们中的一些人会很容易从这样一个简单的程序中发现我的错误。我只在一个按钮上设置了假设的预防条件,这样你就可以看到其他按钮的工作正常。该行已被注释 import javafx.application.Applic

我有一个圆圈和四个按钮来移动它;上(伊洛斯),下(唉),左(瓦塞马利)和右(奥基亚尔)。当然,我想让我的圆圈保持在窗口内,但一旦我为按钮事件添加了一个条件,阻止圆圈在窗口外移动,它就会完全停止向该方向移动

圆的半径为100,从中间(?)开始,表示坐标(200200)

下面是我的代码,我相信你们中的一些人会很容易从这样一个简单的程序中发现我的错误。我只在一个按钮上设置了假设的预防条件,这样你就可以看到其他按钮的工作正常。该行已被注释

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.shape.Circle;
import javafx.scene.paint.Color;
import javafx.scene.control.Button;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.collections.ObservableList;

public class Ympyra extends Application {

private double uusiY, uusiX, raja = 0;

@Override
public void start(Stage aloitus) throws Exception {

    Circle ympyra = new Circle(100);
    ympyra.setStroke(Color.BLACK);
    ympyra.setFill(Color.WHITE);

    Button btnYlos = new Button("Ylos");
    Button btnAlas = new Button("Alas");
    Button btnOikea = new Button("Oikealle");
    Button btnVasen = new Button("Vasemmalle");

    btnYlos.setOnMouseClicked(e -> {
        uusiY = ympyra.getCenterY() + uusiY - 10;
        if (uusiY < 100) { uusiY += 10; } // for example this kind of condition stops upward movement completely
        ympyra.setTranslateX(uusiX);
        ympyra.setTranslateY(uusiY);
    });
    btnAlas.setOnMouseClicked(e -> {
        uusiY = ympyra.getCenterY() + uusiY + 10;
        ympyra.setTranslateX(uusiX);
        ympyra.setTranslateY(uusiY);
    });
    btnOikea.setOnMouseClicked(e -> {
        uusiX = ympyra.getCenterX() + uusiX + 10;
        ympyra.setTranslateX(uusiX);
        ympyra.setTranslateY(uusiY);
    });
    btnVasen.setOnMouseClicked(e -> {
        uusiX = ympyra.getCenterX() + uusiX - 10;
        ympyra.setTranslateX(uusiX);
        ympyra.setTranslateY(uusiY);
    });

    HBox napit = new HBox();
    napit.setAlignment(Pos.CENTER);
    napit.setSpacing(20);
    napit.setMargin(btnYlos, new Insets(5, 5, 5, 5));
    napit.setMargin(btnAlas, new Insets(5, 5, 5, 5));
    napit.setMargin(btnOikea, new Insets(5, 5, 5, 5));
    napit.setMargin(btnVasen, new Insets(5, 5, 5, 5));
    ObservableList lista = napit.getChildren();
    lista.addAll(btnYlos, btnAlas, btnOikea, btnVasen);

    BorderPane paneeli = new BorderPane();
    paneeli.setCenter(ympyra);
    paneeli.setBottom(napit);

    Scene kehys = new Scene(paneeli, 400, 400);
    aloitus.setTitle("Ympyra");
    aloitus.setScene(kehys);
    aloitus.show();

}

public static void main(String[] args) {
    launch(args);
}
导入javafx.application.application;
导入javafx.stage.stage;
导入javafx.scene.scene;
导入javafx.scene.layout.*;
导入javafx.scene.shape.Circle;
导入javafx.scene.paint.Color;
导入javafx.scene.control.Button;
导入javafx.geometry.Insets;
导入javafx.geometry.Pos;
导入javafx.collections.ObservableList;
公共类Ympyra扩展了应用程序{
私人双uusiY,uusiX,raja=0;
@凌驾
public void start(Stage aloitus)引发异常{
圆圈ympyra=新圆圈(100);
ympyra.setStroke(颜色:黑色);
刚毛(颜色:白色);
按钮btnYlos=新按钮(“Ylos”);
按钮btnAlas=新按钮(“Alas”);
按钮btnOikea=新按钮(“Oikealle”);
按钮btnVasen=新按钮(“Vasemmalle”);
btnYlos.setOnMouseClicked(e->{
uusiY=ympyra.getCenterY()+uusiY-10;
例如,如果(uusiY<100){uusiY+=10;}//这种情况完全停止向上运动
蛱蛱蛱(uu6);
ympyra.setTranslateY(uusiY);
});
btnAlas.setOnMouseClicked(e->{
uusiY=ympyra.getCenterY()+uusiY+10;
蛱蛱蛱(uu6);
ympyra.setTranslateY(uusiY);
});
btnOikea.setOnMouseClicked(e->{
uusiX=ympyra.getCenterX()+uusiX+10;
蛱蛱蛱(uu6);
ympyra.setTranslateY(uusiY);
});
btnVasen.setOnMouseClicked(e->{
uusiX=ympyra.getCenterX()+uuusix-10;
蛱蛱蛱(uu6);
ympyra.setTranslateY(uusiY);
});
HBox napit=新的HBox();
Nabit.设置对齐(位置中心);
napit.setspace(20);
napit.setMargin(btnYlos,新插图(5,5,5,5));
napit.setMargin(btnAlas,新插图(5,5,5,5));
napit.setMargin(btnOikea,新插图(5,5,5,5));
napit.setMargin(btnVasen,新插图(5,5,5,5));
ObservableList lista=napit.getChildren();
列表a.addAll(btnYlos、btnAlas、btnOikea、btnVasen);
BorderPane paneeli=新的BorderPane();
paneeli.设置中心(ympyra);
paneeli.setBottom(napit);
场景基希斯=新场景(paneeli,400400);
aloitus.setTitle(“Ympyra”);
aloitus.setScene(基希斯);
aloitus.show();
}
公共静态void main(字符串[]args){
发射(args);
}

}

问题是
ympyra.getCenterX()
ympyra.getCenterY()
在这种情况下将始终返回0。您必须检查父对象中的边界,以了解圆是否“超出”窗口

这应该可以解决问题

btnYlos.setOnMouseClicked(e -> {
    uusiY -= ympyra.getBoundsInParent().getMinY() - 10 < 0 ? ympyra.getBoundsInParent().getMinY() : 10;
    ympyra.setTranslateY(uusiY);
});
btnAlas.setOnMouseClicked(e -> {
    uusiY += ympyra.getBoundsInParent().getMaxY() + 10 > ympyra.getParent().getLayoutBounds().getMaxY()
            ? ympyra.getParent().getLayoutBounds().getMaxY() - ympyra.getBoundsInParent().getMaxY() : 10;
    ympyra.setTranslateY(uusiY);
});
btnOikea.setOnMouseClicked(e -> {
    uusiX += ympyra.getBoundsInParent().getMaxX() + 10 > ympyra.getParent().getLayoutBounds().getMaxX()
            ? ympyra.getParent().getLayoutBounds().getMaxX() - ympyra.getBoundsInParent().getMaxX() : 10;
    ympyra.setTranslateX(uusiX);
});
btnVasen.setOnMouseClicked(e -> {
    uusiX -= ympyra.getBoundsInParent().getMinX() - 10 < 0 ? ympyra.getBoundsInParent().getMinX() : 10;
    ympyra.setTranslateX(uusiX);
});
btnYlos.setOnMouseClicked(e->{
uusiY-=ympyra.getBoundsInParent().getMinY()-10<0?ympyra.getBoundsInParent().getMinY():10;
ympyra.setTranslateY(uusiY);
});
btnAlas.setOnMouseClicked(e->{
uusiY+=ympyra.getBoundsInParent().getMaxY()+10>ympyra.getParent().getLayoutBounds().getMaxY()
?ympyra.getParent().getLayoutBounds().getMaxY()-ympyra.getBoundsInParent().getMaxY():10;
ympyra.setTranslateY(uusiY);
});
btnOikea.setOnMouseClicked(e->{
uusiX+=ympyra.getBoundsInParent().getMaxX()+10>ympyra.getParent().getLayoutBounds().getMaxX()
?ympyra.getParent().getLayoutBounds().getMaxX()-ympyra.getBoundsInParent().getMaxX():10;
蛱蛱蛱(uu6);
});
btnVasen.setOnMouseClicked(e->{
uusiX-=ympyra.getBoundsInParent().getMinX()-10<0?ympyra.getBoundsInParent().getMinX():10;
蛱蛱蛱(uu6);
});

对于每种情况,它都会检查是否可以转换10(窗口和圆之间的转换小于10px),如果不可以,则根据圆的位置和父对象的边界计算转换

问题是
ympyra.getCenterX()
ympyra.getCenterY()
在这种情况下总是返回0。您必须检查父对象中的边界,以了解圆是否“超出”窗口

这应该可以解决问题

btnYlos.setOnMouseClicked(e -> {
    uusiY -= ympyra.getBoundsInParent().getMinY() - 10 < 0 ? ympyra.getBoundsInParent().getMinY() : 10;
    ympyra.setTranslateY(uusiY);
});
btnAlas.setOnMouseClicked(e -> {
    uusiY += ympyra.getBoundsInParent().getMaxY() + 10 > ympyra.getParent().getLayoutBounds().getMaxY()
            ? ympyra.getParent().getLayoutBounds().getMaxY() - ympyra.getBoundsInParent().getMaxY() : 10;
    ympyra.setTranslateY(uusiY);
});
btnOikea.setOnMouseClicked(e -> {
    uusiX += ympyra.getBoundsInParent().getMaxX() + 10 > ympyra.getParent().getLayoutBounds().getMaxX()
            ? ympyra.getParent().getLayoutBounds().getMaxX() - ympyra.getBoundsInParent().getMaxX() : 10;
    ympyra.setTranslateX(uusiX);
});
btnVasen.setOnMouseClicked(e -> {
    uusiX -= ympyra.getBoundsInParent().getMinX() - 10 < 0 ? ympyra.getBoundsInParent().getMinX() : 10;
    ympyra.setTranslateX(uusiX);
});
btnYlos.setOnMouseClicked(e->{
uusiY-=ympyra.getBoundsInParent().getMinY()-10<0?ympyra.getBoundsInParent().getMinY():10;
ympyra.setTranslateY(uusiY);
});
btnAlas.setOnMouseClicked(e->{
uusiY+=ympyra.getBoundsInParent().getMaxY()+10>ympyra.getParent().getLayoutBounds().getMaxY()
?ympyra.getParent().getLayoutBounds().getMaxY()-ympyra.getBoundsInParent().getMaxY():10;
ympyra.setTranslateY(uusiY);
});
btnOikea.setOnMouseClicked(e->{
uusiX+=ympyra.getBoundsInParent().getMaxX()+10>ympyra.getParent().getLayoutBounds().getMaxX()
?ympyra.getParent().getLayoutBounds().getMaxX()-ympyra.getBoundsInParent().getMaxX():10;
蛱蛱蛱(uu6);
});
btnVasen.setOnMouseClicked(e->{
uusiX-=ympyra.getBoundsInParent().getMinX()-10<0?ympyra.getBoundsInParent().getMinX():10;
蛱蛱蛱(uu6);
});
对于每种情况,它将检查平移是否可能为10(窗口和圆之间的平移小于10px),如果不可能,则根据圆位置和父对象的边界计算平移