Core Java

JavaFX TreeView Example

This is a JavaFX TreeView example. A TreeView is a control that displays hierarchical data in a tree-like structure. Each item in a TreeView is an instance of the TreeItem class. The following example creates and displays a TreeView with different kinds of vehicles.

The TreeView class is defined in the javafx.scene.control package of the JavaFX API. The following examples uses Java SE 7 and JavaFX 2.2.

This article’s example is built in four steps.

  • The first example shows, how a TreeView is created
  • The second example handles TreeItem Events
  • The third example shows, how the cells in a TreeView can be editable
  • The fourth example describes, how items in a tree can be added or removed

1. The TreeViewHelper Class

This is a helper class. This:

  • Creates the Items
  • Constructs the TreeView Structure

1.1. The Code

TreeViewHelper.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
import java.util.ArrayList;
import javafx.scene.control.TreeItem;
 
public class TreeViewHelper
{
    public TreeViewHelper()
    {
    }
     
    // This method creates an ArrayList of TreeItems (Products)
    public ArrayList<TreeItem> getProducts()
    {
        ArrayList<TreeItem> products = new ArrayList<TreeItem>();
         
        TreeItem cars = new TreeItem("Cars");
        cars.getChildren().addAll(getCars());
         
        TreeItem buses = new TreeItem("Buses");
        buses.getChildren().addAll(getBuses());
 
        TreeItem trucks = new TreeItem("Trucks");
        trucks.getChildren().addAll(getTrucks());
         
        TreeItem motorbikes = new TreeItem("Motorcycles");
        motorbikes.getChildren().addAll(getMotorcycles());
         
        products.add(cars);
        products.add(buses);
        products.add(trucks);
        products.add(motorbikes);
         
        return products;
    }
 
    // This method creates an ArrayList of TreeItems (Cars)
    private ArrayList<TreeItem> getCars()
    {
        ArrayList<TreeItem> cars = new ArrayList<TreeItem>();
         
        TreeItem ferrari = new TreeItem("Ferrari");
        TreeItem porsche = new TreeItem("Porsche");
        TreeItem ford = new TreeItem("Ford");
        TreeItem mercedes = new TreeItem("Mercedes");
         
        cars.add(ferrari);
        cars.add(porsche);
        cars.add(ford);
        cars.add(mercedes);
         
        return cars;       
    }
 
    // This method creates an ArrayList of TreeItems (Buses)
    private ArrayList<TreeItem> getBuses()
    {
        ArrayList<TreeItem> buses = new ArrayList<TreeItem>();
         
        TreeItem gm = new TreeItem("GM");
        TreeItem vw = new TreeItem("VW");
        TreeItem man = new TreeItem("MAN");
        TreeItem volvo = new TreeItem("Volvo");
         
        buses.add(gm);
        buses.add(man);
        buses.add(volvo);
        buses.add(vw);
         
        return buses;      
    }
     
    // This method creates an ArrayList of TreeItems (Trucks)
    private ArrayList<TreeItem> getTrucks()
    {
        ArrayList<TreeItem> trucks = new ArrayList<TreeItem>();
         
        TreeItem scania = new TreeItem("Scania");
        TreeItem mercedes = new TreeItem("Mercedes");
        TreeItem gm = new TreeItem("GM");
        TreeItem ford = new TreeItem("Ford");
         
        trucks.add(mercedes);
        trucks.add(scania);
        trucks.add(gm);
        trucks.add(ford);
         
        return trucks;
    }
 
    // This method creates an ArrayList of TreeItems (Motorbikes)
    private ArrayList<TreeItem> getMotorcycles()
    {
        ArrayList<TreeItem> motorcycles = new ArrayList<TreeItem>();
         
        TreeItem harley = new TreeItem("Harley");
        TreeItem suzuki = new TreeItem("Suzuki");
        TreeItem ktm = new TreeItem("KTM");
        TreeItem honda = new TreeItem("Honda");
         
        motorcycles.add(harley);
        motorcycles.add(honda);
        motorcycles.add(ktm);
        motorcycles.add(suzuki);
         
        return motorcycles;
    }
}

