JavaFX TreeView Edit Mode über F2

Ja indem du der TreeView einen OnKeyPressed-EventListener verpasst:
(Solltest du keine eigene Klasse für die TreeView verwenden kannst du den Converter natürlich weglassen :)
Java:
public class CustomTreeViewTest extends Application {
    @Override
    public void start( Stage primaryStage ) throws Exception {

        TreeItem<Node> rootItem = new TreeItem<>(new Node("Autos"));
        rootItem.getChildren().addAll(getSampleData());

        TreeView<Node> treeView = new TreeView<>(rootItem);
        
        // falls du es mit Doppelklick gar nicht editieren möchtest, dann diese Zeile einkommentieren
        // treeView.setEditable(false);
        
        treeView.setOnKeyPressed(event -> {
            System.out.println(event.getCode());
            if(event.getCode() == KeyCode.F2) {
                TreeItem<Node> selectedItem = treeView.getSelectionModel().getSelectedItem();
                treeView.setEditable(true);
                treeView.edit(selectedItem);
            }
        });
        
        final StringConverter<Node> converter = new StringConverter<>() {
            @Override
            public String toString( Node object ) {
                return object.getValue();
            }

            @Override
            public Node fromString( String string ) {
                return new Node(string);
            }
        };
        
        treeView.setCellFactory(tv -> TextFieldTreeCell.forTreeView(converter).call(tv));
        

        primaryStage.setScene(new Scene(treeView, 400, 400));
        primaryStage.show();
    }
}
 
Vielen Dank Robert.

Kann ich irgendwie auch auf das Textfeld zugreifen und fokusieren wenn der Mode aktiviert ist?

Zum Beispiel an der Stelle

Code:
treeView.setOnKeyPressed(event -> {
            System.out.println(event.getCode());
            if(event.getCode() == KeyCode.F2) {
                TreeItem<Node> selectedItem = treeView.getSelectionModel().getSelectedItem();
                treeView.setEditable(true);
                treeView.edit(selectedItem);

                // Textfeld Focus request
            }
        });
Ich frage deswegen, weil in mein Code muss ich immer noch separat in das Textfeld klicken damit ich editieren kann.
 
Ich frage deswegen, weil in mein Code muss ich immer noch separat in das Textfeld klicken damit ich editieren kann.
Das kann ich nicht nachvollziehen / reproduzieren. Das Textfeld wird bei mir direkt selektiert und der gesamte Text darin markiert sodass ich einfach schreiben kann. Kannst du das an einem kurzen Beispiel reproduzieren?
 
Das kann ich nicht nachvollziehen / reproduzieren. Das Textfeld wird bei mir direkt selektiert und der gesamte Text darin markiert sodass ich einfach schreiben kann. Kannst du das an einem kurzen Beispiel reproduzieren?
Ich benutze das EMF.edit Framework um das Editieren von EObjects automatisch zu supporten. An der Stelle wenn ich Doppelklicke, wird erst das Textfeld aktiv und beim erneutes anklicken wird erst das Textfeld fokusiert.

Ich bin noch nicht tief in den Code von EMF.edit eingetrungen, aber ich vermute mal, dass es zu viel macht (Drag&Drop, Cell Editing, Undo/Redo) und dann das erwartete nicht mehr macht.

Das mit dem Zugriff auf dem Textfeld wäre einen Workaround für mich gewesen, ich wüsste nur nicht wie ich dahin kommen soll.
 
Mit dem EMF.edit Framework habe ich noch nie gearbeitet und kannte es bis dato auch gar nicht.

An das Textfield zu kommen könnte etwas "hacky" werden.
Java:
treeView.setOnKeyPressed(event -> {
    if (event.getCode() == KeyCode.F2) {
        TreeItem<Node> selectedItem = treeView.getSelectionModel().getSelectedItem();
        treeView.setEditable(true);
        treeView.edit(selectedItem);

        List<javafx.scene.Node> cells = new ArrayList<>(treeView.lookupAll(".tree-cell"));

        int row = treeView.getRow(selectedItem);
        TreeCell cell = ((TreeCell) cells.get(row));

        TextField textfield = (TextField) cell.getGraphic();
        textfield.requestFocus();
        textfield.selectAll();
    }
});
Ob das funktioniert kann ich dir aber nicht sagen, weil ich noch weniger Ahnung von dem Framework habe als du ;)
 
