JavaFX:MVC模式学习01-使用PropertyValueFactory将模型与视图绑定

PropertyValueFactory类是“TableColumn cell value factory”,绑定创建列表中的项。示例如下:

 TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name");firstNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName"));

JavaFX在使用MVC模式绑定数据时,要注意模型中属性与视图中列的绑定。在前面的例子中,Person类是TableView视图绑定的列表的项(items),String和LocalDate是TableColumn中项数据的类型(firstName、lastName是StringProperty,birthDate是ObjectProperty)。

Person类必须是public,“First Name”是在TableView中显示的表头内容。PropertyValueFactory类的构造方法传入参数“firstName”创建实例,在列表项Person类中寻找与对应的无参属性方法firstNameProperty(方法firstNameProperty必须与传入的参数firstName对应,应该是通过反射方式进行名称对应。firstNameProperty方法可以对应任何名称的属性字段,例如firstNameABC属性字段都可以,对应的无参数属性方法为firstNameABCProperty())返回ObservableValue<String>。

如果Person类中没有与“firstName”对应的无参firstNameProperty方法,PropertyValueFactory类则会扫描Person类中是否有返回值是String类型的无参方法getFirstName()或无参方法isFirstName()(注意返回属性方法和返回String方法的命名区别,String方法已get开头)。如果有上述方法(无参方法getFirstName()或无参方法isFirstName()),则方法会被调用,返回被ReadOnlyObjectWrapper包装的值,值填充“Table Cell”。这种情况下,TableCell无法给包装的属性注册观察者观察数据变化状态。这种情况与调用firstNameProperty方法不同。
 

另:

TableView<S>是JavaFX的视图类,通过绑定模型显示。

// 类TableView构造函数。
TableView(ObservableList<S> items)TableView()

TableView绑定模型。

// 模型。
ObservableList<Person> teamMembers = FXCollections.observableArrayList(members);// 方法一:构造函数绑定模型。
TableView<Person> table = new TableView<>(teamMembers);// 方法二:方法setItems绑定模型。
TableView<Person> table = new TableView<>();
table.setItems(teamMembers);

Person类及创建模型:

 public class Person {private StringProperty firstName;public void setFirstName(String value) { firstNameProperty().set(value); }public String getFirstName() { return firstNameProperty().get(); }public StringProperty firstNameProperty() {if (firstName == null) firstName = new SimpleStringProperty(this, "firstName");return firstName;}private StringProperty lastName;public void setLastName(String value) { lastNameProperty().set(value); }public String getLastName() { return lastNameProperty().get(); }public StringProperty lastNameProperty() {if (lastName == null) lastName = new SimpleStringProperty(this, "lastName");return lastName;}public Person(String firstName, String lastName) {setFirstName(firstName);setLastName(lastName);}}// 创建模型。
List<Person> members = List.of(new Person("William", "Reed"),new Person("James", "Michaelson"),new Person("Julius", "Dean"));

将数据列与视图绑定:

 TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");firstNameCol.setCellValueFactory(new PropertyValueFactory<>(members.get(0).firstNameProperty().getName())));TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");lastNameCol.setCellValueFactory(new PropertyValueFactory<>(members.get(0).lastNameProperty().getName())));table.getColumns().setAll(firstNameCol, lastNameCol);

运行结果:

以上是JavaFX官方api示例。以下是我自己写的测试代码。

类AgeCategory,年龄段枚举:

package javafx8.ch13.tableview01;/*** @copyright 2003-2023* @author    qiao wei* @date      2023-12-30 18:19* @version   1.0* @brief     年龄段枚举。* @history   */
public enum AgeCategoryEnum {BABY,CHILD,TEEN,ADULT,SENIOR,UNKNOWN
}

Person类。