1.2. JavaFX Classes Used for Creation of the TreeView

  • The TreeItem class is used to construct a single node of the tree

A TreeItem is categorized as a branch or leaf node. If a TreeItem contains other instances of TreeItem, which are called its children, it is called a branch node. Otherwise, it is called a leaf node.

1.3. Creation of the Tree

The following code creates the node cars and adds all objects, which are created by the getCars() – Method, to the node.

1
2
TreeItem cars = new TreeItem("Cars");
cars.getChildren().addAll(getCars());

This part will be done also for the node buses, trucks and motorcycles. Thereafter the created nodes will be added to the root node products.

2. The JavaFX TreeView Application – Step 1

This is the main program. This:

  • Creates the Gui
  • Displays the data in the TreeView
  • Allows expanding and collapsing of the nodes

The detailed description follows the code below.

2.1 The Code

FxTreeViewExample1.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import java.util.ArrayList;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
 
public class FxTreeViewExample1 extends Application
{
    public static void main(String[] args)
    {
        Application.launch(args);
    }
         
    @Override
    public void start(Stage stage)
    {
        // Create the TreeViewHelper
        TreeViewHelper helper = new TreeViewHelper();
        // Get the Products
        ArrayList<TreeItem> products = helper.getProducts();
         
        // Create the TreeView
        TreeView treeView = new TreeView();
        // Create the Root TreeItem
        TreeItem rootItem = new TreeItem("Vehicles");
        // Add children to the root
        rootItem.getChildren().addAll(products);
        // Set the Root Node
        treeView.setRoot(rootItem);
         
        // Create the VBox
        VBox root = new VBox();
        // Add the TreeView to the VBox
        root.getChildren().add(treeView);      
         
        // Create the Scene
        Scene scene = new Scene(root,400,400);
        // Add the Scene to the Stage
        stage.setScene(scene);
        // Set the Title for the Scene
        stage.setTitle("TreeView Example 1");
        // Display the stage
        stage.show();      
    }
}

2.2 JavaFx Classes used for GUI

  • The Stage class constructs the main window of the application
  • The Scene class represents the visual contents of a stage
  • The VBox class arranges its children vertically in a single column
  • The TreeView class is used to display the data in a tree-like structure
  • The TreeItem class is used to construct the root node of the tree

2.3 Create TreeView and Populate with data

The data will be created by using the TreeViewHelper class. The method getProducts() returns an ArrayList of the class TreeItem and the structure of the tree (relations) itself:

1
2
3
4
// Create the TreeViewHelper
TreeViewHelper helper = new TreeViewHelper();
// Get the Products
ArrayList<TreeItem> products = helper.getProducts();

The following code creates the TreeView and it´s root node. Thereafter, the products will be added to the root node and the root node itself will be added to the tree.

1
2
3
4
5
6
7
8
// Create the TreeView
TreeView treeView = new TreeView();
// Create the Root TreeItem
TreeItem rootItem = new TreeItem("Vehicles");
// Add children to the root
rootItem.getChildren().addAll(products);
// Set the Root Node
treeView.setRoot(rootItem);

2.4 Other Properties

The following are the default properties of the TreeView:

  • The cells in a TreeView are not editable
  • The TreeView automatically provides vertical and horizontal scrollbars when needed

2.5 The Gui

Creation of a TreeView with constant data
Example of a TreeView with constant data

3. The JavaFX TreeView Application – Step 2

The TreeView example is enhanced by handling different TreeItem-Events. A TreeItem fires events as it is modified, for example, by adding or removing children or expanding or collapsing. The following example is enriched by using the branchExpandedEvent and branchCollapsedEvent. Both events are instances of the TreeModificationEvent class.

3.1 The Code

FxTreeViewExample2.java

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import java.util.ArrayList;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeItem.TreeModificationEvent;
import javafx.scene.control.TreeView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.event.EventHandler;
 
public class FxTreeViewExample2 extends Application
{
    // Create the TextArea
    private final TextArea textArea = new TextArea();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
         
