3 Replies Latest reply on Mar 25, 2013 2:23 AM by 857678

    How to remember the width of TableColumns as well as the order of them?

      I am working with TableView in JavaFX2.2 and create one which the user can set the width for each TableColumn and the order of them in this TableView by drag-and-drop. However, after shutdown and re-execute this JavaFX application, the width and order for these TableColumns have restored to the original one. And now the users would like the width and order be the custom one when they re-execute. So, is there any idea for this issue?

      I use the FXML to create this TableView. I thought the way to resolve should be modifying the fxml file for it once the user drag-and-drop something. Are there any advice for it?

      Thank you!

      Edited by: 854675 on Mar 19, 2013 2:00 AM
        • 1. Re: How to remember the width of TableColumns as well as the order of them?
          Don't try to modify the FXML file. Once your application is properly deployed, the FXML file will be bundled in a jar file, and will be hard or impossible to access at runtime. If you're deploying via Java Web Start or as an applet, the user may even download the jar file afresh every time they run the application.

          You need to do a bit of work to implement this, but it's not too bad.

          When the user exits the application, get the current order of the columns (from tableView.getColumns()) and the width of each column.
          Use the [url http://docs.oracle.com/javase/7/docs/api/java/util/prefs/Preferences.html]Java Preferences API to save this information.

          On startup, probably in the initialize() method of your controller, read the information back from the preferences, if it exists, and restore the column order and widths.
          • 2. Re: How to remember the width of TableColumns as well as the order of them?
            Simple example:

            import java.util.ArrayList;
            import java.util.Collections;
            import java.util.List;
            import java.util.prefs.Preferences;
            import javafx.beans.property.SimpleStringProperty;
            import javafx.beans.property.StringProperty;
            import javafx.collections.FXCollections;
            import javafx.collections.ObservableList;
            import javafx.fxml.FXML;
            import javafx.scene.control.TableColumn;
            import javafx.scene.control.TableView;
            public class ColumnPreservingTableController {
              private List<TableColumn<Person, ?>> originalColumns;
              private TableView<Person> table;
              public void initialize() {
                originalColumns = Collections.unmodifiableList(new ArrayList<TableColumn<Person, ?>>(table.getColumns()));
                Preferences prefs = Preferences.userNodeForPackage(this.getClass());
                int[] colReorder = new int[originalColumns.size()];
                double[] colWidths = new double[originalColumns.size()];
                boolean allKnown = true;
                for (int i = 0; i < colReorder.length; i++) {
                  colReorder[i] = prefs.getInt("colReorder" + i, -1);
                  if (colReorder[i] == -1) {
                    allKnown = false;
                  colWidths[i] = prefs.getDouble("colWidth" + i, -1);
                if (allKnown) {
                  ObservableList<TableColumn<Person, ?>> columns = FXCollections.observableArrayList();
                  for (int i = 0; i < colReorder.length; i++) {
            for (int i = 0; i < colWidths.length; i++) {
            if (colWidths[i] > 0) {

            public void shutdown() {
            List<TableColumn<Person, ?>> columns = table.getColumns();
            Preferences prefs = Preferences.userNodeForPackage(getClass());
            for (int i = 0; i < columns.size(); i++) {
            prefs.putInt("colReorder" + i, originalColumns.indexOf(columns.get(i)));
            prefs.putDouble("colWidth" + i, columns.get(i).getWidth());

            private ObservableList<Person> createData() {
            return FXCollections.observableArrayList(
            new Person("Hugo", "Lloris","hugo@thfc.com"),
            new Person("Brad", "Friedel", "brad@thfc.com")

            public class Person {
            private final StringProperty firstName;
            private final StringProperty lastName;
            private final StringProperty email;

            public Person(String firstName, String lastName, String email) {
            this.firstName = new SimpleStringProperty(this, "firstName", firstName);
            this.lastName = new SimpleStringProperty(this, "lastName", lastName);
            this.email = new SimpleStringProperty(this, "email", email);

            public String getFirstName() { return firstName.get();}
            public void setFirstName(String firstName) { this.firstName.set(firstName); }
            public StringProperty firstNameProperty() { return firstName; }

            public String getLastName() { return lastName.get(); }
            public void setLastName(String lastName) { this.lastName.set(lastName); }
            public StringProperty lastNameProperty() { return lastName; }

            public String getEmail() { return email.get(); }
            public void setEmail(String email) { this.email.set(email); }
            public StringProperty emailProperty() { return email; }

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

            <?import javafx.scene.layout.BorderPane?>
            <?import javafx.scene.control.TableView?>
            <?import javafx.scene.control.TableColumn?>
            <?import javafx.scene.control.cell.PropertyValueFactory?>

            <BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="ColumnPreservingTableController">
                      <TableView fx:id="table">
                                <TableColumn text="First Name">
                                          <PropertyValueFactory property="firstName" />
                                <TableColumn text="Last Name">
                                          <PropertyValueFactory property="lastName" />
                                <TableColumn text="Email Address">
                                          <PropertyValueFactory property="email" />
            import java.io.IOException;

            import javafx.application.Application;
            import javafx.event.EventHandler;
            import javafx.fxml.FXMLLoader;
            import javafx.scene.Parent;
            import javafx.scene.Scene;
            import javafx.stage.Stage;
            import javafx.stage.WindowEvent;

            public class ColumnPreservingTable extends Application {

            public void start(Stage primaryStage) throws IOException {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("ColumnPreservingTable.fxml"));
            Parent root = (Parent) loader.load();
            final ColumnPreservingTableController controller = loader.<ColumnPreservingTableController> getController();
            Scene scene = new Scene(root, 400, 200);
            primaryStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            public void handle(WindowEvent event) {

            public static void main(String[] args) { launch(args); }
            • 3. Re: How to remember the width of TableColumns as well as the order of them?
              Dear James,

              Thanks for your advice. Now everything works great.

              I have taken a long time to learn using Preferences Class. Your sample is very helpful.

              Greetings and blessings.