文档



JavaFX:使用JavaFX UI组件

12 列表视图

在本章中,您将学习如何在JavaFX应用程序中创建列表。

ListView类表示一个可滚动的项目列表。在酒店预订系统中,图12-1显示了可用住宿类型的列表。

图12-1 简单列表视图

简单垂直列表视图。
"图12-1 简单列表视图"的描述

您可以使用setItems方法定义列表的项目来填充列表。您还可以通过应用setCellFactory方法为列表中的项目创建视图。

创建列表视图

示例12-1中的代码片段实现了列表视图,其中显示了图12-1中的String项。

示例12-1 创建列表视图控件

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

要更改列表视图控件的大小和高度,使用setPrefHeightsetPrefWidth方法。在示例12-2中,将垂直列表限制为100像素宽和70像素高,结果如图12-2所示。

示例12-2 设置列表视图的高度和宽度

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

图12-2 调整大小的垂直列表

调整大小的列表视图对象。
图12-2 调整大小的垂直列表的描述

您可以通过将ListView对象的方向属性设置为Orientation.HORIZONTAL来使其水平排列。可以使用以下方式完成:list.setOrientation(Orientation.HORIZONTAL)。与图12-1中相同的项的水平列表显示在图12-3中。

图12-3 水平列表视图控件

图12-3的描述将在下面给出
图12-3 水平列表视图控件的描述

您可以使用SelectionModelFocusModel类来跟踪ListView对象的选择和焦点状态。使用以下方法组合来获取每个项的当前状态:

  • getSelectionModel().getSelectedIndex() - 返回单选模式下当前选定项的索引

  • getSelectionModel().getSelectedItem() - 返回当前选定的项

  • getFocusModel().getFocusedIndex() - 返回当前焦点项的索引

  • getFocusModel().getFocusedItem() - 返回当前焦点项

当实例化一个ListView时,默认使用的SelectionModelMultipleSelectionModel抽象类的一个实现。然而,selectionMode属性的默认值是SelectionMode.SINGLE。要在默认的ListView实例中启用多选功能,请使用以下调用序列:

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

还要注意,MultipleSelectionModelselectedItemsselectedIndices属性,它们都是可观察的列表,可以监视以检测任何多选。

使用数据填充列表视图

示例12-1展示了最简单的填充列表视图的方法。为了增强列表的功能,你可以使用ListCell类的特定扩展,如CheckBoxListCellChoiceBoxListCellComboBoxListCellTextFieldListCell,来添加不同类型的数据。这些类为基本的列表单元格提供了额外的功能。通过为这些类实现单元格工厂,开发人员可以直接在列表视图中更改数据。

例如,默认情况下,列表单元格的内容是不可编辑的。然而,ComboBoxListCell类在列表单元格内部绘制了一个组合框。这个修改使得用户可以通过从组合框中选择来构建一个名称列表,如示例12-3所示。

示例12-3 向列表视图添加ComboBoxListCell项

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();
    }
}

示例中的粗体行调用了setCellFactory方法来重新定义列表单元格的实现。当你编译和运行这个示例时,会产生如图12-4所示的应用窗口。

图12-4 带有组合框单元格的列表视图

图12-4的描述
"图12-4 带有组合框单元格的列表视图"的描述

单元格工厂机制不仅使你能够应用列表单元格的替代实现,还可以帮助你完全自定义单元格的外观。

自定义列表视图的内容

学习以下应用程序,了解如何使用单元格工厂生成列表项。在示例12-4中显示的应用程序创建了一个颜色模式列表。

示例12-4 创建单元格工厂

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(
            "巧克力", "鲑鱼", "金色", "珊瑚", "暗紫色",
            "深金色", "浅鲑鱼", "黑色", "玫瑰棕色", "蓝色",
            "蓝紫色", "棕色");
 
    @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);
    }
}

单元格工厂生成ListCell对象。每个单元格与一个数据项关联,并呈现列表视图的一个“行”。通过setGraphic方法表示的单元格内容可以包括其他控件、文本、形状或图像。在这个应用程序中,列表单元格显示矩形。

编译和运行该应用程序会产生图12-5中显示的窗口。

图12-5 颜色模式列表

图12-5的描述
图12-5 颜色模式列表的描述

您可以滚动列表,选择和取消选择其中的任何项。您还可以扩展此应用程序,将文本标签填充为颜色模式,如下一节所示。

处理列表项选择

将应用程序代码修改为如示例12-5所示,以便在选择特定列表项时处理事件。

示例12-5 处理列表项的事件

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(
            "巧克力", "鲑鱼", "黄金", "珊瑚", "暗兰色",
            "深金色", "浅鲑鱼", "黑色", "玫瑰棕色", "蓝色",
            "蓝紫色", "棕色");
    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);
    }
}

addListener方法用于selectedItemProperty,创建一个新的监听器来处理选定项的更改。例如,如果选择了暗兰色项,标签将接收到"darkorchid"的标题,并填充相应的颜色。修改后应用程序的输出如图12-6所示。

图12-6 选择深兰花紫颜色模式

从列表中选择深兰花紫颜色。
图12-6 选择深兰花紫颜色模式的描述

相关文档  

关闭窗口

目录

JavaFX:使用JavaFX UI组件

展开 折叠