    @Override
    public void start(Stage stage)
    {
        // Create the TreeViewHelper
        TreeViewHelper helper = new TreeViewHelper();
        // Get the Products
        ArrayList<TreeItem> products = helper.getProducts();
         
        // Create the TreeView
        TreeView treeView = new TreeView();
        // Create the Root TreeItem
        TreeItem rootItem = new TreeItem("Vehicles");
        // Add children to the root
        rootItem.getChildren().addAll(products);
        // Set the Root Node
        treeView.setRoot(rootItem);
         
        // Set tree modification related event handlers (branchExpandedEvent)
        rootItem.addEventHandler(TreeItem.branchExpandedEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
        {
            @Override
            public void handle(TreeModificationEvent event)
            {
                branchExpended(event);
            }
        });
 
        // Set tree modification related event handlers (branchCollapsedEvent)
        rootItem.addEventHandler(TreeItem.branchCollapsedEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
        {
            @Override
            public void handle(TreeModificationEvent event)
            {
                branchCollapsed(event);
            }
        });
         
        // Set the preferred number of text rows
        textArea.setPrefRowCount(20);
        // Set the preferred number of text columns
        textArea.setPrefColumnCount(25);
 
        // Create the VBox
        VBox root = new VBox();
        // Add the TreeView, the Label and the TextArea to the VBox
        root.getChildren().addAll(treeView,new Label("Message Log:"), textArea);
         
        // Create the Scene
        Scene scene = new Scene(root,400,500);
        // Add the Scene to the Stage
        stage.setScene(scene);
        // Set the Title for the Scene
        stage.setTitle("TreeView Example 2");
        // Display the stage
        stage.show();      
    }
 
    // Helper Methods for the Event Handlers
    private void branchExpended(TreeItem.TreeModificationEvent event)
    {
        String nodeValue = event.getSource().getValue().toString();
        this.writeMessage("Node " + nodeValue + " expanded.");
    }
 
    private void branchCollapsed(TreeItem.TreeModificationEvent event)
    {
        String nodeValue = event.getSource().getValue().toString();
        this.writeMessage("Node " + nodeValue + " collapsed.");
    }
     
    // Method for Logging
    private void writeMessage(String msg)
    {
        this.textArea.appendText(msg + "\n");
    }  
}

3.2 Add Event Handlers for TreeItem Events

The following code adds two EventHandler of the instance TreeItem.TreeModificationEvent to the root node. The events are fired, if the user expands or collapse a node. The effect of these events is a logging entry in the TextArea.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Set tree modification related event handlers (branchExpandedEvent)
rootItem.addEventHandler(TreeItem.branchExpandedEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
{
    @Override
    public void handle(TreeModificationEvent event)
    {
        branchExpended(event);
    }
});
 
// Set tree modification related event handlers (branchCollapsedEvent)
rootItem.addEventHandler(TreeItem.branchCollapsedEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
{
    @Override
    public void handle(TreeModificationEvent event)
    {
        branchCollapsed(event);
    }
});
 
private void branchExpended(TreeItem.TreeModificationEvent event)
{
    String nodeValue = event.getSource().getValue().toString();
    this.writeMessage("Node " + nodeValue + " expanded.");
}
private void branchCollapsed(TreeItem.TreeModificationEvent event)
{
    String nodeValue = event.getSource().getValue().toString();
    this.writeMessage("Node " + nodeValue + " collapsed.");
}

3.3 Add a TextArea for displaying the effect of the Events Handlers

In this section a TextArea is defined for displaying the Messages of the EventHandlers.

1
2
3
4
5
6
7
// Create the TextArea
private final TextArea textArea = new TextArea();
 
// Set the preferred number of text rows
textArea.setPrefRowCount(20);
// Set the preferred number of text columns
textArea.setPrefColumnCount(25);

The following code represents the method, which displays the message in the TextArea.

1
2
3
4
5
// Method for Logging  
private void writeMessage(String msg)
{
    this.textArea.appendText(msg + "\n");
}

Now it is necessary, that the TextArea and a Label will be added to the VBox.

