项目简介:
基于java 的通讯录管理系统。
使用javafx进行界面开发设计,程序包含添加和删除分组、个人主页(含图片等个人信息等等)、增删改查个人信息、模糊搜索、打开xml文件、打开csv(有格式要求)文件、打开vCard(有格式要求)文件、导出为xml文件、导出为csv文件、导出为vCard文件以及基本的新建保存文件功能,是一个小练习。
本程序采用Intellij IDEA 2024.1平台进行开发,使用JavaFX Scene Builder 2.0辅助界面设计,jdk版本为1.8.0_281。
另外,程序中导入了pinyin4j-2.5.0.jar包以及ez-vcard-0.12.1.jar包,如果出现找不到包的问题可以自行导入。
本程序参考学习了以下内容:
JavaFX 教程 (中文) | code.makery.ch
项目结构:

项目类图:

项目代码:
1.model包:
Person
package model;
import java.io.File;
import java.time.LocalDate;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import util.LocalDateAdapter;
public class Person {
private final StringProperty groupName;//所属组
private final StringProperty personName;//名字
private final StringProperty homeAddress;//家庭地址
private final IntegerProperty postalCode;//邮编
private final StringProperty workAddress;//工作地址&&单位
private final ObjectProperty<LocalDate> birthday;//生日
private final StringProperty phonenumber;//电话号码
private final StringProperty emailadd;//邮箱
private final StringProperty extralting;//备注
private String personimage;//图片(URL)
public Person() {
this(null, null);
}
//设置一些初始数据
public Person(String groupName, String personName) {
this.groupName = new SimpleStringProperty(groupName);
this.personName = new SimpleStringProperty(personName);
this.homeAddress = new SimpleStringProperty("泰山区学牲宿舍");
this.postalCode = new SimpleIntegerProperty(1234);
this.workAddress = new SimpleStringProperty("SCAU");
this.birthday = new SimpleObjectProperty<LocalDate>(LocalDate.of(2000, 2, 4));
this.phonenumber = new SimpleStringProperty("1145145178");
this.emailadd = new SimpleStringProperty("11111@163.com");
this.extralting = new SimpleStringProperty("圆神糕首");
File file = new File("src\\resources\\images\\man.png");
String s = file.toURI().toString();
this.personimage = s;
}
public String getgroupName() {
return groupName.get();
}
public void setgroupName(String groupName) {
this.groupName.set(groupName);
}
public StringProperty groupNameProperty() {
return groupName;
}
public String getPersonName() {
return personName.get();
}
public void setPersonName(String personName) {
this.personName.set(personName);
}
public StringProperty personNameProperty() {
return personName;
}
public String getHomeAddress() {
return homeAddress.get();
}
public void setHomeAddress(String homeAddress) {
this.homeAddress.set(homeAddress);
}
public StringProperty homeAddressProperty() {
return homeAddress;
}
public int getPostalCode() {
return postalCode.get();
}
public void setPostalCode(int postalCode) {
this.postalCode.set(postalCode);
}
public IntegerProperty postalCodeProperty() {
return postalCode;
}
public String getWorkAddress() {
return workAddress.get();
}
public void setWorkAddress(String workAddress) {
this.workAddress.set(workAddress);
}
public StringProperty workAddressProperty() {
return workAddress;
}
public void setPhonenumber(String phonenumber) {this.phonenumber.set(phonenumber);}
public String getPhonenumber() {return phonenumber.get();}
public StringProperty phonenumberProperty() {return phonenumber;}
public String getEmailadd() {return emailadd.get();}
public void setEmailadd(String emailadd) {this.emailadd.set(emailadd);}
public StringProperty emailaddProperty() {return emailadd;}
public String getExtralting() {return extralting.get();}
public void setExtralting(String extralting) {this.extralting.set(extralting);}
public StringProperty extraltingProperty() {return extralting;}
public String getPersonimage() {return personimage;}
public void setPersonimage(String personimage) {this.personimage=personimage;}
@XmlJavaTypeAdapter(LocalDateAdapter.class)
public LocalDate getBirthday() {
return birthday.get();
}
public void setBirthday(LocalDate birthday) {
this.birthday.set(birthday);
}
public ObjectProperty<LocalDate> birthdayProperty() {
return birthday;
}
}
PersonListWrapper
package model;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
//读取xml文件
@XmlRootElement(name = "persons")
public class PersonListWrapper {
private List<Person> persons;
@XmlElement(name = "person")
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
}
resources包:存资源图片
util包:
DateUtil
package util;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class DateUtil {
//设置生日格式
private static final String DATE_PATTERN = "yyyy.MM.dd";
private static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern(DATE_PATTERN);
public static String format(LocalDate date) {
if (date == null) {
return null;
}
return DATE_FORMATTER.format(date);
}
public static LocalDate parse(String dateString) {
try {
return DATE_FORMATTER.parse(dateString, LocalDate::from);
} catch (DateTimeParseException e) {
return null;
}
}
public static boolean validDate(String dateString) {
return DateUtil.parse(dateString) != null;
}
}
LocalDateAdapter
package util;
import java.time.LocalDate;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class LocalDateAdapter extends XmlAdapter<String, LocalDate> {
@Override
public LocalDate unmarshal(String v) throws Exception {
return LocalDate.parse(v);
}
@Override
public String marshal(LocalDate v) throws Exception {
return v.toString();
}
}
view包:
ChangeHanziToPinyin
package view;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
public class ChangeHanziToPinyin {
public static String getPinYin(String src) {
String t4 = "";
if (src != null) {
char[] t1 = src.toCharArray();
String[] t2 = new String[t1.length];
// 设置汉字拼音输出的格式
HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();
t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);
t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
t3.setVCharType(HanyuPinyinVCharType.WITH_V);
int t0 = t1.length;
try {
for (int i = 0; i < t0; i++) {
// 判断是否为汉字字符
if (Character.toString(t1[i]).matches("[\\u4E00-\\u9FA5]+")) {
// 将汉字的几种全拼都存到t2数组中
t2 = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3);
// 取出该汉字全拼的第一种读音并连接到字符串t4后
t4 += t2[0];
} else {
// 如果不是汉字字符,直接取出字符并连接到字符串t4后
t4 += Character.toString(t1[i]);
}
}
} catch (Exception e) {
e.printStackTrace();
}
if (t4 != null && !"".equals(t4)) {
t4 = t4.toLowerCase();
}
}
return t4.toLowerCase();
}
}
MainApp
package view;
import java.io.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.prefs.Preferences;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import model.Person;
import model.PersonListWrapper;
public class MainApp extends Application {
private Stage primaryStage;//程序主页面
private BorderPane rootLayout;//背景页面、菜单
private ObservableList<Person> personData = FXCollections.observableArrayList();//运用一个集合类来存储每个联系人的数据
private List<String> personGroup = new ArrayList<>();//用一个list来存储分组数据
private String mainlygroup = " ";//当前选择的分组
private String searchNamestring ="";//当前想要查找的名字字符
private String searchPhonestring ="";//当前想要查找的电话号码字符
private boolean firststart = false;
public MainApp () {}
//将当前分组数据更新到分组list中
public void setPersonGroup(ObservableList<Person> personData){
for (Person person : personData) {
if(personGroup.isEmpty()&&!person.getgroupName().equals("None")){
personGroup.add(person.getgroupName());
}else{
if(!personGroup.contains(person.getgroupName())&&!person.getgroupName().equals("None")){
personGroup.add(person.getgroupName());
}
}
}
}
//清除分组数据
public void clearPersonGroup(){this.personGroup.clear();}
//添加分组
public void addPersonGroup(String groupName){this.personGroup.add(groupName);}
//删除分组
public void deletePersonGroup(String groupName){
for(Person person : rtPersonData()){
if(person.getgroupName().equals(groupName)){
person.setgroupName("None");
}
}
personGroup.clear();
setPersonGroup(rtPersonData());
}
//获得分组数据
public List<String> getPersonGroup(){return personGroup;}
//设置当前分组
public void setMainlygroup(String mainlygroup){this.mainlygroup = mainlygroup;}
//获取当前分组
public String getMainlygroup(){return mainlygroup;}
//获取当前程序中读取的联系人数据(副本)
public ObservableList<Person> getPersonData() {
if(mainlygroup.equals("all")&& searchNamestring.isEmpty() && searchPhonestring.isEmpty()){
return personData;
}
ObservableList<Person> personData1 = FXCollections.observableArrayList();
for(Person person : personData) {
if(searchNamestring.isEmpty() && searchPhonestring.isEmpty()){
if(person.getgroupName().equals(mainlygroup)) {
personData1.add(person);
}
}else if(searchPhonestring.isEmpty()){
if(cmp(ChangeHanziToPinyin.getPinYin(searchNamestring),ChangeHanziToPinyin.getPinYin(person.getPersonName()))){
personData1.add(person);
}
}else if(searchNamestring.isEmpty()){
if(cmp(searchPhonestring,person.getPhonenumber())){
personData1.add(person);
}
}else{
if(cmp(searchPhonestring,person.getPhonenumber())&&cmp(ChangeHanziToPinyin.getPinYin(searchNamestring),ChangeHanziToPinyin.getPinYin(person.getPersonName()))){
personData1.add(person);
}
}
}
return personData1;
}
//获取当前程序中读取的数据,可改变
public ObservableList<Person> rtPersonData(){return personData;}
//字符串对比方法,用于实现搜索功能
public boolean cmp(String searchstring, String thisname){
char [] arr = searchstring.toCharArray();
int res=0;
for(char ch : thisname.toCharArray()) {
for(char ch2 : arr) {
if(ch == ch2) {
++res;
}
}
}
if(res == 0){
return false;
}else {
return true;
}
}
//设置搜索名字
public void setSearchNamestring(String searchNamestring){this.searchNamestring = searchNamestring;}
//设置搜索电话号码
public void setSearchPhonestring(String searchPhonestring){this.searchPhonestring = searchPhonestring;}
//获取搜索名字
public String getSearchNamestring(){return searchNamestring;}
//程序启动
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("通讯录管理APP");
this.primaryStage.getIcons().add(new Image("File:src\\view\\app.png"));
//设置背景、菜单
initRootLayout();
//设置程序主界面
showPersonOverview();
}
//设置菜单和背景界面
public void initRootLayout() {
try {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("RootLayout.fxml"));//读取fxml文件,存储了可视化界面的代码
rootLayout = (BorderPane) loader.load();
if(!firststart) {
File file = getPersonFilePath();
if (file != null) {
if(file.getPath().endsWith(".xml")){
loadPersonDataFromFile(file);
}
else if(file.getPath().endsWith(".csv")){
loadPersonDataFromCSVFile(file);

这是一个基于Java的通讯录管理系统,利用JavaFX构建可视化界面。功能包括分组管理、个人信息增删改查、模糊搜索及多种文件格式的导入导出。开发环境为IntelliJ IDEA,使用JavaFX Scene Builder设计界面,依赖pinyin4j和ez-vcard库。项目提供了详细的类图和代码结构。
最低0.47元/天 解锁文章
915





