2015-10-21 57 views
0

我写了一个线程,不断检查鼠标是否在ListView上,因为我想显示一个Popup,其中包含有关用鼠标指向的单元格的信息。如何获得鼠标指针下的单元格(ListView)?

因此没有问题检查鼠标是否在ListView上。

但是,如何检查鼠标是否在某个单元格上,因为我无法使用ListCell.localToScreen(ListCell.getBoundsInLocal());来获取屏幕上的单元坐标?

我不喜欢使用ListCell事件,如onMouseEntered。

+0

取代

cell.hoverProperty().addListener((obs, wasHovered, isNowHovered) -> { if (isNowHovered && ! cell.isEmpty()) { showPopup(cell); } else { hidePopup(); } }); 

做到这一点的方法是登记用鼠标听众'ListCell's,或者观察他们的'hoverProperty'。你为什么不喜欢使用提供的机制?为什么你不能使用'ListCell.localToScreen(ListCell.getBoundsInLocal())'? –

+0

@James_D我不想用听众,因为他们有随机的错误。我正在尝试使用hoverProperty,但我宁愿继续使用此属性。 ListCell没有这些属性。 – user2468425

+0

@James_D hoverProperty不适合这个用途。 我想我会尝试听众,我希望他们不会像往常一样随机表现 – user2468425

回答

1

无论注册每个ListCellmouseEnteredmouseExited事件处理程序,或者观察ListCellhoverProperty。下面是使用该第二方法的一个示例:

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

要使用的处理程序mouseEnteredmouseExited,与

cell.setOnMouseEntered(e -> showPopup(cell)); 
    cell.setOnMouseExited(e -> hidePopup());