【问题标题】:JavaFX TableView fill with Buttons of ArrayJavaFX TableView 填充数组的按钮
【发布时间】:2018-10-20 18:10:39
【问题描述】:

所以我试图让一个 TableView 来代表一排座位。因此,一行代表“Reihe”类的对象(德语“row”)。Reihe 有一个 Sitzplatz(“seat”)数组。每个座位都有一个按钮,应该显示在座位单元格中。 所以我对 TableColumns 的 cellFactories 有点困惑。如何告诉列显示来自 row.seat[columnIdx] 的座位按钮? 我不能返回 ObservableValue 对吗?那么我用什么作为 CellFactories 呢?

类“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];
 }
    ...

类“Sitzplatz”(“座位”):

 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;
  }
    ...

列的初始化:

   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);
        }

我发现了一些关于使用 Button extends TableCell 的信息,但我还是无法真正弄清楚它应该如何工作:

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) {

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

【问题讨论】:

  • 这可能超出了您的需要,但它应该让您朝着正确的方向前进。 stackoverflow.com/questions/17067481/…
  • 我建议您将自己的代码限制为 1 种语言。您似乎还没有决定要使用德语还是英语。 (我推荐使用英文,因为这样你会与 API 保持一致。)
  • 我知道有人会这么说,我自己也知道因为这主要是为了用“德语”SQL 数据库测试 JavaFX+JDBC,所以语言有点混乱

标签: button javafx tableview tablecolumn


【解决方案1】:

您不应该将 GUI 元素放入模型中。在这种情况下,它的意义就更小了,因为 SeatButton 扩展了 TableCell 和 TableCell 创建独立于项目。此外,items 由TableView 分配给TableCells,TableCell 的项目可以更改/删除。

使用cellValueFactory 为给定列返回Sitzplatz,并使用返回TableCell&lt;Reihe, Sitzplatz&gt; 的cellFactory:

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
        }
    }
}

【讨论】:

  • 非常感谢您的帮助
  • 还有一件事所以 SeatButton 只能通过 TableView 和 getItem() 知道它的 Sitzplatz,但是什么时候初始化呢?我可以在 SeatButton 的构造函数中访问 Sitzplatz 的 SeatButton 吗?
  • @PhilKey 没有。只要不调用updateItem,就将单元格视为空。可以为单元格分配一个新项目,并且单元格在被填充后可能会变为空。 (确保将updateItem 方法中的节点创建减少到最低限度。)。您的代码不应依赖于更新发生的时间。它在布局过程中完成,并且可能由于滚动等而再次完成。
猜你喜欢
  • 2014-10-08
  • 2018-10-14
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多