Thursday, March 5, 2015

JavaFX Capture & Restore Splitpane Divider Position

Here is another simple code example on how to capture, store, and recover the divider position of a JavaFX splitpane. Implementing this approach allows your splitpane divider to be persisted when you close your application and restored as you left it when you closed the window.

Once the application is built and run you can drag the divider and see the current value of the position. Upon closing the program and restarting the divider should return to its last position.


Concepts: This example demonstrates the following:

1) How to access the PositionProperty field on the splitpane divider and add a listener to capture change events using a lambda function in Java 8.

2) How to use the javafx.application.Platform.runLater method to set the divider position when your application launches. (This technique is necessary due to how the application starts up and initializes)

3) How to store and retrieve simple application preferences using java.util.prefs.Preferences.


Requirements: Java SE 8







package com.broadlyapplicable.javafxexamples;

import java.net.URL;
import java.util.ResourceBundle;
import java.util.prefs.Preferences;
import javafx.beans.property.DoubleProperty;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;

public class FXMLDocumentController implements Initializable {
 
    private static final String SPLIT_PANE_DIVIDER = "SplitPaneDivider";
    private static final String NODE = "FXMLDocumentController";
 
    @FXML
    private SplitPane splitPane;
 
    @FXML
    private Label dividerLabel;
 
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        javafx.application.Platform.runLater(new Runnable() {
            @Override
            public void run() {
                Preferences pref = Preferences.userRoot().node(NODE);
                double splitPaneDivider = pref.getDouble(SPLIT_PANE_DIVIDER, .25);
                splitPane.setDividerPositions(splitPaneDivider);
            }
        });
     
        DoubleProperty dividerPositionProperty = splitPane.getDividers().get(0).positionProperty();
        dividerPositionProperty.addListener((ObservableValue<? extends Number> observable, Number oldValue, Number newValue) -> {
            dividerLabel.setText(newValue.toString());
            Preferences pref = Preferences.userRoot().node(NODE);
            pref.putDouble(SPLIT_PANE_DIVIDER, newValue.doubleValue());
        });
    }  
 
}




<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="427.0" prefWidth="570.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.broadlyapplicable.javafxexamples.FXMLDocumentController">
    <children>
      <VBox prefHeight="427.0" prefWidth="570.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <children>
            <SplitPane fx:id="splitPane" dividerPositions="0.33098591549295775">
              <items>
                <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0" style="-fx-background-color: #dddddd;" />
                <AnchorPane prefHeight="425.0" prefWidth="86.0" style="-fx-background-color: #aaaaaa;" />
              </items>
            </SplitPane>
            <Label fx:id="dividerLabel" alignment="CENTER" text="0.0">
               <font>
                  <Font size="31.0" />
               </font>
               <padding>
                  <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
               </padding>
            </Label>
         </children>
      </VBox>
    </children>
</AnchorPane>


No comments:

Post a Comment