Documentation



JavaFX: Working with JavaFX UI Components

12 List View

In this chapter, you learn how to create lists in your JavaFX applications.

The ListView class represents a scrollable list of items. Figure 12-1 shows the list of available accommodation types in a hotel reservation system.

Figure 12-1 Simple List View

Simple vertical list view.
Description of "Figure 12-1 Simple List View"

You can populate the list by defining its items with the setItems method. You can also create a view for the items in the list by applying the setCellFactory method.

Creating a List View

The code fragment in Example 12-1 implements the list with the String items shown in Figure 12-1.

Example 12-1 Creating a List View Control

ListView<String> list = new ListView<>();
ObservableList<String> items =FXCollections.observableArrayList (
    "Single", "Double", "Suite", "Family App");
list.setItems(items);

To alter the size and height of the list view control, use the setPrefHeight and setPrefWidth methods. Example 12-2 constrains the vertical list to 100 pixels wide by 70 pixels high, which results in the list shown in Figure 12-2.

Example 12-2 Setting Height and Width for a List View

list.setPrefWidth(100);
list.setPrefHeight(70);

Figure 12-2 Resized Vertical List

Resized list view object.
Description of "Figure 12-2 Resized Vertical List"

You can orient a ListView object horizontally by setting the orientation property to Orientation.HORIZONTAL. This can be done as follows: list.setOrientation(Orientation.HORIZONTAL). The horizontal list with the same items as in Figure 12-1 is shown in Figure 12-3.

Figure 12-3 Horizontal List View Control

Description of Figure 12-3 follows
Description of "Figure 12-3 Horizontal List View Control"

At any time, you can track the selection and focus of the ListView object with the SelectionModel and FocusModel classes. To obtain the current state of each item, use a combination of the following methods:

  • getSelectionModel().getSelectedIndex() – Returns the index of the currently selected items in a single-selection mode

  • getSelectionModel().getSelectedItem() – Returns the currently selected item

  • getFocusModel().getFocusedIndex() – Returns the index of the currently focused item

  • getFocusModel().getFocusedItem() – Returns the currently focused item

The default SelectionModel used when instantiating a ListView is an implementation of the MultipleSelectionModel abstract class. However, the default value of the selectionMode property is SelectionMode.SINGLE. To enable multiple selection in a default ListView instance, use the following sequence of calls:

listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

Also note that MultipleSelectionModel has the selectedItems and selectedIndices properties, which are both observable lists that can be monitored to detect any multiple selections.

Populating a List View with Data

Example 12-1 shows the simplest way to populate a list view. To enhance your list, you can add data of various types by using the specific extensions of the ListCell class, such as CheckBoxListCell, ChoiceBoxListCell, ComboBoxListCell, and TextFieldListCell. These classes bring additional functionality to the basic list cell. Implementing cell factories for such classes enables developers to change data directly in the list view.

For example, the content of a list cell is not editable by default. However, the ComboBoxListCell class draws a combo box inside the list cell. This modification enables users to build a list of names by selecting them from a combo box, as shown in Example 12-3.

Example 12-3 Adding ComboBoxListCell Items to a List View

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.ComboBoxListCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
 
public class ListViewSample extends Application {
    
    public static final ObservableList names = 
        FXCollections.observableArrayList();
    public static final ObservableList data = 
        FXCollections.observableArrayList();
       
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("List View Sample");        
        
        final ListView listView = new ListView(data);
        listView.setPrefSize(200, 250);
        listView.setEditable(true);
        
        names.addAll(
             "Adam", "Alex", "Alfred", "Albert",
             "Brenda", "Connie", "Derek", "Donny", 
             "Lynne", "Myrtle", "Rose", "Rudolph", 
             "Tony", "Trudy", "Williams", "Zach"
        );
         
        for (int i = 0; i < 18; i++) {
            data.add("anonym");
        }
          
        listView.setItems(data);
        listView.setCellFactory(ComboBoxListCell.forListView(names));              
               
        StackPane root = new StackPane();
        root.getChildren().add(listView);
        primaryStage.setScene(new Scene(root, 200, 250));
        primaryStage.show();
    }
}

The bold line in the example, calls the setCellFactory method to redefine the implementation of the list cell. When you compile and run this example, it produces the application window shown in Figure 12-4.

