Javafx 自定义Java fx cellfactory会弄乱setCellValueFactory

Javafx 自定义Java fx cellfactory会弄乱setCellValueFactory,javafx,tableview,cell,double-click,Javafx,Tableview,Cell,Double Click,在与Netbeans和Scenebuilder混了一段时间之后,我陷入了一个我不太理解的问题。我使用自定义的cellfactory将双击事件绑定到我的tableview中的单元格。但是,当我设置cellfactory和cellValueFactory时,只有自定义cellfactory具有效果 我试图用大量对象的数据填充tableview,并将双击事件绑定到第一列的单元格。人口不是问题,我只是用了 idNumber.setCellValueFactory(new PropertyValueFac

在与Netbeans和Scenebuilder混了一段时间之后,我陷入了一个我不太理解的问题。我使用自定义的
cellfactory
将双击事件绑定到我的tableview中的单元格。但是,当我设置cellfactory和cellValueFactory时,只有自定义cellfactory具有效果

我试图用大量对象的数据填充tableview,并将双击事件绑定到第一列的单元格。人口不是问题,我只是用了

idNumber.setCellValueFactory(new PropertyValueFactory<LiveStock, String>("idNumber"));
status.setCellValueFactory(new PropertyValueFactory<LiveStock, String>("status"));
这会导致我的单元格变空,但具有双击绑定

有什么想法吗

我的家畜课是这样的:

Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>> cellFactory =
    new Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>>() {
        @Override
        public TableCell call(TableColumn p) {
            TableCell cell = new TableCell<LiveStock, String>() {};

            cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getClickCount() == 2) {
                        System.out.println("double clicked!");
                        TableCell c = (TableCell) event.getSource();
                        System.out.println("Livestock ID: " + c.getId());
                    }
                }
            });

            return cell;
        }
package projekt1.fx;

import javafx.beans.property.SimpleStringProperty;

public class LiveStock {
    private final int idNumber;
    private final SimpleStringProperty ownerID;
    private SimpleStringProperty status;
    private double lat;
    private double longd;


    public LiveStock(int idNumber, String ownerID) {
        this.idNumber = idNumber;
        this.ownerID = new SimpleStringProperty(ownerID);
        this.status = new SimpleStringProperty("ok");
    }

    public int getIdNumber() {
        return this.idNumber;
    }

//    public void setIdNumber(int number) {
//        this.idNumber = number;
//    }

    public String getOwnerID(){
        return ownerID.get();
    }

    public void setOwnerID(String id){
        ownerID.set(id);
    }

    public String getStatus(){
        return status.get();
    }

    public void setStatus(String st){
        status.set(st);
    } 
}
    Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>> cellFactory =
        new Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>>() {
            @Override
            public TableCell call(TableColumn p) {
                TableCell cell = new TableCell<LiveStock, String>() {
                    @Override
                    public void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
//                        setText("HELLO WORLD!");
                        setText(empty ? null : getString());
                    }
                };

                cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        if (event.getClickCount() == 2) {
                            System.out.println("double clicked!");
                            TableCell c = (TableCell) event.getSource();
                            System.out.println("Livestock ID: " + c.getId());
                            togglePopup(null);
                        }
                    }
                });

                return cell;
            }
        };

cellfactory现在看起来像这样:

Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>> cellFactory =
    new Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>>() {
        @Override
        public TableCell call(TableColumn p) {
            TableCell cell = new TableCell<LiveStock, String>() {};

            cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    if (event.getClickCount() == 2) {
                        System.out.println("double clicked!");
                        TableCell c = (TableCell) event.getSource();
                        System.out.println("Livestock ID: " + c.getId());
                    }
                }
            });

            return cell;
        }
package projekt1.fx;

import javafx.beans.property.SimpleStringProperty;

public class LiveStock {
    private final int idNumber;
    private final SimpleStringProperty ownerID;
    private SimpleStringProperty status;
    private double lat;
    private double longd;


    public LiveStock(int idNumber, String ownerID) {
        this.idNumber = idNumber;
        this.ownerID = new SimpleStringProperty(ownerID);
        this.status = new SimpleStringProperty("ok");
    }

    public int getIdNumber() {
        return this.idNumber;
    }

//    public void setIdNumber(int number) {
//        this.idNumber = number;
//    }

    public String getOwnerID(){
        return ownerID.get();
    }

    public void setOwnerID(String id){
        ownerID.set(id);
    }

    public String getStatus(){
        return status.get();
    }

    public void setStatus(String st){
        status.set(st);
    } 
}
    Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>> cellFactory =
        new Callback<TableColumn<LiveStock, String>, TableCell<LiveStock, String>>() {
            @Override
            public TableCell call(TableColumn p) {
                TableCell cell = new TableCell<LiveStock, String>() {
                    @Override
                    public void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
//                        setText("HELLO WORLD!");
                        setText(empty ? null : getString());
                    }
                };

                cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent event) {
                        if (event.getClickCount() == 2) {
                            System.out.println("double clicked!");
                            TableCell c = (TableCell) event.getSource();
                            System.out.println("Livestock ID: " + c.getId());
                            togglePopup(null);
                        }
                    }
                });

                return cell;
            }
        };
