Держите окно javafx внутри границ экрана

Я программирую приложение 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();
    }
}

person LilSweden    schedule 05.10.2014    source источник
comment
Если бы вы могли скинуть нам часть своего кода, мы смогли бы сделать для вас гораздо больше. Сейчас я могу только догадываться, что у вас есть...   -  person DreadHeadedDeveloper    schedule 05.10.2014
comment
@DreadHeadedDeveloper Мне нужно только общее решение, поэтому я не уверен, что оно поможет, но я добавлю немного кода.   -  person LilSweden    schedule 05.10.2014


Ответы (2)


Есть много причин не делать этого: вы должны быть осторожны, чтобы не отключить функции, которые может ожидать пользователь, такие как перетаскивание по расширенному рабочему столу (т. е. перетаскивание между несколькими физическими дисплеями) или перемещение окна между виртуальными рабочими столами (например, «Пробелы» в Mac OS X или эквивалентные системы в Linux).

Вероятно, лучшее, что вы можете здесь сделать, это наблюдать за положением окна с помощью слушателя и возвращать его обратно в лучшее место, если оно выходит за желаемые границы. Это, вероятно, немного неудовлетворительно с точки зрения взаимодействия с пользователем, но обеспечивает желаемую функциональность:

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);
    }
}
person James_D    schedule 05.10.2014
comment
Просто потому, что это не позволило бы мне опубликовать комментарий длиной менее 15 символов, это не имело никакого смысла :) - person James_D; 05.10.2014
comment
Работает как шарм! Спасибо. - person Oooogi; 26.06.2017

Вот несколько идей, которые могут помочь

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

Эти 2 строки кода позволят вам получить длину и ширину экрана большинства компьютеров.

Затем я бы настроил метод, который постоянно получает положение вашего окна или, по крайней мере, изменяет значение каждый раз, когда оно перемещается, а затем устанавливает ограничения, основанные на ваших знаниях о размере экрана и вашем размере окна. Один из способов сделать это будет что-то вроде...

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

}

Дайте мне знать, поможет ли это или не ответит на ваш вопрос, и я отредактирую свой ответ в ответ.

person DreadHeadedDeveloper    schedule 05.10.2014
comment
Не смешивайте код AWT с кодом JavaFX, если в этом нет особой необходимости. - person James_D; 05.10.2014
comment
@James_D Было бы так плохо? Мы используем его только для получения размеров экрана, а затем мы закончили с ним, просто сохранив его в int, а затем двигаясь дальше. - person DreadHeadedDeveloper; 05.10.2014
comment
В данном случае это, наверное, хорошо, но в целом у вас нет реальной гарантии, что даже есть инструментарий AWT. Иногда вам нужно сделать это предположение, чтобы получить желаемую функциональность (например, взаимодействие с панелью задач), но когда то же самое можно сделать с помощью всего одного набора инструментов, так всегда лучше. - person James_D; 05.10.2014