Tableview 获取表格单元格的图形

Tableview 获取表格单元格的图形,tableview,javafx-8,tablecell,tablecolumn,Tableview,Javafx 8,Tablecell,Tablecolumn,我实现了一个自定义的TableCell&TableColumn,在单元格未编辑时显示超链接。我想为超链接添加setOnAction事件。因为我想重用TableCell,所以无法在TableCell updateItem方法中添加代码。有什么方法可以实现这一点吗 public class TableColumnHyperlink<S> extends TableColumn<S, String> { public TableColumnHyperlink (Str

我实现了一个自定义的TableCell&TableColumn,在单元格未编辑时显示超链接。我想为超链接添加setOnAction事件。因为我想重用TableCell,所以无法在TableCell updateItem方法中添加代码。有什么方法可以实现这一点吗

public class TableColumnHyperlink<S> extends TableColumn<S, String> {

    public TableColumnHyperlink (String header) {
        super(header);
        Callback<TableColumn<S, String>, TableCell<S, String>> hypCellFactory =
            (TableColumn<S, String> p) -> new TableCellHyperlink();

        setCellFactory(hypCellFactory);
    }
}
公共类TableColumnHyperlink扩展了TableColumn{
公共表列超链接(字符串标题){
超级(标题);
回叫工厂=
(TableColumn p)->新建TableCellHyperlink();
赛赛尔工厂(hypCellFactory);
}
}
TableCell的实现是

public class TableCellHyperlink<S> extends TableCell<S, String> {

    private final TextField textField;
    private final Hyperlink hyperlink;

    public TableCellHyperlink() {

        textField = new TextField();
        hyperlink = new Hyperlink();
        setAlignment(Pos.CENTER_LEFT);
    }

    @Override
    public void startEdit() {
        super.startEdit();
        createTextField();
        setText(null);
        setGraphic(textField);
        textField.requestFocus();
    }

    @Override
    public void cancelEdit() {
        super.cancelEdit();
        setText(getItem());
        setGraphic(null);
    }

    @Override
    public void updateItem(String item, boolean empty) {
        super.updateItem(item, empty && (getTableRow() == null ? true : getTableRow().isEmpty()));
        if (empty) {
            setText(null);
            setGraphic(null);
        } else {
            if(isEditing()) {
                setText(getString());
                setGraphic(textField);
            } else {
                setText(null);
                hyperlink.setText(getString());
                setGraphic(hyperlink);
            }
        }
    }


    private void createTextField() {
        textField.setText(getString());
        textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);

        textField.addEventFilter(KeyEvent.KEY_PRESSED, (KeyEvent t) -> {
            if (t.getCode() == KeyCode.ENTER) {
                commitEdit(textField.getText());
            } else if (t.getCode() == KeyCode.ESCAPE) {
                cancelEdit();
            }
        });
    }

    private String getString() {
        return (getItem() != null)?getItem():"";
    }
}
公共类TableCell超链接扩展TableCell{
私有最终文本字段文本字段;
私人最终超链接;
公共表格超级链接(){
textField=新的textField();
hyperlink=新建超链接();
设置对齐(位置中心左);
}
@凌驾
公开作废已启动IT(){
super.startEdit();
createTextField();
setText(空);
设置图形(文本字段);
textField.requestFocus();
}
@凌驾
公共作废取消编辑(){
super.cancelEdit();
setText(getItem());
设置图形(空);
}
@凌驾
public void updateItem(字符串项,布尔值为空){
super.updateItem(item,empty&(getTableRow()==null?true:getTableRow().isEmpty());
if(空){
setText(空);
设置图形(空);
}否则{
if(isEditing()){
setText(getString());
设置图形(文本字段);
}否则{
setText(空);
setText(getString());
设置图形(超链接);
}
}
}
私有void createTextField(){
setText(getString());
textField.setMinWidth(this.getWidth()-this.getGraphicTextGap()*2);
textField.addEventFilter(按下KeyEvent.KEY_)(按键事件t)->{
if(t.getCode()==KeyCode.ENTER){
committedit(textField.getText());
}else if(t.getCode()==KeyCode.ESCAPE){
取消编辑();
}
});
}
私有字符串getString(){
返回(getItem()!=null)?getItem():“”;
}
}

如果事件处理程序的实现因实例而异,则需要将事件处理程序(或函数)传递给构造函数。由于您可能需要访问手机,您可以执行以下操作

public class TableCellHyperlink<S> extends TableCell<S, String> {

    private final TextField textField;
    private final Hyperlink hyperlink;


    public TableCellHyperlink(Consumer<TableCellHyperlink<S> handlerFunction) {

        textField = new TextField();
        hyperlink = new Hyperlink();
        hyperlink.setOnAction(event -> handlerFunction.accept(this));
        setAlignment(Pos.CENTER_LEFT);
    }

    // ...
}
TableCellHyperlink<MyType> hyperlinkCell = new TableCellHyperlink<>(cell -> {
    MyType rowValue = (MyType) cell.getTableRow().getValue(); // getTableRow() returns TableRow, not TableRow<MyType>
    String cellValue = cell.getItem();
    // implement action
});
公共类TableCell超链接扩展TableCell{
私有最终文本字段文本字段;
私人最终超链接;
public TableCellHyperlink(consumerhandlerFunction.accept(this));
设置对齐(位置中心左);
}
// ...
}
现在你可以做一些像

public class TableCellHyperlink<S> extends TableCell<S, String> {

    private final TextField textField;
    private final Hyperlink hyperlink;


    public TableCellHyperlink(Consumer<TableCellHyperlink<S> handlerFunction) {

        textField = new TextField();
        hyperlink = new Hyperlink();
        hyperlink.setOnAction(event -> handlerFunction.accept(this));
        setAlignment(Pos.CENTER_LEFT);
    }

    // ...
}
TableCellHyperlink<MyType> hyperlinkCell = new TableCellHyperlink<>(cell -> {
    MyType rowValue = (MyType) cell.getTableRow().getValue(); // getTableRow() returns TableRow, not TableRow<MyType>
    String cellValue = cell.getItem();
    // implement action
});
TableCellHyperlinkCell=新建TableCellHyperlink(单元格->{
MyType rowValue=(MyType)cell.getTableRow().getValue();//getTableRow()返回TableRow,而不是TableRow
字符串cellValue=cell.getItem();
//实施行动
});

显然,如果愿意,您可以向上移动参数并将其传递到自定义TableColumn构造函数。

不确定问题是什么。您只需执行
hyperlink.setOnAction(事件->…)
表格超级链接
构造函数中。但是我想我忽略了这个问题…?是的,James_D。因为我想在多个TableView中重用TableCellHyperlink,所以每次超链接的行为都会不同。在TableCellHyperlink中设置hyperlink.setOnAction不会使类成为泛型类。