在javafx中的ListView,添加了多个单元格

时间:2013-08-10 06:29:31

标签: java javafx-2 javafx

调试下面的代码,它显示多次调用updateItem()方法,但我无法弄清楚为什么多次调用它。

我想将工具提示添加到ListView。

// THIS TO ADD TOOLTIP, NOT WORKING FULLY.
lstComments.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
    @Override
    public ListCell<String> call(ListView<String> p) {
        final Tooltip tt = new Tooltip();
        final ListCell<String> cell = new ListCell<String>() {
            String message = ca.getMessage();

            @Override
            public void updateItem(String s, boolean empty) {
                super.updateItem(s, empty);
                tt.setText(message);
                setTooltip(tt);
            }
        };

        cell.setText(ca.getMessage());
        return cell;
    }
});

1 个答案:

答案 0 :(得分:4)

<强>建议

我发现ListView单元格上的工具提示的可用性很糟糕,因为工具提示拦截了用于选择行,滚动列表等的标准鼠标事件。所以我不建议在ListView单元格上放置工具提示。

为什么要创建多个单元格并多次调用updateItem

预计ListView会有多个单元格,并且每个单元格可能会多次调用updateItem()

即使某些单元格为空,也会为场景中显示的ListView中的每一行创建一个单元格。通常会创建一些屏幕外的单元格,以实现高效的滚动处理。每次最初设置或修改ListView的基础数据,或者滚动列表时,将在相关单元格上调用updateItem()以更新单元格的内容。在滚动大型列表的情况下,每个单元格将多次调用updateItem()。

在ListView单元格上设置工具提示的示例代码

下面的代码基于Oracle JavaFX tutorial ListView sample,但是将其自定义为当您将鼠标悬停在单元格上时为单元格创建工具提示。

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);
    }
}