在我的程序中有一个TableView,我想注册两个不同的行工厂来根据内容格式化我的行。
这是我的工厂:
private void highlightReportRowsIfImportant() {
tv_berichte.setRowFactory(new Callback<TableView<DatabaseReport>, TableRow<DatabaseReport>>() {
@Override
public TableRow<DatabaseReport> call(TableView<DatabaseReport> tableView) {
final TableRow<DatabaseReport> row = new TableRow<DatabaseReport>() {
@Override
protected void updateItem(DatabaseReport report, boolean empty) {
super.updateItem(report, empty);
if (report != null) {
if (report.getReport_art().contains("!!!")) {
setStyle("-fx-background-color: #FF0000;");
} else {
setStyle("");
}
} else {
setStyle("");
}
}
};
reports.addListener(new ListChangeListener<DatabaseReport>() {
@Override
public void onChanged(ListChangeListener.Change<? extends DatabaseReport> change) {
if (row.getItem() != null) {
if (row.getItem().getReport_art().contains("!!!")) {
row.setStyle("-fx-background-color: #FF0000;");
} else {
row.setStyle("");
}
} else {
row.setStyle("");
}
}
});
return row;
}
});
}
这是另一个:
private void registerDragAndDropReportListener(TableView view) {
view.setRowFactory(tv -> {
TableRow<DatabaseReport> row = new TableRow<>();
row.setOnDragDetected(event -> {
if (!row.isEmpty()) {
Dragboard db = row.startDragAndDrop(TransferMode.COPY);
db.setDragView(row.snapshot(null, null));
ClipboardContent cc = new ClipboardContent();
cc.putString(row.getItem().getReport_content());
db.setContent(cc);
event.consume();
}
});
row.setOnDragOver(event -> {
Dragboard db = event.getDragboard();
if (db.hasContent(DataFormat.PLAIN_TEXT)) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
event.consume();
}
});
row.setOnDragDropped(event -> {
Dragboard db = event.getDragboard();
if (db.hasContent(DataFormat.PLAIN_TEXT)) {
reportFlowController.addNewReport(username, getSqlTimeStamp().toString(), this.txt_adressnummer.getText(), reports, db.getString());
event.setDropCompleted(true);
event.consume();
}
});
return row;
});
}
现在如果我这样注册工厂:
registerDragAndDropReportListener(tv_berichte);
highlightReportRowsIfImportant();
仅使用最后一个。
请您解释一下我如何注册这两个?
答案 0 :(得分:1)
您无法注册多个行工厂,尝试这样做是没有意义的。 TableView
使用其行工厂在需要时创建TableRow
对象(通常在屏幕上首次布局时,如果它垂直增长并且需要显示更多行,则可能稍后);记住行工厂只是一个提供TableRow
个对象的函数。如果注册了两个或更多行工厂,则TableView
将没有选择使用哪个工厂的机制。
您可以做的是定义一个使用现有行工厂生成行的行工厂。这有效地替换了现有的行工厂,并为其添加了额外的功能:
private void registerDragAndDropReportListener(TableView<DatabaseReport> view) {
Callback<TableView<DatabaseReport>, TableRow<DatabaseReport>> existingRowFactory
= view.getRowFactory();
view.setRowFactory(tv -> {
TableRow<DatabaseReport> row ;
if (existingRowFactory == null) {
row = new TableRow<>();
} else {
row = existingRowFactory.call(view);
}
row.setOnDragDetected(event -> {
if (!row.isEmpty()) {
Dragboard db = row.startDragAndDrop(TransferMode.COPY);
db.setDragView(row.snapshot(null, null));
ClipboardContent cc = new ClipboardContent();
cc.putString(row.getItem().getReport_content());
db.setContent(cc);
event.consume();
}
});
row.setOnDragOver(event -> {
Dragboard db = event.getDragboard();
if (db.hasContent(DataFormat.PLAIN_TEXT)) {
event.acceptTransferModes(TransferMode.COPY_OR_MOVE);
event.consume();
}
});
row.setOnDragDropped(event -> {
Dragboard db = event.getDragboard();
if (db.hasContent(DataFormat.PLAIN_TEXT)) {
reportFlowController.addNewReport(username, getSqlTimeStamp().toString(), this.txt_adressnummer.getText(), reports, db.getString());
event.setDropCompleted(true);
event.consume();
}
});
return row;
});
}
使用此方法,registerDragAndDropReportListener
方法将现有的行工厂替换为向现有行工厂添加其他功能的方法,我认为这就是您想要的。因此,在这种情况下,您首先会调用原始highlightRowsIfImportant
方法,然后调用显示的新registerDragAndDropReportListener
方法。
您可以对其他方法进行类似的更改,以便您可以按所需的任何顺序调用这两种方法。请注意,在这种情况下,确保只调用一次方法非常重要。
答案 1 :(得分:0)
这是我的解决方案,在同一行工厂中使用两个侦听器并使用相同的行对象。在你发布你的awnser James_D之后,我很清楚。我不能注册其中的两个,这应该是handelt ...首先想一想,然后编写代码......
....
$scope.$data = [ ...]
function ativoOrPerfil(item) {
return item.ativo == filtroAtivo && (filtroPerfil == null || item.perfil == filtroPerfil )
}
function updateFiltered() {
$scope.$dataFiltered = $scope.$data.filter(ativoOrPerfil)
}
$scope.$watch('filtroAtivo', updateFiltered)
$scope.$watch('filtroPerfil', updateFiltered)