BlaCkOmN
BlaCkOmN

Reputation: 81

How to add KeyListener on a TreeItem JavaFX?

I have a project with a TreeView and I want that if I select a TreeItem and that I type DELETE the file in relation with it is automatically delete on the disk. But it doesn't work and I don't find my answer just by searching on Internet. This is my function (listeArbres is a TreeView) :

private void recupereFichierProjet(File repertoire, FileFilter filtre) {
    File[] fichiers = repertoire.listFiles(filtre);
    TreeItem<String> rootItem = new TreeItem<String>("Workspace");
    rootItem.setExpanded(true);

    for (File fichier : fichiers) {
        Projet projet = Projet.charge(fichier);
        TreeItem<String> item = new TreeItem<String>(fichier.getName());
        item.addEventHandler(KeyEvent.KEY_TYPED, event -> {
            if (event.getCode() == KeyCode.DELETE) {
                System.out.println("la");
                Projet.supprime(
                        new File("./workspace/" + listeArbres.getSelectionModel().getSelectedItem().getValue()));
                initialiseTreeView();
            }
        });
        rootItem.getChildren().add(item);
        for (Arbre arbre : projet.getArbreDuProjet()) {
            TreeItem<String> itemBis = new TreeItem<String>(arbre.getEntete().getNomFonction());
            item.getChildren().add(itemBis);
        }
    }
    listeArbres.setRoot(rootItem);
    listeArbres.setVisible(true);
}

I think I understand that addEventHandler is for distinct Event so I don't understand how to use a KeyListener on the object 'Item'.

The static methode 'supprime' on 'Projet' is use to deleted my file.

Thank you beforehand.(And sorry for my bad english).

Upvotes: 3

Views: 1436

Answers (1)

James_D
James_D

Reputation: 209724

As stated in the TreeItem documentation (under "TreeItem Events"):

It is important to note however that a TreeItem is not a Node, which means that only the event types defined in TreeItem will be delivered. To listen to general events (for example mouse interactions), it is necessary to add the necessary listeners to the cells contained within the TreeView (by providing a cell factory).

For key presses, however, the actual cells do not get keyboard focus, and so they do not receive key events. So what you really want here is that when the TreeView has focus and the delete key is pressed, then delete the selected item in the tree. So you need

TreeView<String> tree = ... ;

tree.setOnKeyPressed(e -> {
    TreeItem<String> selected = tree.getSelectionModel().getSelectedItem();
    if (selected != null && e.getCode() == KeyCode.DELETE) {
        System.out.println("Delete pressed on "+selected.getValue());
        // delete file associated with selected.getValue()...
    }
});

A couple of other notes:

  1. Key typed events do not have a code associated with them (see docs). You need a key pressed event here, not a key typed event.
  2. Since your tree view seems to be displaying files, it might make (a lot more) sense to have a TreeView<File> and to modify the updateItem method in the cell implementation to display the name of the file. Then you can get the file directly with getItem() in the listener, and the code to delete it will be much easier.

Upvotes: 4

Related Questions