PhilKes
PhilKes

Reputation: 138

JavaFX TableView fill with Buttons of Array

So I am trying to get a TableView to represent rows of seats. So a row represents an Object of class "Reihe" (german "row").A Reihe has an array of Sitzplatz("seat"). Every seat has got a Button which is supposed to be displayed in the seats cell. So I am a bit confused about the cellFactories for the TableColumns. How do I tell the Columns to display the button of a seat from row.seat[columnIdx] ? I cant return an ObservableValue< Button> right? So what am I using as CellFactories?

Class "Reihe"(=row):

public class Reihe implements DataObject
{
  private Sitzplatz[] seats;

 public Reihe(int seats,int saal)
 {
    this.seats=new Sitzplatz[seats];
    for(int i=0; i<this.seats.length; i++)
    {
        this.seats[i]=new Sitzplatz();
        this.seats[i].setSaal_SID(""+saal);
    }
 }

 public Sitzplatz getSeat(int idx)
 {
    return seats[idx];
 }
    ...

Class "Sitzplatz" ("seat"):

 public class Sitzplatz implements DataObject
 {
  private SimpleStringProperty platz, reihe,saal_SID, reservierung_REID;
  private SeatButton button;

  public Sitzplatz()
  {
    this.platz=new SimpleStringProperty();
    this.saal_SID=new SimpleStringProperty();
    this.reihe=new SimpleStringProperty();
    this.reservierung_REID=new SimpleStringProperty();
    button=new SeatButton();
  }

  public SeatButton getButton()
  {
    return button;
  }
    ...

Initialization of Columns:

   for(int j=0; j<seatColumns; j++)
   {
       TableColumn<Reihe,Button> nColumn=new TableColumn<>("Seat"+j);
       //final int idx=j;
       nColumn.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Reihe, Button>, ObservableValue<Button>>() {

            @Override
            public ObservableValue<Button> call(TableColumn.CellDataFeatures<Reihe, Button> p) {
                    // ???
                }
            });
         nColumn.setMinWidth(50);
         nColumn.setEditable(true);
         //getColumns().add(nColumn);
         getColumns().add(nColumn);
        }

I found something about using Button extends TableCell but again I could not really work out how its supposed to work:

public class SeatButton extends TableCell<Reihe, Button>
{
  Button cellButton;
 //private Sitzplatz seat;

 public SeatButton()
 {
    //seat=row.getSeat(column);
    cellButton=new Button();

    cellButton.setMinWidth(30);
    cellButton.setOnAction(new EventHandler<ActionEvent>(){
        @Override
        public void handle(ActionEvent t) {

            //....
        }
    });
 }
}

Upvotes: 0

Views: 287

Answers (1)

fabian
fabian

Reputation: 82451

You shouldn't put GUI elements in the model. In this case it makes even less sense, since SeatButton extends TableCell and TableCell creation is independent of the items. Also items are assigned to TableCells by TableView and the item of a TableCell may be changed/removed.

Use the cellValueFactory to return the Sitzplatz for the given column and use a cellFactory that returns TableCell<Reihe, Sitzplatz>:

for(int j=0; j<seatColumns; j++) {
    final index = j;
    TableColumn<Reihe, Sitzplatz> nColumn = new TableColumn<>("Seat"+j);
    nColumn.setCellValueFactory(p -> new SimpleObjectProperty<>(p.getValue().getSeat(index)));
    nColumn.setCellFactory(c -> new SeatButton<>());
    nColumn.setMinWidth(50);
    nColumn.setEditable(false); // you want to modify items not replace them
    getColumns().add(nColumn);
}
public class SeatButton<T> extends TableCell<T, Sitzplatz> {
    Button cellButton;

    public SeatButton() {
        cellButton=new Button();

        cellButton.setMinWidth(30);
        cellButton.setOnAction(new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent t) {

                //....
            }
        });
    }

    @Override
    protected void updateItem(Sitzplatz item, boolean empty) {
        super.updateItem(item, empty);

        if (empty || item == null) {
            setGraphic(null);
        } else {
            setGraphic(cellButton);
            // TODO: adjust button according to data
        }
    }
}

Upvotes: 1

Related Questions