将Button添加到TableView并将Button的textProperty绑定到TableView对象的属性

时间:2014-01-12 08:52:47

标签: java javafx javafx-2 tableview

我有一个我在TableView中表示的Order对象。 其中一列应包含一个Button。 Button的text属性应绑定到Order对象上的String属性。

我用这篇文章作为起点: http://java-buddy.blogspot.ru/2013/03/javafx-embed-button-in-tableview.html

如何将Button的text属性绑定到Order对象的字符串属性?

订单对象:

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Order {

    private String id;
    private StringProperty action = new SimpleStringProperty("CANCEL"); // initial value, to be changed later 

    public String getAction() {
        return action.get();
    }

    public StringProperty actionProperty() {
        return action;
    }

    public void setAction(String action) {
        this.action.set(action);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

的OrderManager:

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class OrdersManager {

    private Map<String, Order> orders = new ConcurrentHashMap<>();
    private ObservableList<Order> ordersView = FXCollections.observableArrayList(orders.values());

    public ObservableList<Order> getOrdersView() {
        return ordersView;
    }

    // other code below...
}

控制器:

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.util.Callback;

public class Controller {

    @FXML
    private TableView<Order> ordersView;

    private OrdersManager ordersManager;

    public void initController() {

        // other code above...

        // init orders view table
        initOrdersViewTable();
    }

    private void initOrdersViewTable() {

        // create other columns. Removed as not important

        //Insert Button
        TableColumn<Order, String> actionCol = new TableColumn<>("Action");
        actionCol.setSortable(false);

        actionCol.setCellValueFactory(
                new Callback<TableColumn.CellDataFeatures<Order, String>, ObservableValue<String>>() {

                    @Override
                    public ObservableValue<String> call(TableColumn.CellDataFeatures<Order, String> p) {
                        return new SimpleStringProperty(p.getValue().getId()); //order.id is used as cell value
                    }
                });

        actionCol.setCellFactory(
                new Callback<TableColumn<Order, String>, TableCell<Order, String>>() {

                    @Override
                    public TableCell<Order, String> call(TableColumn<Order, String> p) {
                        ButtonCell buttonCell = new ButtonCell();

                        // HOW TO BIND TO Order.action stringProperty ???
                        //buttonCell.textProperty().bind(???);

                        return buttonCell;
                    }

                });

        ordersView.setItems(ordersManager.getOrdersView());
        ordersView.getColumns().addAll(actionCol);
    }

    //Define the button cell
    private class ButtonCell extends TableCell<Order, String> {
        final Button cellButton = new Button();

        ButtonCell(){
            cellButton.setOnAction(new EventHandler<ActionEvent>(){
                @Override
                public void handle(ActionEvent t) {
                    String id = getItem(); // it will be order.id
                    String action = cellButton.getText(); // it's actually will be order.action field

                    // orderManager.doSomethingWithIdandAction
                }
            });
        }

        //Display button if the row is not empty
        @Override
        protected void updateItem(String t, boolean empty) {
            super.updateItem(t, empty);
            if (!empty) {
                setGraphic(cellButton);
            }
        }
    }

    public void setOrdersManager(OrdersManager ordersManager) {
        this.ordersManager = ordersManager;
    }
}
James_D回答后


更新
有人建议将其放入ButtonCell构造函数中:

cellButton.textProperty().bind(itemProperty());

itemProperty()返回与单元格关联的值,以便使解决方案工作我必须修改CellValueFactory(需要将action字段设置为单元格值)

actionCol.setCellValueFactory(
        new Callback<TableColumn.CellDataFeatures<Order, String>, ObservableValue<String>>() {

            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<Order, String> p) {
                return p.getValue().actionProperty();
            }
        });

下一步需要更改是更新按钮的句柄方法。所以现在是:

    cellButton.setOnAction(new EventHandler<ActionEvent>(){
        @Override
        public void handle(ActionEvent t) {
            String id = ((Order) getTableRow().getItem()).getId(); // it will be order.id
            String action = getItem(); // it's actually will be order.action field

            // orderManager.doSomethingWithIdandAction
        }
    });

1 个答案:

答案 0 :(得分:1)

在ButtonCell构造函数中,只需执行

cellButton.textProperty().bind(itemProperty());