带有网格面板的 Javafx treeview 细胞工厂
Javafx treeview cell factory with gridpane
我有一个 TreeView<GridPane>
并且 GridPane
包含多个节点,例如按钮和标签。 GridPane
内的节点数量各不相同。
我需要细胞工厂来获取 MouseEntered
事件,但是当我使用下面的代码时,没有显示任何内容。
我当前的代码如下所示:
treeView.setCellFactory(tv -> {
TreeCell<GridPane> cell = new TreeCell<GridPane>() {
@Override
protected void updateItem(GridPane item, boolean empty) {
super.updateItem(item, empty);
}
};
cell.setOnMouseEntered(e -> {
//TODO
});
return cell ;
});
我知道 updateItem
方法需要修改,但我不知道如何修改,因为 GridPane
中的节点数不同。
编辑
这是 类.
TreeController.java:
public class TreeController {
private TreeItem<GridPane> rootItem;
private int hgap = 5;
@FXML private TreeView<GridPane> treeView;
@FXML
private void initialize() {
GridPane gp = new GridPane();
gp.add(new Label("Label1"), 0, 0);
gp.getColumnConstraints().add(0, new ColumnConstraints());
gp.getColumnConstraints().get(0).setHgrow(Priority.NEVER);
Button cond = new Button("button");
gp.add(cond, 1, 0);
gp.getColumnConstraints().add(1, new ColumnConstraints());
gp.getColumnConstraints().get(1).setHgrow(Priority.NEVER);
gp.add(new Label("Label2"), 2, 0);
gp.getColumnConstraints().add(2, new ColumnConstraints());
gp.getColumnConstraints().get(2).setHgrow(Priority.ALWAYS);
Button btnAdd = new Button("Add");
gp.add(btnAdd, 3, 0);
gp.setHgap(hgap);
rootItem = new TreeItem<GridPane>(gp);
rootItem.setExpanded(true);
treeView.setRoot(rootItem);
rootItem.getChildren().add(new TreeItem<GridPane>(createGridRow("Age", false)));
rootItem.getChildren().add(new TreeItem<GridPane>(createGridRow("Person", true)));
/*
treeView.setCellFactory(tv -> {
TreeCell<GridPane> cell = new TreeCell<GridPane>() {
@Override
protected void updateItem(GridPane item, boolean empty) {
super.updateItem(item, empty);
}
};
cell.setOnMouseEntered(e -> {
System.out.println("changed cell");
});
return cell ;
});
*/
}
private GridPane createGridRow(String selectedCol, Boolean showAddButton) {
int index = 0;
GridPane gp = new GridPane();
Button columnName = new Button(selectedCol);
gp.add(columnName, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.NEVER);
index++;
Button condition = new Button("greater than");
gp.add(condition, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.NEVER);
index++;
Button value = new Button("[enter value]");
gp.add(value, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.ALWAYS);
index++;
if (showAddButton) {
Button btnAdd = new Button("Add");
gp.add(btnAdd, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.NEVER);
index++;
}
gp.setHgap(hgap);
return gp;
}
}
MainClass.java:
public class MainClass extends Application{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Parent root;
try {
TreeController controller = new TreeController();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("TreeController.fxml"));
fxmlLoader.setController(controller);
root = fxmlLoader.load();
Scene scene = new Scene(root, 600, 500);
stage.setMinHeight(400);
stage.setMinWidth(500);
stage.setTitle("TreeController");
stage.setScene(scene);
stage.setResizable(true);
stage.show();
} catch (IOException e) {
e.printStackTrace();
};
}
@Override
public void stop() {
System.exit(0);
}
}
TreeController.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.161" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" layoutX="155.0" layoutY="111.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="20.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="20.0">
<content>
<TreeView fx:id="treeView" prefHeight="200.0" prefWidth="200.0" />
</content>
</ScrollPane>
</children>
</AnchorPane>
这是一个相当简单但综合的例子。分析之后,您应该能够实施您的解决方案。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TreeViewCellApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
TreeItem<Employee> leaf1Item = new TreeItem<Employee>(new Employee("Anne Burnes", "Employee"));
TreeItem<Employee> leaf2Item = new TreeItem<Employee>(new Employee("Ronan Jackson", "Employee"));
TreeItem<Employee> rootItem = new TreeItem<Employee>(new Employee("Jack Shields", "Head"));
rootItem.getChildren().add(leaf1Item);
rootItem.getChildren().add(leaf2Item);
Label label = new Label();
TreeView<Employee> treeView = new TreeView<>(rootItem);
treeView.setCellFactory(param -> new TreeCell<Employee>() {
@Override
protected void updateItem(Employee employee, boolean empty) {
super.updateItem(employee, empty);
if (employee == null || empty) {
setGraphic(null);
} else {
EmployeeControl employeeControl = new EmployeeControl(employee);
employeeControl.setOnMouseClicked(mouseEvent -> label.setText(employee.getName()));
setGraphic(employeeControl);
}
}
});
VBox vBox = new VBox(label, treeView);
stage.setScene(new Scene(vBox));
stage.show();
}
}
class Employee {
private final String name;
private final String capacity;
public Employee(String name, String capacity) {
this.name = name;
this.capacity = capacity;
}
public String getName() {
return name;
}
public String getCapacity() {
return capacity;
}
}
class EmployeeControl extends HBox {
private final Label nameLabel = new Label();
private final Label capacityLabel = new Label();
{
getChildren().addAll(nameLabel, capacityLabel);
}
public EmployeeControl(Employee employee) {
nameLabel.setText(employee.getName());
capacityLabel.setText(employee.getCapacity());
}
}
我有一个 TreeView<GridPane>
并且 GridPane
包含多个节点,例如按钮和标签。 GridPane
内的节点数量各不相同。
我需要细胞工厂来获取 MouseEntered
事件,但是当我使用下面的代码时,没有显示任何内容。
我当前的代码如下所示:
treeView.setCellFactory(tv -> {
TreeCell<GridPane> cell = new TreeCell<GridPane>() {
@Override
protected void updateItem(GridPane item, boolean empty) {
super.updateItem(item, empty);
}
};
cell.setOnMouseEntered(e -> {
//TODO
});
return cell ;
});
我知道 updateItem
方法需要修改,但我不知道如何修改,因为 GridPane
中的节点数不同。
编辑 这是 类.
TreeController.java:
public class TreeController {
private TreeItem<GridPane> rootItem;
private int hgap = 5;
@FXML private TreeView<GridPane> treeView;
@FXML
private void initialize() {
GridPane gp = new GridPane();
gp.add(new Label("Label1"), 0, 0);
gp.getColumnConstraints().add(0, new ColumnConstraints());
gp.getColumnConstraints().get(0).setHgrow(Priority.NEVER);
Button cond = new Button("button");
gp.add(cond, 1, 0);
gp.getColumnConstraints().add(1, new ColumnConstraints());
gp.getColumnConstraints().get(1).setHgrow(Priority.NEVER);
gp.add(new Label("Label2"), 2, 0);
gp.getColumnConstraints().add(2, new ColumnConstraints());
gp.getColumnConstraints().get(2).setHgrow(Priority.ALWAYS);
Button btnAdd = new Button("Add");
gp.add(btnAdd, 3, 0);
gp.setHgap(hgap);
rootItem = new TreeItem<GridPane>(gp);
rootItem.setExpanded(true);
treeView.setRoot(rootItem);
rootItem.getChildren().add(new TreeItem<GridPane>(createGridRow("Age", false)));
rootItem.getChildren().add(new TreeItem<GridPane>(createGridRow("Person", true)));
/*
treeView.setCellFactory(tv -> {
TreeCell<GridPane> cell = new TreeCell<GridPane>() {
@Override
protected void updateItem(GridPane item, boolean empty) {
super.updateItem(item, empty);
}
};
cell.setOnMouseEntered(e -> {
System.out.println("changed cell");
});
return cell ;
});
*/
}
private GridPane createGridRow(String selectedCol, Boolean showAddButton) {
int index = 0;
GridPane gp = new GridPane();
Button columnName = new Button(selectedCol);
gp.add(columnName, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.NEVER);
index++;
Button condition = new Button("greater than");
gp.add(condition, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.NEVER);
index++;
Button value = new Button("[enter value]");
gp.add(value, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.ALWAYS);
index++;
if (showAddButton) {
Button btnAdd = new Button("Add");
gp.add(btnAdd, index, 0);
gp.getColumnConstraints().add(index, new ColumnConstraints());
gp.getColumnConstraints().get(index).setHgrow(Priority.NEVER);
index++;
}
gp.setHgap(hgap);
return gp;
}
}
MainClass.java:
public class MainClass extends Application{
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Parent root;
try {
TreeController controller = new TreeController();
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("TreeController.fxml"));
fxmlLoader.setController(controller);
root = fxmlLoader.load();
Scene scene = new Scene(root, 600, 500);
stage.setMinHeight(400);
stage.setMinWidth(500);
stage.setTitle("TreeController");
stage.setScene(scene);
stage.setResizable(true);
stage.show();
} catch (IOException e) {
e.printStackTrace();
};
}
@Override
public void stop() {
System.exit(0);
}
}
TreeController.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.161" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ScrollPane fitToHeight="true" fitToWidth="true" layoutX="155.0" layoutY="111.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="20.0" AnchorPane.leftAnchor="20.0" AnchorPane.rightAnchor="20.0" AnchorPane.topAnchor="20.0">
<content>
<TreeView fx:id="treeView" prefHeight="200.0" prefWidth="200.0" />
</content>
</ScrollPane>
</children>
</AnchorPane>
这是一个相当简单但综合的例子。分析之后,您应该能够实施您的解决方案。
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TreeViewCellApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
TreeItem<Employee> leaf1Item = new TreeItem<Employee>(new Employee("Anne Burnes", "Employee"));
TreeItem<Employee> leaf2Item = new TreeItem<Employee>(new Employee("Ronan Jackson", "Employee"));
TreeItem<Employee> rootItem = new TreeItem<Employee>(new Employee("Jack Shields", "Head"));
rootItem.getChildren().add(leaf1Item);
rootItem.getChildren().add(leaf2Item);
Label label = new Label();
TreeView<Employee> treeView = new TreeView<>(rootItem);
treeView.setCellFactory(param -> new TreeCell<Employee>() {
@Override
protected void updateItem(Employee employee, boolean empty) {
super.updateItem(employee, empty);
if (employee == null || empty) {
setGraphic(null);
} else {
EmployeeControl employeeControl = new EmployeeControl(employee);
employeeControl.setOnMouseClicked(mouseEvent -> label.setText(employee.getName()));
setGraphic(employeeControl);
}
}
});
VBox vBox = new VBox(label, treeView);
stage.setScene(new Scene(vBox));
stage.show();
}
}
class Employee {
private final String name;
private final String capacity;
public Employee(String name, String capacity) {
this.name = name;
this.capacity = capacity;
}
public String getName() {
return name;
}
public String getCapacity() {
return capacity;
}
}
class EmployeeControl extends HBox {
private final Label nameLabel = new Label();
private final Label capacityLabel = new Label();
{
getChildren().addAll(nameLabel, capacityLabel);
}
public EmployeeControl(Employee employee) {
nameLabel.setText(employee.getName());
capacityLabel.setText(employee.getCapacity());
}
}