package javafx8.ch13.tableview01;import java.time.LocalDate;
import java.time.Period;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;/*** @copyright 2003-2023* @author    qiao wei* @date      2023-12-30 18:20* @version   1.0* @brief     * @history   */
public class Person {/*** @author  qiao wei* @brief   默认构造函数。* @param   * @return  * @throws  */public Person() {this("None", "None", null);}/*** @author  qiao wei* @brief   构造函数。* @param   firstName 名。* @param   lastName 姓。* @param   birthDate 出生日期。  * @return  * @throws  */public Person(String firstName,String lastName,LocalDate birthDate) {// 用户Id由系统自动生成。this.personIdProperty = new ReadOnlyIntegerWrapper(this,"personId",personSequence.incrementAndGet());this.firstNameProperty = new SimpleStringProperty(this,"firstName",firstName);this.lastNameProperty = new SimpleStringProperty(this,"lastName",lastName);this.birthDateProperty = new SimpleObjectProperty<>(this,"birthDate",birthDate);}@Overridepublic String toString() {StringBuilder stringBuilder = new StringBuilder("[personIdProperty=");stringBuilder.append(personIdProperty.get()).append(", firstNameProperty = ").append(firstNameProperty.get()).append(", lastNameProperty = ").append(lastNameProperty.get()).append(", birthDateProperty = ").append(birthDateProperty.get()).append("]");return stringBuilder.toString();}public boolean save(List<String> errorList) {boolean isSaved = false;if (isValidPerson(errorList)) {System.out.println("Saved " + this.toString());isSaved = true;}return isSaved;}public boolean isValidPerson(Person person, List<String> errorList) {boolean isValidPerson = true;String firstName = person.firstName();if (Objects.equals(firstName, null) || 0 == firstName.trim().length()) {errorList.add("First name must contain minimum one character.");isValidPerson = false;}String lastName = person.lastName();if (Objects.equals(null, lastName) || 0 == lastName.trim().length()) {errorList.add("Last name must contain minimum one character.");isValidPerson = false;}return isValidPerson;}public boolean isValidPerson(List<String> errorList) {return isValidPerson(this, errorList);}/*** @author  qiao wei* @brief   判断录入日期是否有效。* @param   * @return  * @throws  */public boolean isValidBirthDate(LocalDate date, List<String> errorList) {if (Objects.equals(null, date)) {errorList.add("Birth date is null");return false;}if (date.isAfter(LocalDate.now())) {errorList.add(LocalDate.now().toString() + " : Birth date must not be in future.");return false;}return true;}/*** @author  qiao wei* @brief   根据年龄,返回年龄层枚举值。* @param   * @return  年龄层枚举值。根据不同年龄返回不同年龄层。* @throws  */public AgeCategoryEnum ageCategory() {if (null == birthDateProperty.get()) {return AgeCategoryEnum.UNKNOWN;}int ages = Period.between(birthDateProperty.get(), LocalDate.now()).getYears();if (0 <= ages && 2 > ages) {return AgeCategoryEnum.BABY;} else if (2 <= ages && 13 > ages) {return AgeCategoryEnum.CHILD;} else if (13 <= ages && 19 >= ages) {return AgeCategoryEnum.TEEN;} else if (19 < ages && 50 >= ages) {return AgeCategoryEnum.ADULT;} else if (50 < ages) {return AgeCategoryEnum.SENIOR;} else {return AgeCategoryEnum.UNKNOWN;}}/*** @author  qiao wei* @brief   方法命名符合***Property格式,PropertyValueFactory类构造方法通过反射调用。返回值继承接*          口ObservableValue<String>。* @param   * @return  * @throws  */public ReadOnlyStringWrapper ageCategoryProperty() {if (null == birthDateProperty.get()) {return new ReadOnlyStringWrapper(AgeCategoryEnum.UNKNOWN.toString());}int ages = Period.between(birthDateProperty.get(), LocalDate.now()).getYears();if (0 <= ages && 2 > ages) {return new ReadOnlyStringWrapper(AgeCategoryEnum.BABY.toString());} else if (2 <= ages && 13 > ages) {return new ReadOnlyStringWrapper(AgeCategoryEnum.CHILD.toString());} else if (13 <= ages && 19 >= ages) {return new ReadOnlyStringWrapper(AgeCategoryEnum.TEEN.toString());} else if (19 < ages && 50 >= ages) {return new ReadOnlyStringWrapper(AgeCategoryEnum.ADULT.toString());} else if (50 < ages) {return new ReadOnlyStringWrapper(AgeCategoryEnum.SENIOR.toString());} else {return new ReadOnlyStringWrapper(AgeCategoryEnum.UNKNOWN.toString());}}public ReadOnlyIntegerProperty personIdProperty() {return personIdProperty.getReadOnlyProperty();}public int personId() {return personIdProperty.get();}public StringProperty firstNameProperty() {return firstNameProperty;}public String firstName() {return firstNameProperty.get();}public void setFirstName(String firstNameProperty) {this.firstNameProperty.set(firstNameProperty);}public StringProperty lastNameProperty() {return lastNameProperty;}public String lastName() {return lastNameProperty.get();}public void setLastName(String lastName) {this.lastNameProperty.set(lastName);}public ObjectProperty<LocalDate> birthDateProperty() {return birthDateProperty;}public LocalDate getBirthDate() {return birthDateProperty.get();}public void setBirthDate(LocalDate birthDate) {this.birthDateProperty.set(birthDate);}/*** @date   2023-07-01 21:33* @brief  Person id。只读类型。*/private final ReadOnlyIntegerWrapper personIdProperty;/*** @date   2023-12-29 11:48* @brief  用户姓。*/private final StringProperty firstNameProperty;/*** @date   2023-12-29 11:48* @author qiao wei* @brief  用户名。*/private final StringProperty lastNameProperty;/*** @date   2023-07-01 21:33* @author qiao wei* @brief  出生日期。*/private final ObjectProperty<LocalDate> birthDateProperty;/*** @date   2023-07-01 21:34* @author qiao wei* @brief  Class field. Keeps track of last generated person id.*/private static AtomicInteger personSequence = new AtomicInteger(0);
}

Person工厂类PersonTableUtil:

package javafx8.ch13.tableview01;import java.time.LocalDate;import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.PropertyValueFactory;/*** @copyright 2003-2023* @author    qiao wei* @date      2023-12-30 16:59* @version   1.0* @brief     模型类。方法getPersonList返回与视图绑定的数据项列表。方法getIdColumn,getFirstNameColumn*            getLastNameColumn以列的数据格式返回列表中各项的对应值。* @history   */
public class PersonTableUtil {/*** @author  qiao wei* @brief   默认构造方法。* @param   * @return  * @throws  */public PersonTableUtil() {}/*** @author  qiao wei* @brief   返回保存类Person实例的观察者列表ObservableList。* @param   * @return  类Person实例的观察者列表。* @throws  */public static ObservableList<Person> getPersonList() {Person p1 = new Person("Ashwin","Sharan",LocalDate.of(1972, 10, 11));Person p2 = new Person("Advik","Tim",LocalDate.of(2012, 10, 11));Person p3 = new Person("Layne","Estes",LocalDate.of(2011, 12, 16));Person p4 = new Person("Mason","Boyd",LocalDate.of(1995, 4, 20));Person p5 = new Person("Babalu","Sha",LocalDate.of(1980, 1, 10));// 返回ObservableList。return FXCollections.<Person>observableArrayList(p1, p2, p3, p4, p5);}/*** @author  qiao wei* @brief   Retrieve person Id TableColumn.* @param   * @return  Id column.* @throws  */public static TableColumn<Person, Integer> getIdColumn() {/*** 创建显示的列实例。参数Person:列绑定的数据模型。参数Integer:数据模型中数据的类型,类型必须是引用类型。*  “Id”是列表头显示的内容。*/TableColumn<Person, Integer> idColumn = new TableColumn<>("Id");// 列实例通过参数“personId”绑定模型的对应属性。idColumn.setCellValueFactory(new PropertyValueFactory<>("personId"));return idColumn;}/*** @class   PersonTableUtil* @date    2023-07-05 20:51* @author  qiao wei* @version 1.0* @brief   Retrieve first name TableColumn.* @param   * @return  First name column.* @throws*/public static TableColumn<Person, String> getFirstNameColumn() {TableColumn<Person, String> firstNameColumn = new TableColumn<>("First Name");firstNameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName1"));return firstNameColumn;}/*** @author  qiao wei* @brief   Retrieve last name TableColumn.* @param   * @return  Last name column.* @throws  */public static TableColumn<Person, String> getLastNameColumn() {TableColumn<Person, String> lastNameColumn = new TableColumn<>("Last Name");lastNameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));return lastNameColumn;}/*** @author  qiao wei* @brief   Retrieve birthdate TableColumn.* @param   * @return  Birthdate column.* @throws  */public static TableColumn<Person, LocalDate> getBirthDateColumn() {TableColumn<Person, LocalDate> birthDateColumn = new TableColumn<>("Birth Date");birthDateColumn.setCellValueFactory(new PropertyValueFactory<>("birthDate"));return birthDateColumn;}
}

运行类:

package javafx8.ch13.tableview01;import java.time.LocalDate;import javafx.application.Application;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;/*** @copyright 2003-2023* @author    qiao wei* @date      2023-12-31 11:36* @version   1.0* @brief     * @history   */
public class SimplestTableView extends Application {public SimplestTableView() {}@Overridepublic void start(Stage primaryStage) throws Exception {start03(primaryStage);}public static void main(String[] args) {try {Application.launch(SimplestTableView.class, args);} catch (Exception exception) {exception.printStackTrace();}}/*** @author  qiao wei* @brief   * @param   primaryStage 主窗体。* @return  * @throws  */private void start01(Stage primaryStage) throws Exception {// Create a TableView and bind model.TableView<Person> table = new TableView<>(PersonTableUtil.getPersonList());// Add columns to the TableView in order.table.getColumns().addAll(PersonTableUtil.getIdColumn(),PersonTableUtil.getFirstNameColumn());TableColumn<Person, String> lastNameColumn = new TableColumn<>("姓");lastNameColumn.setCellValueFactory(new PropertyValueFactory<>(PersonTableUtil.getPersonList().get(0).lastNameProperty().getName()));// Add a table column in index position.table.getColumns().add(1, PersonTableUtil.getBirthDateColumn());table.getColumns().add(2, lastNameColumn);VBox root = new VBox(table);root.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: pink;");        Scene scene = new Scene(root);primaryStage.setScene(scene);primaryStage.setTitle("Simplest TableView");primaryStage.show();}/*** @author  qiao wei* @brief   设置复合表头,占位符测试。设置表头Name中包含FirstName和LastName。当表格没有内容时,显示占位符内容。* @param   primaryStage 主窗体。* @return  * @throws  */private void start02(Stage primaryStage) throws Exception {// Create a TableView with a list of persons.TableView<Person> table = new TableView<>(PersonTableUtil.getPersonList());// Placeholder。当table没有内容显示时,显示Label内容。table.setPlaceholder(new Label("No visible columns and/or data exist."));// Setup nest table header.TableColumn<Person, String> nameColumn = new TableColumn<>("Name");nameColumn.getColumns().addAll(PersonTableUtil.getFirstNameColumn(),PersonTableUtil.getLastNameColumn());// Inserts columns to the TableView.table.getColumns().addAll(PersonTableUtil.getIdColumn(), nameColumn);/*** 在指定列添加列表信息,列从0开始计数。列FirstName和列LastName设置在复合表头,只算一列。所以插入* “出生日期”列只能在0~2列。*/table.getColumns().add(2, PersonTableUtil.getBirthDateColumn());VBox root = new VBox(table);root.setStyle("-fx-padding: 10;"+ "-fx-border-style: solid inside;"+ "-fx-border-width: 2;"+ "-fx-border-insets: 5;"+ "-fx-border-radius: 5;"+ "-fx-border-color: gray;");primaryStage.setScene(new Scene(root));primaryStage.setTitle("Simplest TableView02");primaryStage.show();}/*** @author  qiao wei* @brief   将Person实例通过getItems方法添加到模型ObservableList中。* @param   primaryStage 主窗体。* @return  * @throws  */private void start03(Stage primaryStage) throws Exception {// Create a TableView instance and set Placeholder.TableView<Person> tableView = new TableView<>(PersonTableUtil.getPersonList());tableView.setPlaceholder(new Label("No rows to display"));// 调用PersonTableUtil.getIdColumn方法,返回TableColumn<Person, Integer>。TableColumn<Person, Integer> idColumn = PersonTableUtil.getIdColumn();/*** 创建TableColumn实例,参数Person表示列中显示数据来自于那里,参数String表示显示数据的类型,参数* First Name是该列显示的列表头内容。*/TableColumn<Person, String> firstNameColumn = new TableColumn<>("First Name");
//        TableColumn<Person, String> firstNameColumn = PersonTableUtil.getFirstNameColumn();/*** PropertyValueFactory的参数是Person对象的无参lastNameProperty方法(应该是通过反射方式),如果没* 有找到对应方法,则会按规则继续寻找对应方法绑定,具体资料见JavaFX文档。* In the example shown earlier, a second PropertyValueFactory is set on the second TableColumn* instance. The property name passed to the second PropertyValueFactory is lastName, which will* match the getter method getLastNameProperty() of the Person class.*/firstNameColumn.setCellValueFactory(new PropertyValueFactory<>("firstName"));TableColumn<Person, String> lastNameColumn = new TableColumn<>("Last Name");
//        lastNameColumn.setCellValueFactory(new PropertyValueFactory<>("lastName"));lastNameColumn.setCellValueFactory(new PropertyValueFactory<>(PersonTableUtil.getPersonList().get(0).lastNameProperty().getName()));TableColumn<Person, AgeCategoryEnum> ageCategoryColumn = new TableColumn<>("Age");ageCategoryColumn.setCellValueFactory(new PropertyValueFactory<>("ageCategory"));TableColumn<Person, LocalDate> birthDateColumn = new TableColumn<>("Birth Date");birthDateColumn.setCellValueFactory(new PropertyValueFactory<>("birthDate"));// 两种方式将数据列加入到实例tableView。依次加入和按列插入。tableView.getColumns().addAll(lastNameColumn, firstNameColumn, ageCategoryColumn, birthDateColumn);tableView.getColumns().add(0, idColumn);VBox root = new VBox(tableView);Scene scene = new Scene(root);primaryStage.setScene(scene);primaryStage.show();// 添加2个用户信息。tableView.getItems().add(new Person("John","Doe",LocalDate.of(2000, 8, 12)));tableView.getItems().add(new Person("123","ABC",LocalDate.of(1980, 10, 4)));}
}

在执行类的方法start03中,lastName的数据绑定没有直接使用字符串,而是使用属性lastNameProperty的名称字符串,随后字符串绑定方法lastNameProperty。


 

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

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

相关文章

hyper-v用命令方式创建NAT网络

文章目录 NAT 概述创建 NAT 虚拟网络配置vm的ip地址 NAT 概述 NAT 使用主计算机的 IP 地址和端口通过内部 Hyper-V 虚拟网关向虚拟机授予对网络资源的访问权限。 网络地址转换 (NAT) 是一种网络模式&#xff0c;旨在通过将一个外部 IP 地址和端口映射到更大的内部 IP 地址集来…

IIS服务器发布PHP网站

IIS服务器&#xff0c;相信开发者都不会陌生&#xff0c;它的英文全称是Internet Information Services&#xff0c;是由微软公司提供的基于运行Microsoft Windows的互联网基本服务&#xff0c;常用于Windows系统的Web项目部署&#xff0c;本篇以PHP项目为例&#xff0c;讲解如…

R_handbook_作图专题

ggplot基本作图 1 条形图 library(ggplot2) ggplot(biopics) geom_histogram(aes(x year_release),binwidth1,fill"gray") 2 堆砌柱状图 ggplot(biopics, aes(xyear_release)) geom_bar(aes(fillsubject_sex)) 3 堆砌比例柱状图 ggplot(biopics, aes(xyear_rele…

idea 出现Cannot resolve symbol ‘springframework‘解决方法

Maven手动重新加载 1&#xff09;File–>Invalidate Caches / Restart… 清理缓存&#xff0c;重启idea客户端 2&#xff09;File–>Maven–>Reload project重新从maven中加载工程依赖的组件

51单片机项目(24)——基于51单片机的温控风扇protues仿真

1.功能设计 使用传感器测量温度&#xff0c;并将温度显示在LCD1602上。如果温度超过阈值&#xff0c;那么就打开风扇&#xff0c;否则风扇不打开。&#xff08;仿真的时候&#xff0c;用直流电机模拟风扇&#xff09;。 仿真截图如下&#xff1a; 此时温度是27度&#xff0c;我…

FA组件详解

1、了解FA核心组件以及功能 &#xff08;1&#xff09;TC&#xff08;Thin Client&#xff1a;瘦终端&#xff09;&#xff1a;就是类似于机顶盒的一个小盒子&#xff0c;里面有CPU、内存、USB、MIC、HDMI等接口&#xff0c;可以理解为小型电脑&#xff0c;但是它里面是没有操作…

CSS 文字溢出:多行溢出、一行溢出

CSS 文字溢出&#xff1a;多行溢出、一行溢出 案例请点击查看文章详情。 代码如下&#xff1a; 多行溢出设置&#xff1a; .line-clamp-2{/* height: 52px;line-height: 25px; */overflow: hidden;word-break: break-all;text-overflow: ellipsis;display: -webkit-box;-webkit…

Leetcode的AC指南 —— 字符串:344. 反转字符串

摘要&#xff1a; Leetcode的AC指南 —— 字符串&#xff1a;344. 反转字符串。题目介绍&#xff1a;编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 …

【C#与Redis】--实践案例--案例 1:使用 Redis 实现缓存

在使用 Redis 实现缓存的案例中&#xff0c;我们可以使用 StackExchange.Redis 库&#xff0c;这是一个为 .NET 提供的 Redis 客户端库。以下是一个简单的使用 Redis 缓存的 C# 示例&#xff1a; 首先&#xff0c;你需要安装 StackExchange.Redis 库。可以通过 NuGet 包管理器…

python使用openpyxl操作excel

文章目录 前提读取已有excel创建一个excel工作簿对象创建excel工作簿中的工作表获取工作表第一种&#xff1a;.active 方法第二种&#xff1a;通过工作表名获取指定工作表​​​​​​第三种&#xff1a;.get_sheet_name() 修改工作表的名称数据操作写入数据按单元格写入通过指…

ArkTS语言基础入门学习-鸿蒙开发

文章目录 前言ArkTS简介统一的开发体验ArkTS语言优势ArkTS语言实战演示ArkTS语言的性能与跨平台适配ArkTS和TypeScript区别总结前言 本篇文章将深入介绍鸿蒙开发的主力语言——ArkTS语言,并通过比较传统网页开发模式和ArkTS开发模式,揭示ArkTS语言的独特之处以及其带来的开发…

2021-07-03 51单片机1.高低4位交替8次,2.从0到255,3.1+2+3+4...

缘由求老哥帮做一下单片机题。_嵌入式-CSDN问答 #include "REG52.h" bit k1; void main() {unsigned char Xd0,ss15,cs0;unsigned int ys64000;while(1){P1ss;if(ys0&&cs<8){k~k;cs;ss(k?15:240);ys64000;}} } #include "REG52.h" bit k1; v…

OpenGL ES案例学习-画板

#import "PaintView.h" #import <QuartzCore/QuartzCore.h> #import <GLKit/GLKit.h> #import <OpenGLES/EAGLDrawable.h> #import "debug.h" #import "shaderUtil.h" #import "fileUtil.h" //画笔透明度 #define k…

mobilevit v3 学习笔记

目录 原理讲解:不是特别全,可供参考: torch实现代码: 有预训练:

深信服AF防火墙配置SSL VPN

防火墙版本&#xff1a;8.0.85 需提前确认防火墙是是否有SSL VPN的授权&#xff0c;确认授权用户数量 1、确认内外网接口划分 2、网络→SSL VPN&#xff0c;选择内外网接口地址 3、SSL VPN→用户管理→新增一个SSL VPN的用户 4、新增L3VPN资源&#xff0c;类型选择Other&…

【基础】【Python网络爬虫】【1.认识爬虫】什么是爬虫,爬虫分类,爬虫可以做什么

Python网络爬虫基础 认识爬虫1.什么是爬虫2.爬虫可以做什么3.为什么用 Ptyhon 爬虫4.爬虫的分类通用爬虫聚焦爬虫功能爬虫增量式爬虫分布式爬虫 5.爬虫的矛与盾&#xff08;重点&#xff09;6.盗亦有道的君子协议robots7.爬虫合法性探究 认识爬虫 1.什么是爬虫 网络爬虫&…

第5课 使用openCV捕获摄像头并实现预览功能

这节课我们开始利用ffmpeg和opencv来实现一个rtmp推流端。推流端的最基本功能其实就两个:预览画面并将画面和声音合并后推送到rtmp服务器。 一、FFmpeg API 推流的一般过程 1.引入ffmpeg库&#xff1a;在代码中引入ffmpeg库&#xff0c;以便使用其提供的功能。 2.捕获摄像头…

MongoDB的基本使用

MongoDB的引出 使用Redis技术可以有效的提高数据访问速度&#xff0c;但是由于Redis的数据格式单一性&#xff0c;无法操作结构化数据&#xff0c;当操作对象型的数据时&#xff0c;Redis就显得捉襟见肘。在保障访问速度的情况下&#xff0c;如果想操作结构化数据&#xff0c;…

Spark中的数据加载与保存

Apache Spark是一个强大的分布式计算框架&#xff0c;用于处理大规模数据。在Spark中&#xff0c;数据加载与保存是数据处理流程的关键步骤之一。本文将深入探讨Spark中数据加载与保存的基本概念和常见操作&#xff0c;包括加载不同数据源、保存数据到不同格式以及性能优化等方…

20231231_小米音箱接入GPT

参考资料&#xff1a; GitHub - yihong0618/xiaogpt: Play ChatGPT and other LLM with Xiaomi AI Speaker *.设置运行脚本权限 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned *.配置小米音箱 ()pip install miservice_fork -i https://pypi.tuna.tsinghua.edu.cn/sim…