I have a list of links in a ListView. I want to add an mouseEventListener to each cell of the list so that whenever a user double clicks the list item link is opened. I can write the functionality of opening the link on my own but I am not able to add the doubleclick event with every cell in the list. Please help...
Let us consider your ListView
as playList. Now you can implement the mouse listener with double click functionality on each cell using
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.
}
}
});
I had to solve the same sort of issue, my ListView contains a grid pane and labeled text so you'll have to change the 'instanceof' and the other side of the 'or' to what you have.
(Assuming your ListView is named 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
}
}
});
It is possible if the user clicks near the very edge of the item and the border of the ListView for it not to pass the if loop but it sounds like the user won't be doing that in your case.
Hope this helps.
Answer might be lengthy as I am trying to provide exactly what user asked. I am considering usage of fxml, but the answer is applicable if one is not using fxml. I am also using a custom CellFactory
to render individual list items.
This answer follows MVC pattern. Also, I have skipped all import statements in the code.
So, we need these files. Name of each file is self-explanatory.
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 your 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(getClass().getResourceAsStream("/ListItem.fxml"));
return new ListItemCell(graphic, controller);
}
}
The code above assumes that /ListItem.fxml
is inside resources
directory.
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);
}
}
© 2022 - 2024 — McMap. All rights reserved.