保持JavaFX窗口在屏幕范围内

4

我正在编写一个JavaFX应用程序,希望保持窗口不超出屏幕范围,因为这并没有太多用处。例如,窗口不应该被拖动到屏幕外。

public class ui extends Application{
    public static void main (String[] args){
        launch(args);
    }
    public void start(Stage mainStage){
        mainStage.initStyle(StageStyle.DECORATED);
        Rectangle2D mainScreen = Screen.getPrimary().getVisualBounds();
        mainStage.setWidth(mainScreen.getWidth());
        mainStage.setHeight(mainScreen.getHeight());

        BorderPane mainPane = new BorderPane(background);

        Scene mainScene = new Scene(mainPane, Color.BLACK);
        mainStage.setScene(mainScene);

        mainStage.show();
    }
}

如果您能提供一些代码,我们就能为您做更多的事情。现在,我只能猜测您拥有什么... - DreadHeadedDeveloper
@DreadHeadedDeveloper 我只需要一个通用的解决方案,所以我不确定它是否有帮助,但我会添加一些代码。 - LilSweden
2个回答

6
有很多原因不建议这样做:您需要小心,不要禁用用户可能期望的功能,例如在扩展桌面(即在多个物理显示器之间拖动)或在虚拟桌面之间移动窗口(例如“Mac OS X”中的“Spaces”或类似系统中的等效项)。

在此处,您可以做的最好的事情可能是使用监听器观察窗口位置,并将其推回到最佳位置,如果它超出所需范围。这可能作为用户体验有点不令人满意,但实现了您想要的功能:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.geometry.Rectangle2D;
import javafx.stage.Screen;
import javafx.stage.Stage;

public class ConstrainedWindow extends Application {

    @Override
    public void start(Stage primaryStage) {

        Bounds allScreenBounds = computeAllScreenBounds();
        ChangeListener<Number> boundsListener = (obs, oldValue, newValue) -> {
            double x = primaryStage.getX();
            double y = primaryStage.getY();
            double w = primaryStage.getWidth();
            double h = primaryStage.getHeight();
            if (x < allScreenBounds.getMinX()) {
                primaryStage.setX(allScreenBounds.getMinX());
            }
            if (x + w > allScreenBounds.getMaxX()) {
                primaryStage.setX(allScreenBounds.getMaxX() - w);
            }
            if (y < allScreenBounds.getMinY()) {
                primaryStage.setY(allScreenBounds.getMinY());
            }
            if (y + h > allScreenBounds.getMaxY()) {
                primaryStage.setY(allScreenBounds.getMaxY() - h);
            }
        };
        primaryStage.xProperty().addListener(boundsListener);
        primaryStage.yProperty().addListener(boundsListener);
        primaryStage.widthProperty().addListener(boundsListener);
        primaryStage.heightProperty().addListener(boundsListener);
        primaryStage.show();
    }

    private Bounds computeAllScreenBounds() {
        double minX = Double.POSITIVE_INFINITY ;
        double minY = Double.POSITIVE_INFINITY ;
        double maxX = Double.NEGATIVE_INFINITY ;
        double maxY = Double.NEGATIVE_INFINITY ;
        for (Screen screen : Screen.getScreens()) {
            Rectangle2D screenBounds = screen.getBounds();
            if (screenBounds.getMinX() < minX) {
                minX = screenBounds.getMinX();
            }
            if (screenBounds.getMinY() < minY) {
                minY = screenBounds.getMinY() ;
            }
            if (screenBounds.getMaxX() > maxX) {
                maxX = screenBounds.getMaxX();
            }
            if (screenBounds.getMaxY() > maxY) {
                maxY = screenBounds.getMaxY() ;
            }
        }
        return new BoundingBox(minX, minY, maxX-minX, maxY-minY);
    }

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

1
只是因为它不允许我发布少于15个字符的评论,没有任何意义 :) - James_D
非常好用!谢谢。 - Oooogi

0

以下是几个可能有用的想法

public final int width = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
public final int height = java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;

这两行代码可以让你获得大多数电脑屏幕尺寸的长度和宽度。
接下来,我会建立一个方法来不断获取窗口位置,或者至少在移动时改变值,并根据你了解的屏幕尺寸和窗口尺寸设置限制。其中一种方法是...
if(yWinPos > (height - wHeight))//wHeight is actual height of the window, not the y pos of window
{

//code that prevents it from moving past the bottom part of screen

}

如果这有帮助,或者没有回答你的问题,请告诉我,我会根据你的反馈编辑我的回答。


1
除非你真的必须这样做,否则不要混合使用AWT代码和JavaFX代码。 - James_D
@James_D 这会很糟糕吗?我们只是用它来获取屏幕的尺寸,然后就完成了,将其存储在一个整数中,然后继续进行。 - DreadHeadedDeveloper
3
在这种情况下可能没问题,但总的来说你并不能保证有一个真正的AWT工具包。有时您必须做出这样的假设才能获得所需的功能(例如与任务栏交互),但当只需要一个工具包就能完成同样的事情时,那样总是更好。 - James_D

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接