JavaFx 用户界面控件2——ListView

news2024/12/25 9:23:33

1.列表显示ListView

下面是一个JavaFX ListView的示例代码和使用方法:

public class ListViewExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        // 创建一个可观察的列表,用于存储ListView中的数据
        ObservableList<String> items = FXCollections.observableArrayList(
                "Item 1",
                "Item 2",
                "Item 3",
                "Item 4",
                "Item 5"
        );

        // 创建ListView并将数据项设置为可观察列表
        ListView<String> listView = new ListView<>(items);

        // 设置ListView的布局
        VBox vbox = new VBox(listView);
        vbox.setPadding(new Insets(10));

        // 创建场景并将布局设置为场景根节点
        Scene scene = new Scene(vbox, 200, 200);

        // 设置舞台的标题,并将场景设置为舞台的根节点
        primaryStage.setTitle("ListView Example");
        primaryStage.setScene(scene);

        // 显示舞台
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

 这是一个简单的JavaFX应用程序,创建了一个包含多个项目的ListView。将项目添加到可观察列表中,然后将其设置为ListView的数据项。最后,将ListView加入一个VBox布局中,并通过一个Scene显示在舞台上。

1.1 JavaFX 中的 ListView 过滤

下面演示如何在 JavaFX 应用程序中过滤 ListView。两个列表由应用程序管理。一个列表包含数据模型中的所有项目。第二个列表包含当前正在查看的项目。作为过滤器存储的比较逻辑片段在两者之间进行调解。

大量使用绑定来保持数据结构与用户选择的内容同步。

此屏幕截图显示了应用程序,其中包含顶行的切换按钮(用于设置过滤器)和包含对象的列表视图。

 

数据结构

该程序以域模型 Player 和 Player 对象数组开始。

static class Player {

	private final String team;
	private final String playerName;
	public Player(String team, String playerName) {
		this.team = team;
		this.playerName = playerName;
	}
	public String getTeam() {
		return team;
	}
	public String getPlayerName() {
		return playerName;
	}
	@Override
	public String toString() { return playerName + " (" + team + ")"; }
}

Player 类包含一对字段:team 和playerName。提供了 toString(),以便将对象添加到 ListView(稍后介绍)时,不需要自定义 ListCell 类。

本例的测试数据是美国棒球运动员的列表。

Player[] players = {new Player("BOS", "David Ortiz"),
                    new Player("BOS", "Jackie Bradley Jr."),
                    new Player("BOS", "Xander Bogarts"),
                    new Player("BOS", "Mookie Betts"),
                    new Player("HOU", "Jose Altuve"),
                    new Player("HOU", "Will Harris"),
                    new Player("WSH", "Max Scherzer"),
                    new Player("WSH", "Bryce Harper"),
                    new Player("WSH", "Daniel Murphy"),
                    new Player("WSH", "Wilson Ramos") };
模型

正如文章开头提到的,ListView 过滤是围绕两个列表的管理展开的。所有对象都存储在包装的 ObservableList PlayersProperty 中,当前可查看的对象存储在包装的 FilteredList viewablePlayersProperty 中。 viewablePlayersProperty 是基于playersProperty 构建的,因此对满足 FilteredList 标准的玩家所做的更新也会对 viewablePlayers 进行。

ReadOnlyObjectProperty<ObservableList<Player>> playersProperty =
		new SimpleObjectProperty<>(FXCollections.observableArrayList());

ReadOnlyObjectProperty<FilteredList<Player>> viewablePlayersProperty =
		new SimpleObjectProperty<FilteredList<Player>>(
				new FilteredList<>(playersProperty.get()
						));

filterProperty() 可以方便地允许调用者绑定到底层谓词。

ObjectProperty<Predicate<? super Player>> filterProperty =
	viewablePlayersProperty.get().predicateProperty();

UI 根是一个 VBox,其中包含一个 ToggleButtons 的 HBox 和一个 ListView。

VBox vbox = new VBox();
vbox.setPadding( new Insets(10));
vbox.setSpacing(4);

HBox hbox = new HBox();
hbox.setSpacing( 2 );

ToggleGroup filterTG = new ToggleGroup();
过滤动作

ToggleButtons 附加了一个处理程序,它将修改 filterProperty。每个 ToggleButton 都在 userData 字段中提供一个谓词。设置过滤器属性时,toggleHandler 使用此提供的谓词。此代码设置特殊情况“显示全部”ToggleButton。

