gpt4 book ai didi

java - setOnMouseEntered 不适用于 ListView 中的 ImageView

转载 作者:行者123 更新时间:2023-12-02 01:03:48 26 4
gpt4 key购买 nike

我在 JavaFx 上的 ImageViews 上遇到 setOnMouseEntered 问题。我正在尝试使用 ColorAdjust 更改放置在 Listview 中的 ImageView 的亮度。该效果本身适用于不在 ListView 中的 ImageView。

我猜只有ListView会触发setOnMouseEntered,但ImageViews不会,这是我的目标。同样的问题是由 ImageView 的悬停效果引起的,它们在 ListView 中后不会立即触发。

fxml:

 <ListView fx:id="cardsView" />

java代码:

@FXML private ListView<ImageView> cardsView;
private ObservableMap<ImageView, Card> hCards;

@FXML
public void initialize() {
hCards= FXCollections.observableHashMap();
cardsView.getItems().setAll(hCards.keySet());
hCards.addListener(
(MapChangeListener<ImageView, Card>)
change -> {
cardsView.getItems().removeAll(change.getKey());
if (change.wasAdded()) {
cardsView.getItems().add(change.getKey());
}
});
}

稍后,将为每个 ImageView 添加:

private void addLightEffectOnMouseEntered(ImageView imageView) {
imageView.setOnMouseEntered(
t -> {
ColorAdjust colorAdjust = new ColorAdjust();
colorAdjust.setBrightness(0.4);
imageView.setEffect(colorAdjust);
});
}

在调试时,我发现 css 和 setOnMouseEntered 等内容已正确添加。所以似乎被ListView以某种方式阻止了ChildNodes获得setOnMouseEntered或Hover效果而不是ListView

最佳答案

您的问题与此基本相同:Adding EventHandler To ImageView contained in a Label 。所有 Cell 特化(包括 ListCell)均继承自 Labeled,并且其所有默认外观均继承自 LabeledSkinBase,这是你的问题的根源。作为对错误的修复(请参阅其他问答),当将 ImageView 用作 Labeled 的图形时,它被设置为鼠标透明。由于 ImageView 是鼠标透明的,因此您的 MOUSE_ENTERED 处理程序由于明显的原因永远不会被调用。

如果您不知道,ListView 的默认单元工厂会返回一个 ListCell 实现,当该项是 Node 的实例时>,将单元格的图形设置为项目。一个简单的解决方法是使用您自己的 ListCell 实现,将 ImageView 包装在另一个节点(例如 Pane)中。这是一个例子:

listView.setCellFactory(lv -> new ListCell<>() {

private final Pane imageViewContainer = new Pane();

@Override
protected void updateItem(ImageView item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
imageViewContainer.getChildren().clear();
setGraphic(null);
} else {
imageViewContainer.getChildren().setAll(item);
setGraphic(imageViewContainer);
}
}
});

这将防止 ImageView 变得对鼠标透明。

<小时/>

顺便说一句,使用 GUI 对象(例如 ImageView)作为 ListView(或任何其他虚拟化控件)的模型项通常不是一个好主意。在这种情况下,这可能是一个更糟糕的想法,因为这种设置鼓励同时将与应用程序相关的每个 Image 保存在内存中。根据图像的数量以及这些图像的大小,这很容易导致 OutOfMemoryError 或至少消耗用户不必要的 RAM。

您可能需要考虑使用 Card 作为模型项,并结合 Image 对象的内存受限缓存(请参阅 WeakReference/SoftReference ,尽管您也可以寻找第三方缓存库)。 Card 类可以保存其关联图像的位置,或者缓存可以根据 Card 的状态导出位置。

但是,您仍然会使用 ImageView 作为 ListCell 的图形,因此您仍然需要使用上面提到的解决方法。使用内存受限缓存的帮助是,如果 Card 未显示在 ListCell 中,则其关联的 Image 可能会变为符合垃圾回收条件,从而减少应用程序的内存需求。

缓存还允许您在应用程序中的任何地方使用相同的Image(相同的Image可以在多个ImageView之间共享)这意味着当需要特定图像时,您并不总是加载新的图像(因为在请求时它可能仍然在内存中)。换句话说,任何缓存提供的典型功能。

关于java - setOnMouseEntered 不适用于 ListView 中的 ImageView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60310121/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com