将侦听器和文本格式添加到 TableRow [closed]

Add both listeners and text formatting to TableRow [closed]

提问人:cworner1 提问时间:8/9/2023 最后编辑:0009laHcworner1 更新时间:8/10/2023 访问量:46

问:


这个问题是由一个错别字或一个无法再重现的问题引起的。虽然类似的问题可能在这里成为主题,但这个问题的解决方式不太可能帮助未来的读者。

4个月前关闭。

我有一个扩展的类。具有以下代码中的拖放功能:JobTableTableViewTableView

setRowFactory(tv -> {
    TableRow<Job> row = new TableRow<>();
    row.setOnDragDetected(event -> {
        if (!row.isEmpty()) {
            Dragboard db = row.startDragAndDrop(TransferMode.MOVE);
            ClipboardContent content = new ClipboardContent();
            content.putString(Integer.toString(row.getIndex()));
            db.setContent(content);
        }

        event.consume();
    });

    row.setOnDragOver(event -> {
        Dragboard db = event.getDragboard();
        if (db.hasString()) {
            int draggedIndex = Integer.parseInt(db.getString());
            if (draggedIndex != row.getIndex())
                event.acceptTransferModes(TransferMode.MOVE);
        }

        event.consume();
    });

    row.setOnDragDropped(event -> {
        Dragboard db = event.getDragboard();
        if (db.hasString()) {
            int draggedIndex = Integer.parseInt(db.getString());
            Job draggedItem = getItems().get(draggedIndex);

            int dropIndex = (row.isEmpty()) ? this.getItems().size() : row.getIndex();
                
            reIndexJobs(draggedIndex + 1, dropIndex + 1, draggedItem.getCategoryProperty().getValue());

            event.setDropCompleted(true);
            refreshDataModel();
            getSelectionModel().select(dropIndex);
        }

        event.consume();
    });

    return row;
});

代码工作正常。后来我想添加一些格式,所以我后来写了以下代码:

setRowFactory(tv -> new TableRow<Job>() {
    @Override
    protected void updateItem(Job job, boolean empty) {
        super.updateItem(job, empty);
            
        System.out.println("Checkpoint");
            
        if (job == null)
            setStyle("");
        else if (job.isOnHold())
            setStyle("-fx-background-color: #baffba;");
        else
            setStyle("");
    }
});

这也正常工作。但是,目前我只能选择其中之一。我试图通过扩展在以下声明中声明的内部类来组合这两个功能:setRowFactoryTableRowJobTable

public class CustomTableRow extends TableRow<Job> {
    public CustomTableRow() {
        super();            
        
        setOnDragDetected(event -> {
            if (!isEmpty()) {
                Dragboard db = startDragAndDrop(TransferMode.MOVE);
                ClipboardContent content = new ClipboardContent();
                content.putString(Integer.toString(getIndex()));
                db.setContent(content);
            }

            event.consume();
        });

        setOnDragOver(event -> {
            Dragboard db = event.getDragboard();
            if (db.hasString()) {
                int draggedIndex = Integer.parseInt(db.getString());
                if (draggedIndex != getIndex())
                    event.acceptTransferModes(TransferMode.MOVE);
            }

            event.consume();
        });

        setOnDragDropped(event -> {
            Dragboard db = event.getDragboard();
            if (db.hasString()) {
                int draggedIndex = Integer.parseInt(db.getString());
                Job draggedItem = getItems().get(draggedIndex);

                int dropIndex = (isEmpty()) ? getItems().size() : getIndex();            
                
                reIndexJobs(draggedIndex + 1, dropIndex + 1, 
                        draggedItem.getCategoryProperty().getValue());

                event.setDropCompleted(true);
                refreshDataModel();
                getSelectionModel().select(dropIndex);
            }

            event.consume();
        });
    }
    
    @Override
    protected void updateItem(Job job, boolean empty) {
        super.updateItem(job, empty);

        if (job == null) 
            setStyle("");                        
        else if (job.isOnHold()) 
            setStyle("-fx-background-color: #baffba;");                        
        else 
            setStyle("");
    }
}

然后将行工厂设置为新类:CustomTableRowsetRowFactory(tv -> new CustomTableRow());

格式有效,但我失去了拖放功能。我对函数式编程相当陌生,所以我有点挣扎......

Java JavaFX TableView OnClickListener 工厂

评论

2赞 James_D 8/9/2023
我看不出有什么理由不行。创建并发布一个最小的可重现示例
0赞 James_D 8/9/2023
另请注意,在 JavaFX 20 及更高版本中,您可以使用 实现格式设置,这样可以避免子类化,并且可以与拖放的原始实现相结合。(不过,您建议的方法仍然没有理由不起作用。row.itemProperty().map(Job::onHoldProperty).orElse(false).addListener((obs, wasOnHold, isOnHold) -> row.setStyle(isOnHold ? "-fx-background-color: #baffba;" : ""));TableRow
3赞 James_D 8/9/2023
在没有可重现示例的情况下,我尽我所能对其进行了测试,并且效果很好。如果它不起作用,问题几乎可以肯定出在你没有发布的代码上
2赞 jewelsea 8/9/2023
设置暂停作业样式的更通用解决方案是使用 style 类或 psuedoclass,类似于默认 tableview 行样式设置奇数行和偶数行样式的方式。但这并不是你所拥有的代码的真正问题,所以我不会在这里详细说明它。
1赞 cworner1 8/9/2023
感谢您的回复。我真的不认为我能写出最小的可重现代码,因为我认为潜在的问题是我缺乏对函数、lambda 和 Callbacks 的理解。因为我被告知它应该可以工作,所以我回到了基础,从头开始重写了代码,它确实有效。我还没有真正确定最初的问题是什么。

答: 暂无答案