@SuppressWarnings("unchecked")
EventHandler<ActionEvent> toggleHandler = (event) -> {
		ToggleButton tb = (ToggleButton)event.getSource();
	    Predicate<Player> filter = (Predicate<Player>)tb.getUserData();
	    filterProperty.set( filter );
	};

ToggleButton tbShowAll = new ToggleButton("Show All");
tbShowAll.setSelected(true);
tbShowAll.setToggleGroup( filterTG );
tbShowAll.setOnAction(toggleHandler);
tbShowAll.setUserData( (Predicate<Player>) (Player p) -> true);

过滤特定团队的切换按钮是在运行时根据 Players 数组创建的。该流执行以下操作。

  1. 将球员列表提炼为不同的团队字符串列表

  2. 为每个团队创建一个 ToggleButton String

  3. 为每个 ToggleButton 设置一个谓词以用作过滤器

  4. 收集 ToggleButtons 以添加到 HBox 容器中

List<ToggleButton> tbs = Arrays.asList( players)
		.stream()
		.map( (p) -> p.getTeam() )
		.distinct()
		.map( (team) -> {
			ToggleButton tb = new ToggleButton( team );
			tb.setToggleGroup( filterTG );
			tb.setOnAction( toggleHandler );
			tb.setUserData( (Predicate<Player>) (Player p) -> team.equals(p.getTeam()) );
			return tb;
		})
		.collect(Collectors.toList());

hbox.getChildren().add( tbShowAll );
hbox.getChildren().addAll( tbs );
列表显示

下一步创建 ListView 并将 ListView 绑定到 viewablePlayersProperty。这使得 ListView 能够根据不断变化的过滤器接收更新。

ListView<Player> lv = new ListView<>();
lv.itemsProperty().bind( viewablePlayersProperty );

程序的其余部分创建一个场景并显示舞台。 onShown 将数据集加载到playersProperty 和viewablePlayersProperty 列表中。尽管两个列表在该特定版本的程序中是同步的,但如果库存过滤器与“无过滤器”完全不同,则无需修改此代码。

vbox.getChildren().addAll( hbox, lv );

Scene scene = new Scene(vbox);

primaryStage.setScene( scene );
		primaryStage.setOnShown((evt) -> {
			playersProperty.get().addAll( players );
		});

primaryStage.show();

 完整代码

public class FilterListApp extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        //
        // 测试数据
        //
        Player[] players = {new Player("BOS", "David Ortiz"),
                new Player("BOS", "Jackie Bradley Jr."),
                new Player("BOS", "Xander Bogarts"),
                new Player("BOS", "Mookie Betts"),
                new Player("HOU", "Jose Altuve"),
                new Player("HOU", "Will Harris"),
                new Player("WSH", "Max Scherzer"),
                new Player("WSH", "Bryce Harper"),
                new Player("WSH", "Daniel Murphy"),
                new Player("WSH", "Wilson Ramos") };

        //
        // 建立两个玩家列表和一个过滤标准的模型
        //
        ReadOnlyObjectProperty<ObservableList<Player>> playersProperty =
                new SimpleObjectProperty<>(FXCollections.observableArrayList());

        ReadOnlyObjectProperty<FilteredList<Player>> viewablePlayersProperty =
                new SimpleObjectProperty<FilteredList<Player>>(
                        new FilteredList<>(playersProperty.get()
                        ));

        ObjectProperty<Predicate<? super Player>> filterProperty =
                viewablePlayersProperty.get().predicateProperty();


        //
        // 构建UI界面
        //
        VBox vbox = new VBox();
        vbox.setPadding( new Insets(10));
        vbox.setSpacing(4);

        HBox hbox = new HBox();
        hbox.setSpacing( 2 );

        ToggleGroup filterTG = new ToggleGroup();

        //
        // toggleHandler操作将根据所选择的TB设置过滤器
        //
        @SuppressWarnings("unchecked")
        EventHandler<ActionEvent> toggleHandler = (event) -> {
            ToggleButton tb = (ToggleButton)event.getSource();
            Predicate<Player> filter = (Predicate<Player>)tb.getUserData();
            filterProperty.set( filter );
        };

        ToggleButton tbShowAll = new ToggleButton("Show All");
        tbShowAll.setSelected(true);
        tbShowAll.setToggleGroup( filterTG );
        tbShowAll.setOnAction(toggleHandler);
        tbShowAll.setUserData( (Predicate<Player>) (Player p) -> true);

        //
        // 从Player对象中创建一个不同的球队列表,然后创建ToggleButtons
        //
        //
        List<ToggleButton> tbs = Arrays.asList( players)
                .stream()
                .map( (p) -> p.getTeam() )
                .distinct()
                .map( (team) -> {
                    ToggleButton tb = new ToggleButton( team );
                    tb.setToggleGroup( filterTG );
                    tb.setOnAction( toggleHandler );
                    tb.setUserData( (Predicate<Player>) (Player p) -> team.equals(p.getTeam()) );
                    return tb;
                })
                .collect(Collectors.toList());

        hbox.getChildren().add( tbShowAll );
        hbox.getChildren().addAll( tbs );

        //
        // 创建一个绑定到viewablePlayers属性的ListView
        //
        ListView<Player> lv = new ListView<>();
        lv.itemsProperty().bind( viewablePlayersProperty );

        vbox.getChildren().addAll( hbox, lv );

        Scene scene = new Scene(vbox);

        primaryStage.setScene( scene );
        primaryStage.setOnShown((evt) -> {
            playersProperty.get().addAll( players );
        });

        primaryStage.show();

    }

    public static void main(String args[]) {
        launch(args);
    }

    static class Player {

        private final String team;
        private final String playerName;
        public Player(String team, String playerName) {
            this.team = team;
            this.playerName = playerName;
        }
        public String getTeam() {
            return team;
        }
        public String getPlayerName() {
            return playerName;
        }
        @Override
        public String toString() { return playerName + " (" + team + ")"; }
    }
}

