0

我尝试使用ComboxBoxTableCell没有成功。
单元格的内容显示对象属性的正确值。但是当显示组合框时,所有项目都使用toString对象方法而不是属性显示。
我试图覆盖updateItemComboBoxTableCell提供一个StringConverter但没有任何效果。

您对在表格单元格中自定义组合框列表显示有一些想法吗?

我在下面放了一个简短的例子来快速查看问题。执行应用程序并单击单元格,您将看到包含toString对象值的组合框。

package javafx2;  

import javafx.application.Application;
import javafx.beans.property.adapter.JavaBeanObjectPropertyBuilder;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.ComboBoxTableCell;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.StringConverter;

public class ComboBoxTableCellTest extends Application {

    public class Product {
        private String name;
        public Product(String name) {
            this.name = name;
        }
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }
    }

    public class Command {
        private Integer quantite;
        private Product product;
        public Command(Product product, Integer quantite) {
            this.product = product;
            this.quantite = quantite;
        }
        public Integer getQuantite() { return quantite; }
        public void setQuantite(Integer quantite) { this.quantite = quantite; }
        public Product getProduct() { return product; }
        public void setProduct(Product product) { this.product = product; }
    }

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

    @Override
    public void start(Stage stage) throws Exception {
        Product p1 = new Product("Product 1");
        Product p2 = new Product("Product 2");
        final ObservableList<Product> products  = FXCollections.observableArrayList(p1, p2);
        ObservableList<Command> commands  = FXCollections.observableArrayList(new Command(p1, 20)); 

        TableView<Command> tv = new TableView<Command>();
        tv.setItems(commands);

        TableColumn<Command, Product> tc = new TableColumn<Command, Product>("Product");
        tc.setMinWidth(140);
        tc.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Command,Product>, ObservableValue<Product>>() {

            @Override
            public ObservableValue<Product> call(CellDataFeatures<Command, Product> cdf) {
                try {
                    JavaBeanObjectPropertyBuilder<Product> jbdpb = JavaBeanObjectPropertyBuilder.create();
                    jbdpb.bean(cdf.getValue());
                    jbdpb.name("product");
                    return (ObservableValue) jbdpb.build();
                } catch (NoSuchMethodException e) {
                    System.err.println(e.getMessage());
                }
                return null;
            }
        });
        final StringConverter<Product> converter = new StringConverter<ComboBoxTableCellTest.Product>() {

            @Override
            public String toString(Product p) {
                return p.getName();
            }

            @Override
        public Product fromString(String s) {
                // TODO Auto-generated method stub
                return null;
            }
        };

        tc.setCellFactory(new Callback<TableColumn<Command,Product>, TableCell<Command,Product>>() {

            @Override
            public TableCell<Command, Product> call(TableColumn<Command, Product> tc) {
                return new ComboBoxTableCell<Command, Product>(converter, products) {
                    @Override
                    public void updateItem(Product product, boolean empty) {
                        super.updateItem(product, empty);
                        if (product != null) {
                            setText(product.getName());
                        }
                    }
                };
            }
        });

        tv.getColumns().add(tc);
        tv.setEditable(true);

        Scene scene = new Scene(tv, 140, 200);
        stage.setScene(scene);
        stage.show();
    }
}
4

1 回答 1

4

Desculpe-me Philippe Jean por respondê-lo em português, mas como não domino bem sua língua, achei melhor desta forma。

Encontrei o mesmo problema que o seu e solucionei-o com a seguinte implementação。


我发现了与您相同的问题,并通过以下实现解决了它。

final ObservableList<Product> products  = FXCollections.observableArrayList(p1, p2);
ObservableList<Command> commands  = FXCollections.observableArrayList(new Command(p1, 20));

TableView<Command> tv = new TableView<Command>();
tv.setItems(commands);

/**
 * Substitua as sugestões de tipo Product por String da TableColumn e suas correlacionadas como abaixo
 */
TableColumn<Command, String> tc = new TableColumn<Command, String>("Product");
tc.setMinWidth(140);
tc.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<Command, String>, ObservableValue<String>>(){
    @Override
    public ObservableValue<String> call(CellDataFeatures<Command, String> p) {
        return new SimpleObjectProperty(p.getValue().getProduct().getName());
    }
});
tc.setCellFactory(new Callback<TableColumn<Command, String>, TableCell<Command, String>>() {
    @Override
    public TableCell<Command, String> call(TableColumn<Command, String> p) {
        /**
         * Este Map guardará os objetos Product indexando pelo "name"
         */
        final Map<String, Product> products = new HashMap();
        Iterator<Product> productsi = pojosComboBox.iterator();
        while(productsi.hasNext()) {
            Product product = productsi.next();
            products.put(product.getName(), product);
        }

        ComboBoxTableCell cell = new ComboBoxTableCell(FXCollections.observableArrayList(products.keySet())){
            @Override
            public void updateItem(Object item, boolean empty) {
                super.updateItem(item, empty);
                if(item != null) {
                    /**
                     * Aqui acontece a atualização do objeto Command de acordo com o esperado
                     */
                    tabela.getItems().get(getIndex()).setProduct(products.get(item.toString()));
                }
            }
        };
        cell.setAlignment(Pos.CENTER);
        return cell;
    }
});
于 2012-12-19T13:45:13.450 回答