1
2
// Add the TreeView, the Label and the TextArea to the VBox
root.getChildren().addAll(treeView,new Label("Message Log:"), textArea);

3.4 The GUI

TreeView Example with EventHandlers
Example of a TreeView with EventHandlers

4. The JavaFX TreeView Application – Step 3

This TreeView example is enhanced to have editable cells.

4.1 The Code

FxTreeViewExample3.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import java.util.ArrayList;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView.EditEvent;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.control.TreeView;
import javafx.event.EventHandler;
 
public class FxTreeViewExample3 extends Application
{
    // Create the TextArea
    private final TextArea textArea = new TextArea();
     
    public static void main(String[] args)
    {
        Application.launch(args);
    }
         
    @Override
    public void start(Stage stage)
    {
        // Create the TreeViewHelper
        TreeViewHelper helper = new TreeViewHelper();
        // Get the Products
        ArrayList<TreeItem> products = helper.getProducts();
         
        // Create the TreeView
        TreeView treeView = new TreeView();
        // Create the Root TreeItem
        TreeItem rootItem = new TreeItem("Vehicles");
        // Add children to the root
        rootItem.getChildren().addAll(products);
        // Set the Root Node
        treeView.setRoot(rootItem);    
        // Make the TreeView editable
        treeView.setEditable(true);
        // Set a cell factory to use TextFieldTreeCell
        treeView.setCellFactory(TextFieldTreeCell.forTreeView());
         
        // Set editing related event handlers (OnEditStart)
        treeView.setOnEditStart(new EventHandler<TreeView.EditEvent>()
        {
            @Override
            public void handle(EditEvent event)
            {
                editStart(event);
            }
        });
 
        // Set editing related event handlers (OnEditCommit)
        treeView.setOnEditCommit(new EventHandler<TreeView.EditEvent>()
        {
            @Override
            public void handle(EditEvent event)
            {
                editCommit(event);
            }
        });
 
        // Set editing related event handlers (OnEditCancel)
        treeView.setOnEditCancel(new EventHandler<TreeView.EditEvent>()
        {
            @Override
            public void handle(EditEvent event)
            {
                editCancel(event);
            }
        });
         
        // Set the preferred number of text rows
        textArea.setPrefRowCount(15);
        // Set the preferred number of text columns
        textArea.setPrefColumnCount(25);
 
        // Create the VBox
        VBox root = new VBox();
        // Add the TreeView to the VBox
        root.getChildren().addAll(treeView,new Label("Message Log:"), textArea);
        // Create the Scene
        Scene scene = new Scene(root,400,500);
        // Add the Scene to the Stage
        stage.setScene(scene);
        // Set the Title for the Scene
        stage.setTitle("TreeView Example 3");
        // Display the stage
        stage.show();
    }
     
    // Helper Methods for the Event Handlers
    private void editStart(TreeView.EditEvent event)
    {
        writeMessage("Started editing: " + event.getTreeItem() );
    }
     
    private void editCommit(TreeView.EditEvent event)
    {
        writeMessage(event.getTreeItem() + " changed." +
                " old = " + event.getOldValue() +
                ", new = " + event.getNewValue());
    }
     
    private void editCancel(TreeView.EditEvent e)
    {
        writeMessage("Cancelled editing: " + e.getTreeItem() );
    }
     
    // Method for Logging
    private void writeMessage(String msg)
    {
        this.textArea.appendText(msg + "\n");
    }
}

4.2 Editing Data in a TreeView

A cell (node) in a TreeView can be editable. An editable cell may switch between editing and nonediting mode. In editing mode, cell data can be modified by the user. TreeView has an editable property, which can be set to true using the setEditable(true) method, as shown in the following code.

1
2
// Make the TreeView editable
treeView.setEditable(true);

4.3 Editing Data Using a TextField

A TextFieldTreeCell is rendered as a Label in nonediting mode and as a TextField in editing mode. Its forTreeView() static method returns a cell factory.

1
2
// Set a cell factory to use TextFieldTreeCell
treeView.setCellFactory(TextFieldTreeCell.forTreeView());