1.2 LIstView添加和删除


首先,你需要设置一个ListView和一个ObservableList。
 

public class Main extends Application{
    ObservableList<String> data = FXCollections.observableArrayList();
    ListView<String> listView = new ListView<String>(data);

    ...
}

接下来,你可以想这样添加列表项:
 

public void addItem(String item) {
    data.add(item);
}

然后,你可以使用以下方式从列表中删除项目:

public void removeItem(String item) {
    data.remove(item);
}

 若此文档不够详细,​可以参考十分钟教你JAVAFX基础入门_哔哩哔哩_bilibili​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/761163.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【深度学习笔记】正则化与 Dropout

本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记&#xff0c;视频由网易云课堂与 deeplearning.ai 联合出品&#xff0c;主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习&#xff0c;视频的链接如下&#xff1a; 神经网络和…

如何手动初始化项目目录结构,并在命令行用gradle编译运行项目

父目录 Android 开发入门 - wuyujin1997 文章目录 Intro纯手动手动创建项目目录结构源码gradle tasksgradle wrapper执行前&#xff1a;执行后&#xff1a;执行前后对比&#xff1a; gradle wrappergradlew 和 gradlew.batplugin java编译Java项目【重点】如何通过 gradle run …

【GAMES202】Real-Time Shadows1—实时阴影1

一、Shadow Mapping回顾 [计算机图形学]光线追踪前瞻&#xff1a;阴影图(前瞻预习/复习回顾)__Yhisken的博客-CSDN博客 关于Shadow Mapping我们在GAMES101中学过&#xff0c;如果不知道可以参考我的博客。 Shadow Mapping是光栅化时为了实现阴影的一种算法&#xff0c;而它实…

python将dataframe数据导入MySQL