Figure 12-4 List View with the Combo Box Cells

Description of Figure 12-4 follows
Description of "Figure 12-4 List View with the Combo Box Cells"

Not only the cell factory mechanism enables you to apply the alternative implementations of the list cells, it can help you to totally customize the appearance of the cells.

Customizing the Content of a List View

Study the following application to learn how to generate the list items by using the cell factory. The application shown in Example 12-4 creates a list of color patterns.

Example 12-4 Creating a Cell Factory

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
    
public class ListViewSample extends Application {
 
    ListView<String> list = new ListView<>();
    ObservableList<String> data = FXCollections.observableArrayList(
            "chocolate", "salmon", "gold", "coral", "darkorchid",
            "darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue",
            "blueviolet", "brown");
 
    @Override
    public void start(Stage stage) {
        VBox box = new VBox();
        Scene scene = new Scene(box, 200, 200);
        stage.setScene(scene);
        stage.setTitle("ListViewSample");
        box.getChildren().addAll(list);
        VBox.setVgrow(list, Priority.ALWAYS);
 
        list.setItems(data);
 
        list.setCellFactory((ListView<String> l) -> new ColorRectCell());
 
        stage.show();
    }
    
    static class ColorRectCell extends ListCell<String> {
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            Rectangle rect = new Rectangle(100, 20);
            if (item != null) {
                rect.setFill(Color.web(item));
                setGraphic(rect);
            }
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

The cell factory produces ListCell objects. Every cell is associated with a single data item and renders a single "row" of the list view. The content that the cell represents through the setGraphic method can include other controls, text, shapes, or images. In this application, the list cell shows rectangles.

Compiling and running the application produces the window shown in Figure 12-5.

Figure 12-5 List of Color Patterns

Description of Figure 12-5 follows
Description of "Figure 12-5 List of Color Patterns"

You can scroll through the list, selecting and deselecting any of its items. You can also extend this application to fill the text label with the color pattern as shown in the next section.

Processing the List Item Selection

Modify the application code as shown in Example 12-5 to enable processing of the event when a particular list item is selected.

Example 12-5 Processing Events for a List Item

import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.stage.Stage;
 
public class ListViewSample extends Application {
 
    ListView<String> list = new ListView<>();
    ObservableList<String> data = FXCollections.observableArrayList(
            "chocolate", "salmon", "gold", "coral", "darkorchid",
            "darkgoldenrod", "lightsalmon", "black", "rosybrown", "blue",
            "blueviolet", "brown");
    final Label label = new Label();
 
    @Override
    public void start(Stage stage) {
        VBox box = new VBox();
        Scene scene = new Scene(box, 200, 200);
        stage.setScene(scene);
        stage.setTitle("ListViewSample");
        box.getChildren().addAll(list, label);
        VBox.setVgrow(list, Priority.ALWAYS);
 
        label.setLayoutX(10);
        label.setLayoutY(115);
        label.setFont(Font.font("Verdana", 20));
 
        list.setItems(data);
 
        list.setCellFactory((ListView<String> l) -> new ColorRectCell());
 
        list.getSelectionModel().selectedItemProperty().addListener(
            (ObservableValue<? extends String> ov, String old_val, 
                String new_val) -> {
                    label.setText(new_val);
                    label.setTextFill(Color.web(new_val));
        });
        stage.show();
    }
    
    static class ColorRectCell extends ListCell<String> {
        @Override
        public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            Rectangle rect = new Rectangle(100, 20);
            if (item != null) {
                rect.setFill(Color.web(item));
                setGraphic(rect);
            } else {
                setGraphic(null);
            }
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

The addListener method called for the selectedItemProperty creates a new listener to handle changes of the selected item. If, for instance, the dark orchid item is selected, the label receives the "darkorchid" caption and is filled with the corresponding color. The output of the modified application is shown in Figure 12-6.

Figure 12-6 Selecting a Dark Orchid Color Pattern

The dark orchid color is selected from the list.
Description of "Figure 12-6 Selecting a Dark Orchid Color Pattern"

Related Documentation  

Close Window

Table of Contents

JavaFX: Working with JavaFX UI Components

Expand | Collapse