推荐
我发现 ListView 单元格上的 Tooltips 的可用性很糟糕,因为 Tooltips 拦截用于选择行、滚动列表等的标准鼠标事件。所以我不建议将 Tooltips 放在 ListView 单元格上。
为什么会创建多个单元格并多次调用 updateItem
预计 ListView 有多个单元格,并且可能会为每个单元格多次调用updateItem() 。
即使某些单元格是空的,也会为场景中显示的 ListView 中的每一行创建一个单元格。通常会创建更多屏幕外的单元格以进行有效的滚动处理。每次初始设置或修改 ListView 的基础数据或滚动列表时,都会在相关单元格上调用 updateItem() 以更新单元格的内容。在滚动大列表的情况下,updateItem() 将为每个单元格调用很多次。
在 ListView 单元格上设置工具提示的示例代码
下面的代码基于Oracle JavaFX 教程 ListView 示例,但对其进行了自定义,以便在将鼠标悬停在单元格上时为单元格创建工具提示。
mport javafx.application.Application;
import javafx.collections.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Callback;
public class ListViewSample extends Application {
ListView<String> list = new ListView<String>();
ObservableList<String> data = FXCollections.observableArrayList(
"chocolate", "salmon", "gold", "coral", "darkorchid",
"darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue",
"blueviolet", "brown");
final Label label = new Label();
@Override
public void start(Stage stage) {
VBox box = new VBox();
Scene scene = new Scene(box, 200, 200);
stage.setScene(scene);
stage.setTitle("ListViewSample");
box.getChildren().addAll(list, label);
VBox.setVgrow(list, Priority.ALWAYS);
label.setLayoutX(10);
label.setLayoutY(115);
label.setFont(Font.font("Verdana", 20));
list.setItems(data);
list.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override public ListCell<String> call(ListView<String> list) {
return new ColorRectCell();
}
});
list.getSelectionModel().selectedItemProperty().addListener(
(ov, old_val, new_val) -> {
label.setText(new_val);
label.setTextFill(Color.web(new_val));
});
stage.show();
}
static class ColorRectCell extends ListCell<String> {
final Rectangle swatch = new Rectangle(30, 30);
final Tooltip tip = new Tooltip();
public ColorRectCell() {
tip.setGraphic(swatch);
}
@Override
public void updateItem(String color, boolean empty) {
super.updateItem(color, empty);
if (color != null) {
swatch.setFill(Color.valueOf(color.toUpperCase()));
setText(color);
setTooltip(tip);
} else {
setText("");
setTooltip(null);
}
}
}
public static void main(String[] args) {
launch(args);
}
}