我在 ListView 中有一个链接列表。我想向列表的每个单元格添加一个 mouseEventListener,以便每当用户双击时都会打开列表项链接。我可以自己编写打开链接的功能,但我无法为列表中的每个单元格添加双击事件。请帮忙...
让我们将您的
ListView
视为播放列表。现在,您可以使用每个单元格上的双击功能来实现鼠标侦听器
playList.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent click) {
if (click.getClickCount() == 2) {
//Use ListView's getSelected Item
currentItemSelected = playList.getSelectionModel()
.getSelectedItem();
//use this to do whatever you want to. Open Link etc.
}
}
});
我必须解决同样的问题,我的 ListView 包含一个网格窗格和标记文本,因此您必须将“instanceof”和“or”的另一侧更改为您所拥有的。
(假设你的ListView名为listView):
listView.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2 &&
(event.getTarget() instanceof LabeledText || ((GridPane) event.getTarget()).getChildren().size() > 0)) {
//your code here
}
}
});
如果用户单击项目的最边缘和 ListView 的边框附近,则可能不会通过 if 循环,但听起来用户在您的情况下不会这样做。
希望这有帮助。
答案可能很长,因为我试图准确提供用户所要求的内容。我正在考虑使用 fxml,但如果不使用 fxml,答案也是适用的。我还使用自定义
CellFactory
来渲染各个列表项。
这个答案遵循 MVC 模式。另外,我跳过了代码中的所有导入语句。
所以,我们需要这些文件。每个文件的名称都是不言自明的。
ItemModel.java
PrimaryScene.fxml
PrimarySceneController.java
ListItem.fxml
ListItemController.java
ListItemCellFactory.java
ListItemCell.java
OnItemDoubleClickListener.java
ItemModel.java
public class ItemModel{
private String name;
private String description;
// All Getters, and Setters here ....
}
OnItemDoubleClickListener.java
public interface OnItemDoubleClickListener{
public void handleDoubleClick(MouseEvent event, ItemModel model);
}
PrimaryScene.fxml
<AnchorPane xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="PrimarySceneController">
<ListView fx:id="listView" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</AnchorPane>
PrimarySceneController.java
public class PrimarySceneController implements Initializable, OnItemDoubleClickListener{
@FXML
public ListView<ItemModel> listView;
private final ObservableList<ItemModel> items = FXCollections.observableArrayList();
@Override
public void initialize(URL location, ResourceBundle resources) {
listView.setCellFactory(new ListItemCellFactory(this));
listView.setItems(items);
// TODO: populate items here ...
}
@Override
public void handleDoubleClick(MouseEvent event, ItemModel model){
// TODO: Item was double clicked. Do you thing.
}
}
ListItem.fxml
<AnchorPane xmlns="http://javafx.com/javafx/17.0.2-ea" xmlns:fx="http://javafx.com/fxml/1" fx:id="root">
<VBox AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<Label fx:id="labelName" text="Label"/>
<Label fx:id="labelDescription" text="Label/>
</VBox>
</AnchorPane>
ListItemController.java
private static class ListItemController implements Initializable{
@FXML
private AnchorPane root;
@FXML
private Label labelName;
@FXML
private Label labelDescription;
private final OnItemDoubleClickListener listener;
public ListItemController(OnItemDoubleClickListener listener){
this.listener = listener;
}
public void draw(ItemModel model) {
labelName.setText(model.getName());
labelDescription.setText(model.getDescription());
// Magic happens here
root.setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
if(event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2){
this.listener.handleDoubleClick(event, model);
}
}
});
}
@Override
public void initialize(URL location, ResourceBundle resources) {
}
}
ListItemCellFactory.java
public class ListItemCellFactory implements Callback<ListView<ItemModel>, ListCell<ItemModel>> {
private final OnItemDoubleClickListener listener;
public ListItemCellFactory(OnItemDoubleClickListener listener){
this.listener = listener;
}
@Override
public ListCell<ItemModel> call(ListView<ItemModel> listView) {
FXMLLoader fxmlLoader = new FXMLLoader();
ListItemController controller = new ListItemController(this.listener);
fxmlLoader.setController(controller);
Node graphic = fxmlLoader.load(Home2Controller.class.getResourceAsStream("/ListItem.fxml"));
return new ListItemCell(graphic, controller);
}
}
ListItemCell.java
private static class ListItemCell extends ListCell<ItemModel> {
private final Node graphic;
private final ListItemController controller;
public ListItemCell(Node graphic, ListItemController controller) {
this.graphic = graphic;
this.controller = controller;
}
@Override
protected void updateItem(ItemModel item, boolean empty) {
super.updateItem(item, empty);
if (empty){
setText(null);
setGraphic(null);
return;
}
setText(null);
setGraphic(graphic);
controller.draw(item);
}
}