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

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.

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

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:

// 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.

// 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

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.

// 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.

// 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.

// 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.

// 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

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.

// 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.

// 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.

// 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

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.

// 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:

// 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.

// 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.

// 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
3 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