0

I have a tableview table populated with an observable list in JavaFX and I need a column that would hold a radio button or checkbox for every item, so that if multiple ones are selected they can be used for the next GUI screen list. I've never used TableView/JavaFX before this project, and while I know how to implement the button/checkbox I have no idea how do put it into my list or tableColumn. ANy help is much appreciated.

 @FXML private TableView<SummerClass> table;

        @FXML private TableColumn<SummerClass, Integer> id;
        @FXML private TableColumn<SummerClass, String> dept;
        @FXML private TableColumn<SummerClass,Integer> number;
        @FXML private TableColumn<SummerClass, String> title;
        @FXML private TableColumn<SummerClass, String> day;
        @FXML private TableColumn<SummerClass, String> time;

public ObservableList<SummerClass> list1 =        FXCollections.observableArrayList(
        new SummerClass (10001, "ACCT", 1010 , "Intro to Acct (3)", "MWF",   "1:00 - 2:15" ),
        new SummerClass (10002, "ACCT", 2010 , "Acct for Bus. (3)", "MWF", "9:00 - 10:15" ),
        new SummerClass (10003, "ART", 1010 , "Fund. of Art (3)", "TR", "3:00 - 4:15" ),
        new SummerClass (10004, "ART", 1110 , "Art History (3)", "MWF", "1:00 - 2:15" ),
Hunter Noman
  • 1
  • 1
  • 7
  • 1
    If you're using the check box just to track a set of selected rows, you could just use the table view's built-in selection functionality instead of having a check box at all. – James_D Apr 20 '16 at 01:22

2 Answers2

1

As James_D states in comments:

If you're using the check box just to track a set of selected rows, you could just use the table view's built-in selection functionality instead of having a check box at all.


However, if the built-in selection functionality is not appropriate for you and you do need checkbox functionality, then you either:

  1. Set a custom cell factory on a column, and override updateItem as in Ruslan's answer OR
  2. Use the built-in CheckBoxTableCell functionality.

Of the two options, I'd advise using the CheckBoxTableCell instead of creating a custom cell factory and update handler (unless, for some some reason, CheckBoxTableCell won't work for you).

There are various existing StackOverflow questions or Oracle forum questions asking how to use CheckBoxTableCell if you need more information on it:

The key parts of using a CheckBoxTableCell are to define a related boolean property in the model class that is backing your table and to link it to the relevant editable table column:

vegetarianCol.setCellValueFactory(new PropertyValueFactory<>("vegetarian"));
vegetarianCol.setCellFactory(CheckBoxTableCell.forTableColumn(vegetarianCol));
vegetarianCol.setEditable(true);

I have just copy and pasted the James_D's solution from the Oracle forum link below (this is older code, newer code should not use PropertyValueFactory):

import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class CheckBoxTableCellTest extends Application {
  @Override
  public void start(Stage primaryStage) {
    final TableView<Person> tableView = new TableView<>();
    tableView.setItems(FXCollections.observableArrayList(
        new Person("Robert", "Plant"), 
        new Person("Neil", "Young"), 
        new Person("Willie", "Nelson"),
        new Person("Natalie", "Merchant")
    ));
    tableView.getItems().get(3).setVegetarian(true);
    final TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
    final TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
    final TableColumn<Person, Boolean> vegetarianCol = new TableColumn<>("Vegetarian");
    tableView.getColumns().addAll(firstNameCol, lastNameCol, vegetarianCol);
    firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
    lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
    vegetarianCol.setCellValueFactory(new PropertyValueFactory<>("vegetarian"));
    vegetarianCol.setCellFactory(CheckBoxTableCell.forTableColumn(vegetarianCol));
    vegetarianCol.setEditable(true);
    tableView.setEditable(true);

    final BorderPane root = new BorderPane();
    root.setCenter(tableView);

    final HBox controls = new HBox(5);
    final Button infoButton = new Button("Show details");
    infoButton.setOnAction(event -> {
      for (Person p : tableView.getItems())
        System.out.printf("%s %s (%svegetarian)%n", p.getFirstName(),
            p.getLastName(), p.isVegetarian() ? "" : "not ");
      System.out.println();
    });
    controls.getChildren().add(infoButton);
    root.setBottom(controls);

    Scene scene = new Scene(root, 300, 400);
    primaryStage.setScene(scene);
    primaryStage.show();
  }

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

  public static class Person {
    private StringProperty firstName;
    private StringProperty lastName;
    private BooleanProperty vegetarian;

    public Person(String firstName, String lastName) {
      this.firstName = new SimpleStringProperty(firstName);
      this.lastName = new SimpleStringProperty(lastName);
      this.vegetarian = new SimpleBooleanProperty(false);
    }

    public String getFirstName() {
      return firstName.get();
    }

    public String getLastName() {
      return lastName.get();
    }

    public boolean isVegetarian() {
      return vegetarian.get();
    }

    public void setFirstName(String firstName) {
      this.firstName.set(firstName);
    }

    public void setLastName(String lastName) {
      this.lastName.set(lastName);
    }

    public void setVegetarian(boolean vegetarian) {
      this.vegetarian.set(vegetarian);
    }

    public StringProperty firstNameProperty() {
      return firstName;
    }

    public StringProperty lastNameProperty() {
      return lastName;
    }

    public BooleanProperty vegetarianProperty() {
      return vegetarian;
    }
  }
}
jewelsea
  • 150,031
  • 14
  • 366
  • 406
0

In order to become it you need to override "updateItem" method for Cell, where you want to put you RadioButton or something else. Something like

    @Override
    public void updateItem(Number item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setGraphic(null);
        } else {
            setGraphic(***YourNode!***);
        }

Here is a sample with buttons, added to TableView, which you could use to see how it works: http://java-buddy.blogspot.de/2013/03/javafx-embed-button-in-tableview.html

Ruslan Gabbazov
  • 732
  • 7
  • 21