4.4 Event Handler

TreeView supports three types of events:

  • onEditStart
  • onEditCommit
  • onEditCancel

The onEditStart event is fired when a cell enters editing mode. The onEditCommit event is fired
when the user successfully commits the editing, for example, by pressing the Enter key in a TextField.

The following code shows an implementation of the necessary Event Handlers. In this case, a message will be written to the TextArea.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Set editing related event handlers (OnEditStart)
treeView.setOnEditStart(new EventHandler<TreeView.EditEvent>()
{
    @Override
    public void handle(EditEvent event)
    {
        editStart(event);
    }
});
 
// Set editing related event handlers (OnEditCommit)
treeView.setOnEditCommit(new EventHandler<TreeView.EditEvent>()
{
    @Override
    public void handle(EditEvent event)
    {
        editCommit(event);
    }
});
 
// Set editing related event handlers (OnEditCancel)
treeView.setOnEditCancel(new EventHandler<TreeView.EditEvent>()
{
    @Override
    public void handle(EditEvent event)
    {
        editCancel(event);
    }
});
 
// Helper Methods for the Event Handlers
private void editStart(TreeView.EditEvent event)
{
    writeMessage("Started editing: " + event.getTreeItem() );
}
 
private void editCommit(TreeView.EditEvent event)
{
    writeMessage(event.getTreeItem() + " changed." +
            " old = " + event.getOldValue() +
            ", new = " + event.getNewValue());
}
 
private void editCancel(TreeView.EditEvent e)
{
    writeMessage("Cancelled editing: " + e.getTreeItem() );
}

4.5 The Gui

Clicking a selected cell or double-clicking an unselected cell puts the cell into editing mode, which displays the cell data in a TextField.

Renaming the selected Item
Editing the selected Item

Once the cell is in editing mode, you need to click in the TextField to put the caret in the TextField so you can make changes.

Renamed the selected item
Renamed the selected item

5. The JavaFX TreeView Application – Step 4

This TreeView allows adding and removing nodes by the user.

5.1 The Code

FxTreeViewExample4.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
import java.util.ArrayList;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeItem.TreeModificationEvent;
import javafx.scene.control.TreeView.EditEvent;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.scene.control.TreeView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
 
public class FxTreeViewExample4 extends Application
{
    // Create the TreeView
    private final TreeView treeView = new TreeView();
    // Create the TextArea
    private final TextArea textArea = new TextArea();
    // Create the TextField
    private TextField textField = new TextField();
 
    public static void main(String[] args)
    {
        Application.launch(args);
    }
 
    @Override
    public void start(Stage stage)
    {
        // Create the TreeViewHelper
        TreeViewHelper helper = new TreeViewHelper();
        // Get the Products
        ArrayList<TreeItem> products = helper.getProducts();
         
        // Make the TreeView editable
        treeView.setEditable(true);
        // Set a cell factory to use TextFieldTreeCell
        treeView.setCellFactory(TextFieldTreeCell.forTreeView());
        // Select the root node
        treeView.getSelectionModel().selectFirst();
        // Create the root node and adds event handler to it
        TreeItem rootItem = new TreeItem("Vehicles");
        // Add children to the root
        rootItem.getChildren().addAll(products);
        // Set the Root Node
        treeView.setRoot(rootItem);
 
        // Set editing related event handlers (OnEditStart)
        treeView.setOnEditStart(new EventHandler<TreeView.EditEvent>()
        {
            @Override
            public void handle(EditEvent event)
            {
                editStart(event);
            }
        });
 
        // Set editing related event handlers (OnEditCommit)
        treeView.setOnEditCommit(new EventHandler<TreeView.EditEvent>()
        {
            @Override
            public void handle(EditEvent event)
            {
                editCommit(event);
            }
        });
 
        // Set editing related event handlers (OnEditCancel)
        treeView.setOnEditCancel(new EventHandler<TreeView.EditEvent>()
        {
            @Override
            public void handle(EditEvent event)
            {
                editCancel(event);
            }
        });
 
        // Set tree modification related event handlers (branchExpandedEvent)
        rootItem.addEventHandler(TreeItem.branchExpandedEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
        {
            @Override
            public void handle(TreeModificationEvent event)
            {
                branchExpended(event);
            }
        });
 
        // Set tree modification related event handlers (branchCollapsedEvent)
        rootItem.addEventHandler(TreeItem.branchCollapsedEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
        {
            @Override
            public void handle(TreeModificationEvent event)
            {
                branchCollapsed(event);
            }
        });
 
        // Set tree modification related event handlers (childrenModificationEvent)
        rootItem.addEventHandler(TreeItem.childrenModificationEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
        {
            @Override
            public void handle(TreeModificationEvent event)
            {
                childrenModification(event);
            }
        });
 
        // Create the VBox
        VBox rightPane = getRightPane();
 
        // Create the HBox
        HBox root = new HBox();
        // Set the horizontal space between each child in the HBox
        root.setSpacing(20);
        // Add the TreeView to the HBox
        root.getChildren().addAll(treeView,rightPane);
 
        // Create the Scene
        Scene scene = new Scene(root,600,500);
        // Add the Scene to the Stage
        stage.setScene(scene);
        // Set the Title for the Scene
        stage.setTitle("TreeView Example 4");
        // Display the stage
        stage.show();      
    }
 