Ich sags mal so. Man könnte das ganze auch selber bauen - so wie man es in Swing auch machen würde. Dann müsste man es nicht so machen und hätte das "Problem" nicht. Das Problem liegt da gerade weniger bei FX sondern mehr beim Fakt, dass noch ein anderes Framework dazwischen funkt. ;)
 
Mit dem EMF.edit Framework habe ich noch nie gearbeitet und kannte es bis dato auch gar nicht.

An das Textfield zu kommen könnte etwas "hacky" werden.
Java:
treeView.setOnKeyPressed(event -> {
    if (event.getCode() == KeyCode.F2) {
        TreeItem<Node> selectedItem = treeView.getSelectionModel().getSelectedItem();
        treeView.setEditable(true);
        treeView.edit(selectedItem);

        List<javafx.scene.Node> cells = new ArrayList<>(treeView.lookupAll(".tree-cell"));

        int row = treeView.getRow(selectedItem);
        TreeCell cell = ((TreeCell) cells.get(row));

        TextField textfield = (TextField) cell.getGraphic();
        textfield.requestFocus();
        textfield.selectAll();
    }
});
Ob das funktioniert kann ich dir aber nicht sagen, weil ich noch weniger Ahnung von dem Framework habe als du ;)
Grad getestet, funktioniert super. Und der obere Code funktioniert ohne EMF prima, nur mit dem Framework muss man so viel drum rum bauen, leider.

Eine Unschönheit hätte ich noch, wenn das alles eingegeben ist, will ich mit Enter das Textfeld schließen.

Ich habe das so gemacht, was ist da falsch?

Code:
        treeView.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.F2) {
                TreeItem<Object> selectedItem = treeView.getSelectionModel().getSelectedItem();
                treeView.setEditable(true);
                treeView.edit(selectedItem);

                List<javafx.scene.Node> cells = new ArrayList<>(treeView.lookupAll(".tree-cell"));

                int row = treeView.getRow(selectedItem);
                TreeCell cell = ((TreeCell) cells.get(row));

                TextField textfield = (TextField) cell.getGraphic();
                textfield.setOnKeyPressed(e->{
                    if (e.getCode() == KeyCode.ENTER) {
                       
                        //treeView.setEditable(false);
                       
                        //cell.commitEdit(textfield.getText());
                    }
                });
                textfield.requestFocus();
                textfield.selectAll();
            }
        });
Danke Robert.

Aktuell kann ich es nur verlassen wenn ich auf Tabulator drücke.
 
Das kommt jetzt ein bisschen drauf an was deine TreeView für Elemente enthält.
Wenn wir mein Beispiel von oben aufgreifen muss es so aussehen
Java:
textfield.setOnKeyPressed(e-> {
    if(e.getCode() == KeyCode.ENTER) {
        cell.commitEdit(new Node(textfield.getText()));
    }
});
EDIT:
Aus TreeCell muss noch TreeCell<Node> werden bzw eben dein Datentyp der TreeView
 
Zuletzt bearbeitet:
Das kommt jetzt ein bisschen drauf an was deine TreeView für Elemente enthält.
Wenn wir mein Beispiel von oben aufgreifen muss es so aussehen
Java:
textfield.setOnKeyPressed(e-> {
    if(e.getCode() == KeyCode.ENTER) {
        cell.commitEdit(new Node(textfield.getText()));
    }
});
EDIT:
Aus TreeCell muss noch TreeCell<Node> werden bzw eben dein Datentyp der TreeView
Anscheinend muss ich nicht das Ergebnis des Textfeldes explzit irgendwie weitergeben
Code:
        treeView.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.F2) {
                TreeItem<Object> selectedItem = treeView.getSelectionModel().getSelectedItem();
                treeView.setEditable(true);
                treeView.edit(selectedItem);

                List<javafx.scene.Node> cells = new ArrayList<>(treeView.lookupAll(".tree-cell"));

                int row = treeView.getRow(selectedItem);
                TreeCell cell = ((TreeCell) cells.get(row));

                TextField textfield = (TextField) cell.getGraphic();
                textfield.setOnKeyPressed(e->{
                    if (e.getCode() == KeyCode.ENTER) {
                        cell.commitEdit(selectedItem.getValue());
                    }
                });
                textfield.requestFocus();
                textfield.selectAll();
            }
        });
Das hier hat vollkommen ausgereicht.

Vielen Dank nochmal.
 
Passende Stellenanzeigen aus deiner Region:

Neue Themen

Oben