[英]How to get the Cell (of a ListView) under the mouse pointer?
我编写了一个线程,该线程不断检查鼠标是否在ListView上,因为我想显示一个弹出窗口,其中包含有关用鼠标指向的单元格的信息。
因此,检查鼠标是否在ListView上没有问题。
但是如何检查鼠标是否在某个单元格上,因为我无法使用ListCell.localToScreen(ListCell.getBoundsInLocal());
在屏幕上获取单元格坐标?
我不想使用ListCell事件,例如onMouseEntered。
在每个ListCell
上为mouseEntered
和mouseExited
事件注册处理程序,或者观察ListCell
的hoverProperty
。 这是使用第二种方法的示例:
import java.util.stream.IntStream;
import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.util.Duration;
public class PopupOnListCellHover extends Application {
private Popup popup ;
private Node popupContent ;
private Label titleLabel ;
private Label detailsLabel ;
private FadeTransition fadeOut ;
@Override
public void start(Stage primaryStage) {
ListView<Item> listView = new ListView<>();
popup = new Popup();
titleLabel = new Label();
titleLabel.setStyle("-fx-font-size: 1.5em ; -fx-font-weight: bold;");
detailsLabel = new Label();
popupContent = new VBox(10, titleLabel, detailsLabel);
popupContent.setStyle("-fx-background-color: -fx-background; "+
"-fx-background: lightskyblue; -fx-padding:12px;");
popup.getContent().add(popupContent);
fadeOut = new FadeTransition(Duration.millis(500), popupContent);
fadeOut.setFromValue(1.0);
fadeOut.setToValue(0.0);
fadeOut.setOnFinished(e -> popup.hide());
listView.setCellFactory(lv -> {
ListCell<Item> cell = new ListCell<Item>() {
@Override
public void updateItem(Item item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
} else {
setText(item.getName());
}
}
};
cell.hoverProperty().addListener((obs, wasHovered, isNowHovered) -> {
if (isNowHovered && ! cell.isEmpty()) {
showPopup(cell);
} else {
hidePopup();
}
});
return cell ;
});
IntStream.rangeClosed(1, 100).mapToObj(i -> new Item("Item "+i, i))
.forEach(listView.getItems()::add);
BorderPane root = new BorderPane(listView);
Scene scene = new Scene(root, 250, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private void showPopup(ListCell<Item> cell) {
fadeOut.stop();
popupContent.setOpacity(1.0);
Bounds bounds = cell.localToScreen(cell.getBoundsInLocal());
popup.show(cell, bounds.getMaxX(), bounds.getMinY());
Item item = cell.getItem() ;
titleLabel.setText(item.getName());
detailsLabel.setText(String.format("This is %s.%nIt has value %d.",
item.getName(), item.getValue()));
}
private void hidePopup() {
fadeOut.playFromStart();
}
public static class Item {
private final int value ;
private final String name ;
public Item(String name, int value) {
this.name = name ;
this.value = value ;
}
public int getValue() {
return value ;
}
public String getName() {
return name ;
}
}
public static void main(String[] args) {
launch(args);
}
}
要对mouseEntered
和mouseExited
使用处理程序,请替换
cell.hoverProperty().addListener((obs, wasHovered, isNowHovered) -> {
if (isNowHovered && ! cell.isEmpty()) {
showPopup(cell);
} else {
hidePopup();
}
});
与
cell.setOnMouseEntered(e -> showPopup(cell));
cell.setOnMouseExited(e -> hidePopup());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.