文章目录 mysql操作pymysql操作导入数据并启动使用pandas导入MySQL数据库连接引擎使用to_sql方法pandas读取sqlread_sql_tableread_sql_query mysql操作 创建数据库test和table create database test;CREATE TABLE car (文章ID int, 链接 VARCHAR(255), 标题 VARCHAR(255),发…

ts中setState的类型

两种方法: 例子: 父组件 const [value, setValue] useState(); <ChildsetValue{setValue} />子组件 interface Ipros {setValue: (value: string) > void } const Child: React.FC<Ipros> (props) > {}

应用层协议设计及ProtoBuf

文章目录 一、协议概述二、消息的完整性三、协议设计3.1 协议设计实例IM即时通讯的协议设计nginx协议HTTP协议redis协议 3.2 序列化方法3.3 协议安全3.4 协议压缩3.5 协议升级 四、Protobuf4.1 安装编译4.2 工作流程4.3 标量数值类型4.4 编码原理4.4.1 Varints 编码4.4.2 Zigza…

soci源码解析

结构 use_type into_type statement backend 针对不同数据库后端的抽象 session

vue对象复制(使用es6对象扩展运算符,深拷贝)

vue3es6语法 直接上代码 const objA { name: 小飞, age: 18 };const objACopy { ...objA };console.log(对比objA与objACopy的引用地址是否相同);console.log(objA objACopy); //falseconsole.log(objA);console.log(objACopy);//对象包含对象&#xff0c;浅拷贝const objB …

pytorch cv自带预训练模型再微调

参考&#xff1a; https://pytorch.org/docs/0.4.1/torchvision/models.html https://zhuanlan.zhihu.com/p/436574436 https://blog.csdn.net/u014297502/article/details/125884141 Network Top-1 error Top-5 error AlexNet 43.45 20.91 VGG-11 30.98 11.37 VGG-13 30.07 …

动态规划完全背包之518零钱兑换 II

题目&#xff1a; 给你一个整数数组 coins 表示不同面额的硬币&#xff0c;另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额&#xff0c;返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 …

【Kafka中间件】ubuntu 部署kafka,实现Django生产和消费

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、Kafka安装1.下载并安装Java2.下载和解压 Kafka3.配置 Kafka4.启动 Kafka5.创建主题和生产者/消费者6.发布和订阅消息 二、KafkaDjang…

红黑树底层原理【白话版】

一、红黑树——特殊的平衡二叉搜索树 定义&#xff1a;红黑树是一种特殊的平衡二叉搜索树。我们用它来排列数据&#xff0c;并方便以后快速检索数据。 估计看到这句话&#xff0c;你就崩溃了&#xff0c;因为这话说了等于没说。 先观察这个图。 球要不是黑色&#xff0c;要不…

console的奇妙用法

console的奇妙用法 console.log是调试 JavaScript 代码的最佳方法之一。但是本文将介绍几个与console交互的更好方法。 在vscode或者的其他ide中输入console可以看到里边提供了非常多的方法。 虽然我们通常都是用console.log&#xff0c;但是使用其他可以使调试过程变得更加容…

分布式链路追踪

文章目录 1、背景2、微服务架构下的问题3、链路追踪4、核心概念5、技术选型对比6、zipkin 1、背景 随着互联网业务快速扩展&#xff0c;软件架构也日益变得复杂&#xff0c;为了适应海量用户高并发请求&#xff0c;系统中越来越多的组件开始走向分布式化&#xff0c;如单体架构…

流水灯——FPGA

文章目录 前言一、流水灯介绍二、系统设计1.模块框图2.RTL视图 三、源码四、效果五、总结六、参考资料 前言 环境&#xff1a; 1、Quartus18.0 2、vscode 3、板子型号&#xff1a;EP4CE6F17C8 要求&#xff1a; 每隔0.2s循环亮起LED灯 一、流水灯介绍 从LED0开始亮起到LED3又回…

如何定制自己的应用层协议?|面向字节流|字节流如何解决黏包问题?如何将字节流分成数据报?

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量干货博客汇总https://blog.csdn.net/yu_cblog/c…

基于ssm的社区生活超市的设计与实现

博主介绍&#xff1a;专注于Java技术领域和毕业项目实战。专注于计算机毕设开发、定制、文档编写指导等&#xff0c;对软件开发具有浓厚的兴趣&#xff0c;工作之余喜欢钻研技术&#xff0c;关注IT技术的发展趋势&#xff0c;感谢大家的关注与支持。 技术交流和部署相关看文章…

SpringBoot拦截器

一、SpringBoot拦截器介绍 Spring Boot中的拦截器是一种用于在处理请求之前或之后执行特定操作的组件。拦截器通常用于实现对请求进行预处理、日志记录、权限验证等功能。 在Spring Boot中&#xff0c;可以使用HandlerInterceptor接口来定义自己的拦截器&#xff0c;并通过配…

流水灯实现

文章目录 一、流水灯二、代码实现三、引脚分配 一、流水灯 流水灯指的是LED像水流一样点亮&#xff0c;即LED依次点亮但不立刻熄灭&#xff0c;等到4个LED都点亮后&#xff0c;再把所有灯一次性熄灭。 二、代码实现 module horse_led(input wire clk,input wire rst_n,output…

记录管理系统

简单的记录管理系统&#xff0c;适用于保存表格数据&#xff0c;可以用来替代Excel软件保存数据&#xff0c;提供可视化拖动组件用于自定义数据列&#xff0c;数据存到数据库&#xff0c;相比于Excel&#xff0c;更易保存&#xff0c;易搜索。 例如创建合同记录数据&#xff0…