    // This method creates a VBox and it´s components and returns it to the calling Method
    private VBox getRightPane()
    {
        // Create the addItemBtn and its corresponding Event Handler
        Button addItemBtn = new Button("Add new Item");
        addItemBtn.setOnAction(new EventHandler()
        {
            @Override
            public void handle(ActionEvent event)
            {
                addItem(textField.getText());
            }
        });
 
        // Create the removeItemBtn and its corresponding Event Handler
        Button removeItemBtn = new Button("Remove Selected Item");
        removeItemBtn.setOnAction(new EventHandler()
        {
            @Override
            public void handle(ActionEvent event)
            {
                removeItem();
            }
        });
 
        // Set the preferred number of text rows
        textArea.setPrefRowCount(15);
        // Set the preferred number of text columns
        textArea.setPrefColumnCount(25);
 
        // Create the HBox
        HBox hbox = new HBox();
        // Add Children to the HBox
        hbox.getChildren().addAll(new Label("Item:"), textField, addItemBtn);
 
        // Create the VBox
        VBox vbox = new VBox();
        // Add children to the VBox
        vbox.getChildren().addAll(new Label("Select an item to add to or remove."),hbox,removeItemBtn,
                new Label("Message Log:"), textArea);
        // Set the vertical space between each child in the VBox
        vbox.setSpacing(10);
         
        return vbox;
    }
 
 
    // Helper Method for Adding an Item
    private void addItem(String value)
    {
        if (value == null || value.trim().equals(""))
        {
            this.writeMessage("Item cannot be empty.");
            return;
        }
 
        TreeItem parent = treeView.getSelectionModel().getSelectedItem();
 
        if (parent == null)
        {
            this.writeMessage("Select a node to add this item to.");
            return;
        }
 
        // Check for duplicate
        for(TreeItem child : parent.getChildren())
        {
            if (child.getValue().equals(value))
            {
                this.writeMessage(value + " already exists under " + parent.getValue());
                return;
            }
        }
 
        TreeItem newItem = new TreeItem(value);
        parent.getChildren().add(newItem);
 
        if (!parent.isExpanded())
        {
            parent.setExpanded(true);
        }
    }
 
    // Helper Method for Removing an Item
    private void removeItem()
    {
        TreeItem item = treeView.getSelectionModel().getSelectedItem();
 
        if (item == null)
        {
            this.writeMessage("Select a node to remove.");
            return;
        }
 
        TreeItem parent = item.getParent();
        if (parent == null )
        {
            this.writeMessage("Cannot remove the root node.");
        }
        else
        {
            parent.getChildren().remove(item);
        }
    }
 
