Search code examples
javajavafxjava-8tablecolumn

javafx tablecolumn cell change


I am looking to set the cell column to receive an object circle in replacement of the value that is coming from a database in an observableList. Values are populated in that column that mirror the other column(lets say col A and B (left to right) - they basically contain the same information except- I wanted col B to change to represent the circle object.Here is my code so far, please advise if you have suggestions.

status.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList, Circle>, ObservableValue<Circle>>() {
    @Override
    public ObservableValue<Circle> call(TableColumn.CellDataFeatures<ObservableList, Circle> param) {


        String c = (String) param.getValue().get(2); //getting all data in column 2 of the row
        System.out.println(c);

        switch(c){

            case "High":        
                circle.setFill(Color.GREEN);
                healthstatus.setStyle( "-fx-alignment: CENTER;");            
                break;

            case "Medium":
                circle.setFill(Color.YELLOW);
                healthstatus.setStyle( "-fx-alignment: CENTER;");           
                break;

            case "Low":
                circle.setFill(Color.RED);
                healthstatus.setStyle( "-fx-alignment: CENTER;");           
                break;

            default:
                circle.setFill(Color.BLUEVIOLET);
            }   
        return new SimpleObjectProperty(circle);                        
    }            
});

I prefer to continue with the code I have without having to create a class in response to setting the value.

I've attached a picture to show my result so far.

thanks in advance! Image


Solution

  • Update

    As @kleopatra pointed out some issues and suggestions from the previous answer, I have updated the answer accordingly.

    CircleCell

    Customized TableCell for Circle rendering

    public class CircleCell extends TableCell<Person, String> {
    
        @Override
        protected void updateItem(String item, boolean empty) {
    
            super.updateItem(item, empty);
    
            if (isSafe(item, empty)) {
                CellData data = CellData.cellData(item);
                Circle circle = new Circle(6);
                circle.setFill(data.getColor());
                setGraphic(circle);
            }
        }
    
        private boolean isSafe(String item, boolean empty) {
            return !empty && Objects.nonNull(item);
        }
    }
    

    CellData

    Holds color based on cell data.

    public enum CellData {
    
        HIGH("High", Color.GREEN),
        MEDIUM("Medium", Color.YELLOW),
        LOW("Low", Color.RED),
        NONE("None", Color.BLUEVIOLET);
    
        private String data;
        private Color color;
    
        CellData(String data, Color color) {
            this.data = data;
            this.color = color;
        }
    
        public static CellData cellData(String data) {
            return Arrays.stream(values())
                        .filter(e -> e.data.equals(data))
                        .findAny()
                        .orElse(NONE);
        }
    
        public Color getColor() {
            return color;
        }
    }
    

    Set Factory

    Set cell-factory with the customized CircleCell.

    status.setCellFactory(column -> new CircleCell());
    

    Simple Demo

    public class CustomCellDemo extends Application {
    
        @Override
        public void start(Stage primaryStage) throws Exception {
            BorderPane root = new BorderPane();
            root.setCenter(getTable());
            primaryStage.setScene(new Scene(root, 200, 200));
            primaryStage.show();
        }
    
        private TableView<Person> getTable() {
            TableView<Person> table = new TableView<>();
            table.getColumns().add(statusColumn());
            table.setItems(getItems());
            return table;
        }
    
        private TableColumn<Person, String> statusColumn() {
            TableColumn<Person, String> status = new TableColumn<>();
            status.setCellFactory(col -> new CircleCell());
            status.setGraphic(new Label("Status"));
            status.setStyle("-fx-alignment:center");
            status.setCellValueFactory(new PropertyValueFactory("Status"));
            status.setMinWidth(199);
            return status;
        }
    
        private ObservableList<Person> getItems() {
            ObservableList<Person> detail = FXCollections.observableArrayList();
            detail.add(new Person("Medium"));
            detail.add(new Person("Low"));
            detail.add(new Person("High"));
            detail.add(new Person(""));
            detail.add(new Person(null));
            return detail;
        }
    
        public class Person {
            private SimpleStringProperty status;
    
            public Person(String status) {
                this.status = new SimpleStringProperty(status);
            }
    
            public String getStatus() {
                return status.get();
            }
    
            public void setStatus(String status) {
                this.status = new SimpleStringProperty(status);
            }
        }
    }
    

    Output

    enter image description here