我尝试进行研究,并为此花了几天时间,但似乎找不到解决方法。使用JFXTreeTableView,将特定的列组合在一起后,每个组标题仍具有一个按钮。我一直在尝试检查它是否是标题行,请不要添加按钮。我一直在使用Callback方法setCellFactory和setCellValueFactory,但它仍然无法正常工作。即使研究后,我也不100%了解回调,setCellFactory和setCellValueFactory。有人可以指出我正确的方向吗?非常感谢您的提前帮助! :)
底部带有图片和代码段
import com.jfoenix.controls.*;
import com.jfoenix.controls.cells.editors.TextFieldEditorBuilder;
import com.jfoenix.controls.cells.editors.base.GenericEditableTreeTableCell;
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableColumn.CellEditEvent;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import java.io.File;
import java.net.MalformedURLException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
public class TreeTableDemo extends Application {
private static final String COMPUTER_DEPARTMENT = "Computer Department";
private static final String SALES_DEPARTMENT = "Sales Department";
private static final String IT_DEPARTMENT = "IT Department";
private static final String HR_DEPARTMENT = "HR Department";
@Override
public void start(Stage primaryStage) throws Exception {
JFXTreeTableColumn<User, String> deptColumn = new JFXTreeTableColumn<>("Department");
deptColumn.setPrefWidth(150);
deptColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<User, String> param) -> {
if (deptColumn.validateValue(param)) {
return param.getValue().getValue().department;
} else {
return deptColumn.getComputedValue(param);
}
});
JFXTreeTableColumn<User, String> empColumn = new JFXTreeTableColumn<>("Employee");
empColumn.setPrefWidth(150);
empColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<User, String> param) -> {
if (empColumn.validateValue(param)) {
return param.getValue().getValue().userName;
} else {
return empColumn.getComputedValue(param);
}
});
JFXTreeTableColumn<User, String> ageColumn = new JFXTreeTableColumn<>("Age");
ageColumn.setPrefWidth(150);
ageColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<User, String> param) -> {
if (ageColumn.validateValue(param)) {
return param.getValue().getValue().age;
} else {
return ageColumn.getComputedValue(param);
}
});
ageColumn.setCellFactory((TreeTableColumn<User, String> param) -> new GenericEditableTreeTableCell<>(
new TextFieldEditorBuilder()));
ageColumn.setOnEditCommit((CellEditEvent<User, String> t) -> t.getTreeTableView()
.getTreeItem(t.getTreeTablePosition()
.getRow())
.getValue().age.set(t.getNewValue()));
empColumn.setCellFactory((TreeTableColumn<User, String> param) -> new GenericEditableTreeTableCell<>(
new TextFieldEditorBuilder()));
empColumn.setOnEditCommit((CellEditEvent<User, String> t) -> t.getTreeTableView()
.getTreeItem(t.getTreeTablePosition()
.getRow())
.getValue().userName.set(t.getNewValue()));
deptColumn.setCellFactory((TreeTableColumn<User, String> param) -> new GenericEditableTreeTableCell<>(
new TextFieldEditorBuilder()));
deptColumn.setOnEditCommit((CellEditEvent<User, String> t) -> t.getTreeTableView()
.getTreeItem(t.getTreeTablePosition()
.getRow())
.getValue().department.set(t.getNewValue()));
JFXTreeTableColumn<User, String> settingsColumn = new JFXTreeTableColumn<>("Others");
settingsColumn.setPrefWidth(150);
Callback<TreeTableColumn<User, String>, TreeTableCell<User, String>> cellFactory
=
new Callback<TreeTableColumn<User, String>, TreeTableCell<User, String>>() {
@Override
public TreeTableCell call(final TreeTableColumn<User, String> param) {
final TreeTableCell<User, String> cell = new TreeTableCell<User, String>() {
@Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
setText(null);
} else {
JFXButton btn = new JFXButton();
btn.setText("Others");
setGraphic(btn);
setText(null);
}
}
};
return cell;
}
};
settingsColumn.setCellFactory(cellFactory);
// data
ObservableList<User> users = FXCollections.observableArrayList();
users.add(new User(COMPUTER_DEPARTMENT, "23", "CD 1"));
users.add(new User(SALES_DEPARTMENT, "22", "Employee 1"));
users.add(new User(SALES_DEPARTMENT, "24", "Employee 2"));
users.add(new User(SALES_DEPARTMENT, "25", "Employee 4"));
users.add(new User(SALES_DEPARTMENT, "27", "Employee 5"));
users.add(new User(IT_DEPARTMENT, "42", "ID 2"));
users.add(new User(HR_DEPARTMENT, "21", "HR 1"));
users.add(new User(HR_DEPARTMENT, "28", "HR 2"));
for (int i = 0; i < 40000; i++) {
users.add(new User(HR_DEPARTMENT, Integer.toString(i % 10), "HR 3" + i));
}
for (int i = 0; i < 40000; i++) {
users.add(new User(COMPUTER_DEPARTMENT, Integer.toString(i % 20), "CD 2" + i));
}
for (int i = 0; i < 40000; i++) {
users.add(new User(IT_DEPARTMENT, Integer.toString(i % 5), "HR 4" + i));
}
// build tree
final TreeItem<User> root = new RecursiveTreeItem<>(users, RecursiveTreeObject::getChildren);
JFXTreeTableView<User> treeView = new JFXTreeTableView<>(root);
treeView.setShowRoot(false);
treeView.setEditable(true);
treeView.getColumns().setAll(deptColumn, ageColumn, empColumn, settingsColumn);
FlowPane main = new FlowPane();
main.setPadding(new Insets(10));
main.getChildren().add(treeView);
JFXButton groupButton = new JFXButton("Group");
groupButton.setOnAction((action) -> new Thread(() -> treeView.group(empColumn)).start());
main.getChildren().add(groupButton);
JFXButton unGroupButton = new JFXButton("unGroup");
unGroupButton.setOnAction((action) -> treeView.unGroup(empColumn));
main.getChildren().add(unGroupButton);
JFXTextField filterField = new JFXTextField();
main.getChildren().add(filterField);
Label size = new Label();
filterField.textProperty().addListener((o, oldVal, newVal) -> {
treeView.setPredicate(userProp -> {
final User user = userProp.getValue();
return user.age.get().contains(newVal)
|| user.department.get().contains(newVal)
|| user.userName.get().contains(newVal);
});
});
size.textProperty()
.bind(Bindings.createStringBinding(() -> String.valueOf(treeView.getCurrentItemsCount()),
treeView.currentItemsCountProperty()));
main.getChildren().add(size);
Scene scene = new Scene(main, 475, 500);
// scene.getStylesheets().add(TreeTableDemo.class.getResource("/css/jfoenix-components.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private static final class User extends RecursiveTreeObject<User> {
final StringProperty userName;
final StringProperty age;
final StringProperty department;
User(String department, String age, String userName) {
this.department = new SimpleStringProperty(department);
this.userName = new SimpleStringProperty(userName);
this.age = new SimpleStringProperty(age);
}
}
}