    // Helper Methods for the Event Handlers
    private void branchExpended(TreeItem.TreeModificationEvent event)
    {
        String nodeValue = event.getSource().getValue().toString();
        this.writeMessage("Node " + nodeValue + " expanded.");
    }
 
    private void branchCollapsed(TreeItem.TreeModificationEvent event)
    {
        String nodeValue = event.getSource().getValue().toString();
        this.writeMessage("Node " + nodeValue + " collapsed.");
    }
 
    private void childrenModification(TreeItem.TreeModificationEvent event)
    {
        if (event.wasAdded())
        {
            for(TreeItem item : event.getAddedChildren())
            {
                this.writeMessage("Node " + item.getValue() + " has been added.");
            }
        }
 
        if (event.wasRemoved())
        {
            for(TreeItem item : event.getRemovedChildren())
            {
                this.writeMessage("Node " + item.getValue() + " has been removed.");
            }
        }
    }
 
    private void editStart(TreeView.EditEvent event)
    {
        this.writeMessage("Started editing: " + event.getTreeItem() );
    }
 
    private void editCommit(TreeView.EditEvent event)
    {
        this.writeMessage(event.getTreeItem() + " changed." +
                " old = " + event.getOldValue() +
                ", new = " + event.getNewValue());
    }
 
    private void editCancel(TreeView.EditEvent e)
    {
        this.writeMessage("Cancelled editing: " + e.getTreeItem() );
    }
 
    // Method for Logging
    private void writeMessage(String msg)
    {
        this.textArea.appendText(msg + "\n");
    }
}

5.2 Changes for the GUI

In this example we are using a HBox for the TreeView and a VBox for Buttons, Labels, etc. The VBox represents the right Pane. There exists a Button for adding and removing an item.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// This method creates a VBox and it´s components and returns it to the calling Method
private VBox getRightPane()
{
    // Create the addItemBtn and its corresponding Event Handler
    Button addItemBtn = new Button("Add new Item");
    addItemBtn.setOnAction(new EventHandler()
    {
        @Override
        public void handle(ActionEvent event)
        {
            addItem(textField.getText());
        }
    });
 
    // Create the removeItemBtn and its corresponding Event Handler
    Button removeItemBtn = new Button("Remove Selected Item");
    removeItemBtn.setOnAction(new EventHandler()
    {
        @Override
        public void handle(ActionEvent event)
        {
            removeItem();
        }
    });
 
    // Set the preferred number of text rows
    textArea.setPrefRowCount(15);
    // Set the preferred number of text columns
    textArea.setPrefColumnCount(25);
 
    // Create the HBox
    HBox hbox = new HBox();
    // Add Children to the HBox
    hbox.getChildren().addAll(new Label("Item:"), textField, addItemBtn);
 
    // Create the VBox
    VBox vbox = new VBox();
    // Add children to the VBox
    vbox.getChildren().addAll(new Label("Select an item to add to or remove."),hbox,removeItemBtn,
            new Label("Message Log:"), textArea);
    // Set the vertical space between each child in the VBox
    vbox.setSpacing(10);
 
    return vbox;
}

In the main method it is necessary to change the code as follows:

1
2
3
4
5
6
7
8
// Create the VBox
VBox rightPane = getRightPane();
// Create the HBox
HBox root = new HBox();
// Set the horizontal space between each child in the HBox
root.setSpacing(20);
// Add the TreeView to the HBox
root.getChildren().addAll(treeView,rightPane);

5.3 Event Handler for Children Modification

Given the fact, that we want to add / remove items to / from the tree, we have to handle ChildrenModification-Events. The following code shows an example of an EventHandler, which handles an childrenModificationEvent.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Set tree modification related event handlers (childrenModificationEvent)
rootItem.addEventHandler(TreeItem.childrenModificationEvent(),new EventHandler<TreeItem.TreeModificationEvent>()
{
    @Override
    public void handle(TreeModificationEvent event)
    {
        childrenModification(event);
    }
});
 
