java - 将 Button 添加到 TableView 并将 Button 的 textProperty 绑定(bind)到 TableView 对象的属性

标签 java javafx javafx-2 tableview

我有一个在 TableView 中表示的 Order 对象。 其中一列应包含一个按钮。 按钮的文本属性应绑定(bind)到 Order 对象上的 String 属性。

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

如何将 Button 的 text 属性绑定(bind)到 Order 对象的 string 属性?

订单对象:

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

订单管理器:

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

Controller :

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 (需要将操作字段设置为单元格值)

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

最佳答案

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

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

关于java - 将 Button 添加到 TableView 并将 Button 的 textProperty 绑定(bind)到 TableView 对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21072909/

相关文章:

java - 如何根据鼠标坐标(JavaFX)沿着围绕固定中心的圆形轨道定位节点?

java - 在 jnlp 文件上传递参数

javafx-2 - JavaFX 2 动态点加载

java - 调整 GridPane 节点的大小

java - 计算矩阵中非直连节点之间的距离

java - 将 Spring REST 服务与 Wicket 结合起来

java - 将jhipster后端和前端分离成两个项目?

java - 使用 java 和 activemq-all 库进行 STOMP 心跳跟踪

events - JavaFx 按钮事件冒泡

java - 将 javafx 打包器用于非 JavaFX 应用程序