2015-10-21 35 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());