回调单元工厂=
新回调函数(){
@凌驾
公共TableCell调用(TableP列){
TableCell单元格=新的TableCell(){
@凌驾
public void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
//setText(“你好,世界!”);
setText(空?null:getString());
}
};
cell.addEventFilter(MouseEvent.MOUSE_单击,新建EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
if(event.getClickCount()==2){
System.out.println(“双击!”);
TableCell c=(TableCell)事件.getSource();
System.out.println(“牲畜ID:+c.getId());
切换弹出窗口(空);
}
}
});
返回单元;
}
};
的文档说明:

因为到目前为止,单元格最常见的用例是向 用户,这个用例是专门为单元内部优化的。这是 由标记为的细胞延伸而成。这意味着 单元格只需设置文本属性,而不需要创建单独的 在单元格中标记并设置它

当前设置将文本设置为空:

public Cell() {
    setText(null);
    ...
}
子类
IndexedCell
和子类
TableCell
,它们都没有设置标记为
文本
文本在源代码中默认设置为
TableColumn
的单元格工厂

public static final Callback<TableColumn<?,?>, TableCell<?,?>> DEFAULT_CELL_FACTORY = new Callback<TableColumn<?,?>, TableCell<?,?>>() {
    @Override public TableCell<?,?> call(TableColumn<?,?> param) {
        return new TableCell() {
            @Override protected void updateItem(Object item, boolean empty) {
                if (item == getItem()) return;

                super.updateItem(item, empty);

                if (item == null) {
                    super.setText(null);
                    super.setGraphic(null);
                } else if (item instanceof Node) {
                    super.setText(null);
                    super.setGraphic((Node)item);
                } else {
                    super.setText(item.toString());
                    super.setGraphic(null);
                }
            }
        };
    }
};
这将避免类型不匹配或错误的类型铸件。
然后,您的用例的单元工厂回调将是

Callback<TableColumn<LiveStock, Integer>, TableCell<LiveStock, Integer>> cellFactory =
        new Callback<TableColumn<LiveStock, Integer>, TableCell<LiveStock, Integer>>() {
    public TableCell<LiveStock, Integer> call(TableColumn<LiveStock, Integer> p) {
        TableCell<LiveStock, Integer> cell = new TableCell<LiveStock, Integer>() {

            @Override
            public void updateItem(Integer item, boolean empty) {
                super.updateItem(item, empty);
                setText((item == null || empty) ? null : item.toString());
                setGraphic(null);
            }
        };

        cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if (event.getClickCount() > 1) {
                    System.out.println("double clicked!");
                    TableCell c = (TableCell) event.getSource();
                    System.out.println("Cell text: " + c.getText());
                }
            }
        });
        return cell;
    }
};
回调单元工厂=
新回调函数(){
公共TableCell调用(TableP列){
TableCell单元格=新的TableCell(){
@凌驾
public void updateItem(整数项,布尔空){
super.updateItem(项,空);
setText((item==null | | empty)?null:item.toString();
设置图形(空);
}
};
cell.addEventFilter(MouseEvent.MOUSE_单击,新建EventHandler()){
@凌驾
公共无效句柄(MouseeEvent事件){
如果(event.getClickCount()>1){
System.out.println(“双击!”);
TableCell c=(TableCell)事件.getSource();
System.out.println(“单元格文本:+c.getText());
}
}
});
返回单元;
}
};
发生了什么变化?
牲畜的idNumber类型为
int
。通过定义
newtablecolumn
我们说这是一个来自牲畜行的列,其属性idNumber具有类型int,但泛型类型必须是引用类型,不能是
TableCell
,因此我们定义
TableCell
。经验法则:行项目类的属性类型应该匹配TableColumn的第二个泛型类型参数,因此TableCell的参数也应该匹配


getString方法是在您提到的参考答案链接中定义的。但它只是一个用户定义的方法,不是必须使用的。

也发布您的牲畜类。它有idNumber的访问器吗?非常好的解释。好的,谢谢。现在我明白了这个问题,但不知道如何解决它。我已经将一个
updateItem
方法添加到
cellFactory
中,但是如果我只是从[link]复制这个方法,我就找不到符号了。符号:方法getString()。如果我在
setText
中添加一个静态字符串,它就会工作。那么,我如何告诉
setText
方法获取每个
avests
对象的
IdNumber
。我尝试了提供的
setTest
方法,但我的单元格中仍然没有文本。我在想,
updateItem
中的
item
参数如何知道应该从牲畜对象中的哪个变量获取字符串?它是通过:
idNumber.setCellValueFactory(newPropertyValueFactory(“idNumber”))获得的但我指定了“idNumber”。我使用:
TableCell cell=new TableCell
与定制cellFactory中的牲畜建立连接,但从未连接到IdNumber字段。再次,您好。我已经离开一段时间了。我填充了单元格,它们有双击功能。耶!但我从来没有让它只与定制细胞工厂。我最终得到了定制的和
idNumber.setCellValueFactory(新的PropertyValueFactory(“idNumber”)非常感谢您的帮助!