Search code examples
javafxalignmenttableviewcell

JavaFX: Different types of alignment in one column of TableView


Is it possible to do different types of alignment for each cell in one column of TableView?

E.g. I have a column with 3 possible types of data inside: positive number, negative number and "-". First should be aligned left, second - right and 3rd - center.

This is what I've tried:

private void setPositionAndColor(TableColumn<TransferItem, String> tableColumn){
    tableColumn.setCellFactory(new Callback<TableColumn<TransferItem, String>, TableCell<TransferItem, String>>() {
        @Override
        public TableCell<TransferItem, String> call(TableColumn<TransferItem, String> column) {
            TableCell<TransferItem, String> cell = new TableCell<TransferItem, String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);

                    if (item == null || empty) {
                        setText("");
                    } else {
                        setText(item);
                        if (item.matches("-+\\d.*")) {
                            setTextFill(Color.RED);
                            setTextAlignment(TextAlignment.RIGHT);
                        }
                        else if (item.equals("-")) {
                            setTextFill(Color.AQUA);
                            setTextAlignment(TextAlignment.CENTER);
                        }else {
                            setTextFill(Color.GREEN);
                            setTextAlignment(TextAlignment.LEFT);
                        }
                    }
                }
            };
            return cell;
        }
    });
}

I added color changes just for testing and it works, but alignment doesn't.

Another approach:

Pos position;
private void setPositionAndColor(TableColumn<TransferItem, String> tableColumn){
    tableColumn.setCellFactory(new Callback<TableColumn<TransferItem, String>, TableCell<TransferItem, String>>() {
        @Override
        public TableCell<TransferItem, String> call(TableColumn<TransferItem, String> column) {
            TableCell<TransferItem, String> cell = new TableCell<TransferItem, String>() {
                @Override
                protected void updateItem(String item, boolean empty) {
                    super.updateItem(item, empty);

                    if (item == null || empty) {
                        setText("");
                    } else {
                        setText(item);
                        if (item.matches("-+\\d.*")) {
                            setTextFill(Color.RED);
                            position = Pos.CENTER_RIGHT;
                        }
                        else if (item.equals("-")) {
                            setTextFill(Color.AQUA);
                            position = Pos.CENTER;
                        }else {
                            setTextFill(Color.GREEN);
                            position = Pos.CENTER_LEFT;
                        }
                    }
                }
            };
            cell.setAlignment(position);
            return cell;
        }
    });
}

Doesn't work either. Ty for help.


Solution

  • Ok, I got a working example - It seems, setAlignment() does the trick:

    @Override
    public void start(Stage primaryStage) {
    
        ObservableList<String> data = FXCollections.observableArrayList();
        IntStream.range(0, 1000).mapToObj(Integer::toString).forEach(data::add);
    
        TableView<String> table = new TableView<String>(data);
    
        TableColumn<String, String> column = new TableColumn<String, String>("test");
        column.setCellFactory(c -> new TableCell<String,String>(){
    
            @Override
            protected void updateItem(String item, boolean empty) {
                if(empty) {
                    setText(null);
                }
                else {
                    setText(item);
                    if(getIndex() % 2 == 0) {
                        setAlignment(Pos.CENTER_LEFT);
                    }
                    else if(getIndex() % 3 == 0) {
                        setAlignment(Pos.CENTER_RIGHT);
                    }
                    else {
                        setAlignment(Pos.CENTER);
                    }
                }
            }
        });
        column.setCellValueFactory(c -> new SimpleStringProperty(c.getValue()));
        table.getColumns().add(column);
    
        Scene scene = new Scene(new BorderPane(table), 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }