Monday, February 23, 2015

JavaFX Restore Window Size & Position

So this evening I decided to figure out how to make my new JavaFX application remember the screen size and location so my wonderful users won't get mad at me when the app doesn't remember how they positioned it. I started to research how to do this in JavaFX and learned two things I did not know so I thought I'd share them with the world.

1) How to get the location and size of a JavaFX stage at the close of the application.
2) How to use java.util.prefs.Preferences to store simple key/value application settings.

package javafxexamples;

import java.io.IOException;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

public class ViewSwitcher {

    private static final String WINDOW_POSITION_X = "Window_Position_X";
    private static final String WINDOW_POSITION_Y = "Window_Position_Y";
    private static final String WINDOW_WIDTH = "Window_Width";
    private static final String WINDOW_HEIGHT = "Window_Height";
    private static final double DEFAULT_X = 10;
    private static final double DEFAULT_Y = 10;
    private static final double DEFAULT_WIDTH = 800;
    private static final double DEFAULT_HEIGHT = 600;
    private static final String NODE_NAME = "ViewSwitcher";
    private static final String BUNDLE = "Bundle";

    public void switchView(String fxmlView, Stage stage, String title) throws IOException {
        Parent root = FXMLLoader.load(getClass().getResource(fxmlView),
            ResourceBundle.getBundle(BUNDLE));
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle(title);
        stage.show();

     
        // Pull the saved preferences and set the stage size and start location
     
        Preferences pref = Preferences.userRoot().node(NODE_NAME);
        double x = pref.getDouble(WINDOW_POSITION_X, DEFAULT_X);
        double y = pref.getDouble(WINDOW_POSITION_Y, DEFAULT_Y);
        double width = pref.getDouble(WINDOW_WIDTH, DEFAULT_WIDTH);
        double height = pref.getDouble(WINDOW_HEIGHT, DEFAULT_HEIGHT);
        stage.setX(x);
        stage.setY(y);
        stage.setWidth(width);
        stage.setHeight(height);
     
     
        // When the stage closes store the current size and window location.
     
        stage.setOnCloseRequest((final WindowEvent event) -> {
            Preferences preferences = Preferences.userRoot().node(NODE_NAME);
            preferences.putDouble(WINDOW_POSITION_X, stage.getX());
            preferences.putDouble(WINDOW_POSITION_Y, stage.getY());
            preferences.putDouble(WINDOW_WIDTH, stage.getWidth());
            preferences.putDouble(WINDOW_HEIGHT, stage.getHeight());
        });
    }
}

4 comments:

  1. Thanks for posting this, I never realized there was such an easy built in solution.

    ReplyDelete
    Replies
    1. Glad it helped! I needed the functionality for a task management app I created and after finally figuring this out I had to post it.

      Delete
  2. used this code to come up with a modified Kotlin version ➟ http://pastebin.com/xm0TWyz0

    ReplyDelete
    Replies
    1. Awesome! Always excited to hear stories about the code being used. I'm glad it was useful.

      Delete