4

I'm programming a javafx application, and I'd like to keep my window from going outside the screen bounds, since there isn't much use for this. So, for example, the window shouldn't be able to be dragged so that half of it is off the screen.

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();
    }
}
LilSweden
  • 625
  • 1
  • 7
  • 15

2 Answers2

6

There are a lot of reasons not to do this: you need to be careful not to disable functionality the user might expect, such as dragging across an extended desktop (i.e. dragging between multiple physical displays) or moving the window between virtual desktops (such as "Spaces" in Mac OS X, or equivalent systems in Linux).

Probably the best you can do here is to observe the position of the window with a listener, and push it back to the best location if it's outside the desired bounds. This is probably a little unsatisfactory as a user experience, but achieves the functionality you want:

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);
    }
}
James_D
  • 201,275
  • 16
  • 291
  • 322
0

Here's a few ideas that may help

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

These 2 lines of code will allow you to get the length and width of most computer's screen dimensions.

Next, I would set up a method that constantly gets the position of your window, or at least changes value anytime it is moved, and then set restrictions based off of your knowledge of the screen size and you window size. One way to do it would be something like...

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

}

Let me know if this is any help or if it doesn't answer your question, and I'll edit my answer in response.

  • 1
    Don't mix AWT code with JavaFX code unless you really have to. – James_D Oct 05 '14 at 16:02
  • @James_D Would it be that bad? We are only using it to get the dimensions of the screen and then we are done with it, simply storing it into an int, and then moving on – DreadHeadedDeveloper Oct 05 '14 at 16:03
  • 3
    It's probably fine in this case, but in general you have no real guarantee that there even is an AWT toolkit. Sometimes you have to make that assumption to get the functionality you want (e.g. interacting with the task bar), but when the same thing can be done using just one toolkit, it's always better that way. – James_D Oct 05 '14 at 16:05