private void childrenModification(TreeItem.TreeModificationEvent event)
{
    if (event.wasAdded())
    {
        for(TreeItem item : event.getAddedChildren())
        {
            this.writeMessage("Node " + item.getValue() + " has been added.");
        }
    }
 
    if (event.wasRemoved())
    {
        for(TreeItem item : event.getRemovedChildren())
        {
            this.writeMessage("Node " + item.getValue() + " has been removed.");
        }
    }
}

5.4 Event Handler for Action Events

An event handler of type ActionEvent is used as a button’s action event handler. The interface EventHandler is implemented for this purpose. The button’s handler property is set as button.setOnaction. This is common for both buttons in this example – add and remove.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// Create the addItemBtn and its corresponding Event Handler
Button addItemBtn = new Button("Add new Item");
addItemBtn.setOnAction(new EventHandler()
{
    @Override
    public void handle(ActionEvent event)
    {
        addItem(textField.getText());
    }
});
 
// Create the removeItemBtn and its corresponding Event Handler
Button removeItemBtn = new Button("Remove Selected Item");
removeItemBtn.setOnAction(new EventHandler()
{
    @Override
    public void handle(ActionEvent event)
    {
        removeItem();
    }
});
 
 
// Helper Method for Adding an Item
private void addItem(String value)
{
    if (value == null || value.trim().equals(""))
    {
        this.writeMessage("Item cannot be empty.");
        return;
    }
 
    TreeItem parent = treeView.getSelectionModel().getSelectedItem();
 
    if (parent == null)
    {
        this.writeMessage("Select a node to add this item to.");
        return;
    }
 
    // Check for duplicate
    for(TreeItem child : parent.getChildren())
    {
        if (child.getValue().equals(value))
        {
            this.writeMessage(value + " already exists under " + parent.getValue());
            return;
        }
    }
 
    TreeItem newItem = new TreeItem(value);
    parent.getChildren().add(newItem);
 
    if (!parent.isExpanded())
    {
        parent.setExpanded(true);
    }
}
 
// Helper Method for Removing an Item
private void removeItem()
{
    TreeItem item = treeView.getSelectionModel().getSelectedItem();
 
    if (item == null)
    {
        this.writeMessage("Select a node to remove.");
        return;
    }
 
    TreeItem parent = item.getParent();
    if (parent == null )
    {
        this.writeMessage("Cannot remove the root node.");
    }
    else
    {
        parent.getChildren().remove(item);
    }
}

5.5 The Gui

This section shows an the following examples:

  • Adding a Nw Item to the Tree
  • Removing an existing Item from the Tree

5.5.1 Add New Items

The user navigates to the node, under which he want to add a new item (children).

Adding new Item Audi to the tree
Adding new Item Audi to the tree

He writes the name into the Textield and clicks the Add button. The action creates a new TreeItem instance and adds it to the data model. The new node is added to the TreeView.

Added new Item Audi to the tree
Added new Item Audi to the tree

5.5.2 Remove Items

The user selects the node, which he want to remove.

Removing GM from the tree
Removing GM from the tree

The user clicks the Remove Selected Item button. The action deletes the selected item from the data model and from the TreeView.

Removed GM from the tree
Removed GM from the tree

6. Download Java Source Code

This was an example of javafx.scene.control.TreeView

Download
You can download the full source code of this example here: JavaFxTreeViewExample.zip

Andreas Pomarolli

Andreas has graduated from Computer Science and Bioinformatics at the University of Linz. During his studies he has been involved with a large number of research projects ranging from software engineering to data engineering and at least web engineering. His scientific focus includes the areas of software engineering, data engineering, web engineering and project management. He currently works as a software engineer in the IT sector where he is mainly involved with projects based on Java, Databases and Web Technologies.
Subscribe
Notify of
guest


This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Chuck Nelson
Chuck Nelson
4 years ago

The downloaded code does not match the code of the web page and it does not compile.

Erik
Erik
3 years ago

I get the error

java: incompatible types: java.util.ArrayList<javafx.scene.control.TreeItem> cannot be converted to java.util.ArrayList<javafx.scene.control.TreeItem<java.lang.String>>

This does not work sadly…

Back to top button