0

I didn't find the question where I got an answer for fixing the columns in a tableView/treeTableView.

I would like to do the same for the rows in the table, but applying the same idea I could't manage to achieve anything.

For the columns the idea was to fix the cells' X position to scrolling.

So I tried the same thing with the rows, but instead fixing their Y position to vertical scrolling, but it seems nothing happened.

Here is the code you can check:

Controller.java:

public class Controller implements Initializable {

    @FXML
    private TreeTableView<Model> table;
    @FXML
    private TreeTableColumn<Model, String> col;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        col.setCellValueFactory(data -> data.getValue().getValue().text);

        setup();
        table.skinProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                TreeTableRow<Model> firstRow = (TreeTableRow<Model>) table
                        .queryAccessibleAttribute(AccessibleAttribute.ROW_AT_INDEX, 0);
                ScrollBar scrollBar = (ScrollBar) table
                        .queryAccessibleAttribute(AccessibleAttribute.VERTICAL_SCROLLBAR);
                scrollBar.valueProperty().addListener((obs, oV, nV) -> {
                    firstRow.toFront();
                    System.out.println("norm: " + nV); // debug
                    double value = convert(nV.doubleValue(), 0, table.getHeight()) / 2;
                    System.out.println("non-norm: " + value); // debug
                    firstRow.setTranslateY(value);
                });
            }
        });

    }

    private void setup() {
        table.setShowRoot(false);
        table.setRoot(new TreeItem<>());

        Model r1 = new Model("A");
        Model r2 = new Model("B");

        Model r11 = new Model("A1");

        Model l1 = new Model("Ba");
        Model l2 = new Model("Bb");

        TreeItem<Model> ti = new TreeItem<>(r2);

        ti.getChildren().add(new TreeItem<>(l1));
        ti.getChildren().add(new TreeItem<>(l2));

        table.getRoot().getChildren().add(new TreeItem<>(r11));
        table.getRoot().getChildren().add(ti);
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
        table.getRoot().getChildren().add(new TreeItem<>(r1));
    }

    private double convert(double val, double min, double max) {
        return val * (max - min) + min;
    }

    public static class Model {

        private StringProperty text;

        public Model(String text) {
            this.text = new SimpleStringProperty(text);
        }

        public StringProperty textProperty() {
            return text;
        }
    }

}

View.fxml:

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

<?import javafx.scene.control.TreeTableColumn?>
<?import javafx.scene.control.TreeTableView?>
<?import javafx.scene.layout.StackPane?>
<StackPane xmlns="http://javafx.com/javafx"
           xmlns:fx="http://javafx.com/fxml"
           fx:controller="stackoverflow.fixrow.Controller">

    <TreeTableView fx:id="table">
        <columns>
            <TreeTableColumn fx:id="col" prefWidth="200"/>
        </columns>
    </TreeTableView>
</StackPane>

After debugging a while I figured out that the vertical scroll's values differ from the horizontal ones. The vertical scroll has normalized values, so I tought ohh that was the problem I was trying to work with normalized values that's why its not working, but after converting it back to real values It seems the same happens, so nothing.

Any idea what did I miss, or why isn't working the same idea like at the columns?

Of course I would appreciate any other working solution.

Note: Here I have a TreeTableView, because at the moment I need it for that, but I think the same solution can be applied for both TV and TTV

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Sunflame
  • 2,993
  • 4
  • 24
  • 48
  • You cannot use (Tree)`TableRow` for this purpose, since the skin of the (Tree)`TableView` is managing the row lifecycle and will reuse the rows. Even if you manage to get hold on the row cell for row 0, after some scrolling the item set for this row may be the one at index 30 and there may not be a row for the first item anymore. also the positioning of the position of the rows is an implementation detail of the skin. If you mess around with this, you may get different effects for different JavaFX versions/skins, since there are multiple ways of positioning the rows appropriately... – fabian Jan 28 '19 at 14:01
  • Ohh, that sounds bad, I didn't even think about the cell/row recycling. Then you say that it is impossible to achieve this functionality? – Sunflame Jan 28 '19 at 14:10
  • You may have better luck placing some nodes on top of the `TableView` "immitating" cells. You need to make sure those cells are propely aligned/cliped though and the overlay does not block mouse events for the `TableView`. It may be simpler, maybe it's simpler to do this extending `TableViewSkin`, but this would require you to write different code for JavaFX 8 and JavaFX 9+. (Haven't extended the skin myself yet...) – fabian Jan 28 '19 at 14:32

0 Answers0