JavaFX: Save and restore visual state of TableView (order, width and visibility)
Asked Answered
R

2

11

In a JavaFX TableView, how can I determine changes of

  • I. The column order [solved]
  • II. The column's width [solved]
  • III. The column's visibilty [solved]

to save them in preferences and restore them, the next time I start an application?

I. The column order

Works now. However, wasRemoved() is triggered when reordering columns, not wasPermutation().

final List<TableColumn<MyType, ?>> unchangedColumns = Collections.unmodifiableList(new ArrayList<TableColumn<MyType, ?>>(columns));

columns.addListener(new ListChangeListener<TableColumn<MyType, ?>>() {
  @Override
  public void onChanged(ListChangeListener.Change<? extends TableColumn<MyType, ?>> change) {
    while (change.next()) {
      if (change.wasRemoved()) {
        ObservableList<TableColumn<MyType, ?>> columns = table.getColumns();
        int[] colOrder = new int[columns.size()];

        for (int i = 0; i < columns.size(); ++i) {
          colOrder[i] = unchangedColumns.indexOf(columns.get(i));
        }

        // colOrder will now contain current order (e.g. 1, 2, 0, 5, 4)
      }
    }
  }
});

II. The column's width

This is working.

for (TableColumn<MyType, ?> column: columns) {
  column.widthProperty().addListener(new ChangeListener<Number>() {
    @Override
      public void changed(ObservableValue<? extends Number> observableValue, Number oldWidth, Number newWidth) {
        logger.info("Width: " + oldWidth + " -> " + newWidth);
  });
}

III. The column's visibilty

This does the trick.

for (TableColumn<MyType, ?> column: columns) {
  column.visibleProperty().addListener(new ChangeListener<Boolean>() {
    @Override
      public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldVisibility, Boolean newVisibility) {
        logger.info("Visibility: " + oldVisibility + " -> " + newVisibility);
  });
}
Rigney answered 28/11, 2014 at 12:52 Comment(4)
Managed to handle column width and column order now. Though, no idea about column visibility yet.Rigney
Have you tried column.visibleProperty()?Ukrainian
Why do you need listeners? Isn't it enough just to check these when the application exits, instead of updating the values any time they change?Minstrelsy
I agree with @Minstrelsy - in my app I am only checking/saving these settings at app start / stop.Shel
F
1

I have implemented a simple custom TableView as an extension of the TableView for automated storage of the columns order and width. It is based on the given solution in the question. My custom TableView is called PropertySaveTableView.

You can find it here: https://gist.github.com/y4nnick/ca976e58be23aab20dfbc8d81ea46816

The "EinstellungService.java" is only a interface for permanent storage of the properties. You must create your own implementation with you favorite technology.

Maybe i will add the visibility saving later, if so i will let you know here.

Franklin answered 21/8, 2016 at 14:32 Comment(0)
S
0

FWIW - the following code is the complement to the first part of the question, to apply the saved column order:

private void applyColumnOrder(int[] order) {    
   ObservableList<TableColumn<MyType, ?>> columns = getColumns();

   if (order.length == columns.size()) {
      columns.clear();

      for (int ix = 0; ix < order.length; ix++) {
          columns.add(unchangedColumns.get(order[ix]));
      }
   }
}

On top, here are some methods for persisting the table sort order:

private void saveSortOrder(ArrayList<String> sortCols, ArrayList<String> sortDirs) {
    sortCols = new ArrayList<>();
    sortDirs = new ArrayList<>();

    for (TableColumn<MyType, ?> c : getSortOrder()) {
        sortCols.add(c.getText());
        sortDirs.add(c.getSortType().toString());
    }
}

private void applySortOrder(ArrayList<String> sortCols, ArrayList<String> sortDirs) {
    List<TableColumn<MyType, ?>> sortOrder = getSortOrder();
    sortOrder.clear();

    for (int ix = 0; ix < sortCols.length; ix++) {
        for (TableColumn<MyType, ?> c : unchangedColumns) {
            if (c.getText().equals(sortCols[ix])) {
                sortOrder.add(c);
                c.setSortType(TableColumn.SortType.valueOf(sortDirs[ix]));
            }
        }
    }
}
Shel answered 8/9, 2015 at 0:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.