javajavafx

How to create a column for TableView in JavaFX with leading ellipsis?


I have a column with paths where all paths belong to one root folder. When paths do not fit in the column (they can be rather long and column width is limited) I want to show user only the end of the path with leading ellipsis. For example:

..someverylongdirectoryname/file.txt
..omeverylongdirectoryname/file2.txt

I tried this code, but it didn't work.

public class JavaFxTest extends Application {


    public static class FilePath {
        private final String path;

        public FilePath(String path) {
            this.path = path;
        }

        public String getPath() {
            return path;
        }
    }

    @Override
    public void start(Stage primaryStage) {
        TableView<FilePath> tableView = new TableView<>();

        TableColumn<FilePath, String> pathColumn = new TableColumn<>("Path");
        pathColumn.setCellValueFactory(new PropertyValueFactory<>("path"));
        pathColumn.setPrefWidth(200);

        pathColumn.setCellFactory(column -> new javafx.scene.control.TableCell<>() {
            private final Text text = new Text();

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                if (empty || item == null) {
                    setGraphic(null);
                } else {
                    text.setText(item);
                    text.setStyle("-fx-text-alignment: right;");
                    setGraphic(text);
                }
            }
        });

        tableView.getColumns().add(pathColumn);
        tableView.getItems().addAll(
            new FilePath("/usr/local/bin/someverylongdirectoryname/file.txt"),
            new FilePath("/usr/local/bin/someverylongdirectoryname/file2.txt")
        );

        primaryStage.setScene(new Scene(tableView, 300, 200));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Could anyone say how to do it?


Solution

  • It looks like you are looking to have the text overrun ellipsis at the beginning of the label, instead of the end. Just use the fact that the Cell is a Labeled and set the overrun style:

            pathColumn.setCellFactory(column -> new javafx.scene.control.TableCell<>() {
    
                {
                    setTextOverrun(OverrunStyle.LEADING_ELLIPSIS);
                }
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    setText(item);
                }
            });
    

    Of course, you can also just manually replace the root folder if you prefer:

            String commonPath = "/usr/local/bin/someverylongdirectoryname";
    
            pathColumn.setCellFactory(column -> new javafx.scene.control.TableCell<>() {
    
    
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty || item == null) {
                        setText(null);
                    } else {
                        setText(item.replace(commonPath, "..."));
                    }
                }
            });