MBTI测试系统——java课程设计
用Java做一个MBTI测试系统
前情:网上MBTI测试系统不是题量冗杂,就是一股脑写完最后要收费,介于需求,借此java课程设计设计了一个MBTI人格测试测试系统,没用数据库,全程靠JSON文件存数据,轻量又好部署。
目录
一、项目核心要点
1. 功能定位
- 交互式MBTI答题(30道题,覆盖E/I/S/N/T/F/J/P维度)
- 自动计算维度得分+生成人格类型(比如ISTP)
- JSON文件存测试结果(替代数据库,免配置)
- ECharts可视化:个人维度占比+总体人格分布
2. 技术栈
- 语言:Java
- 界面:Java Swing(GUI界面
- 数据存储:JSON(Gson解析)
- 可视化:ECharts 5.x
- 工具:IDEA + Git
3. 包结构(分层解耦)
com.mbti
├─ entity // 实体类:TestResult(测试结果)、MBTIDimension(维度得分)
├─ dao // 数据层:ResultDao(JSON文件读写)
├─ gui // 界面层:TestFrame(答题界面)、ResultFrame(结果界面)
├─ chart // 可视化层:EChartsUtil(生成图表HTML)
└─ util // 工具类:FileUtil(文件操作)

图1.1项目具体分包结构
二、核心代码实现
1. JSON文件使用(替代数据库)
用ResultDao类操作桌面的mbti_results.json文件,实现结果的增删查:
package com.mbti.dao;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.mbti.entity.TestResult;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class ResultDao {
// 固定存桌面,跨环境通用
private static final String JSON_PATH =
System.getProperty("user.home") + "/Desktop/mbti_results.json";
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
// 查:读取所有测试结果
public List<TestResult> readAllResults() {
File file = new File(JSON_PATH);
if (!file.exists()) return new ArrayList<>();
try (FileReader reader = new FileReader(file, StandardCharsets.UTF_8)) {
return gson.fromJson(reader, new TypeToken<List<TestResult>>() {}.getType());
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
}
}
// 增:写入新测试结果
public void writeResult(TestResult result) {
List<TestResult> results = readAllResults();
results.add(result);
try (FileWriter writer = new FileWriter(JSON_PATH, StandardCharsets.UTF_8)) {
gson.toJson(results, writer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
2. 答题逻辑以及四个不同维度得分计算
在TestFrame(答题界面)里收集答案,计算E/I/S/N/T/F/J/P得分:
package com.mbti.gui;
import com.mbti.entity.MBTIDimension;
import com.mbti.entity.TestResult;
import com.mbti.dao.ResultDao;
import com.mbti.chart.EChartsUtil;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class TestFrame extends JFrame {
private final List<String> answers = new ArrayList<>();
// MBTI题目(示例,实际30题)
private final String[][] questions = {
{"你更爱独处?", "I", "E"},
{"你关注细节?", "S", "N"}
};
private int currentQ = 0;
public TestFrame() {
initUI();
showQuestion();
}
private void initUI() {
setTitle("MBTI测试");
setSize(600, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new BorderLayout());
}
// 展示题目
private void showQuestion() {
getContentPane().removeAll();
JLabel qLabel = new JLabel((currentQ+1)+". "+questions[currentQ][0]);
JButton opt1 = new JButton("选项A");
JButton opt2 = new JButton("选项B");
// 选项点击事件
opt1.addActionListener(e -> {
answers.add(questions[currentQ][1]);
nextQuestion();
});
opt2.addActionListener(e -> {
answers.add(questions[currentQ][2]);
nextQuestion();
});
add(qLabel, BorderLayout.NORTH);
add(opt1, BorderLayout.WEST);
add(opt2, BorderLayout.EAST);
revalidate();
}
// 下一题/提交
private void nextQuestion() {
currentQ++;
if (currentQ < questions.length) {
showQuestion();
} else {
// 计算得分
MBTIDimension dim = calculateDimension();
TestResult result = new TestResult(dim, getMbtiType(dim));
// 存JSON
new ResultDao().writeResult(result);
// 展示结果+生成图表
new ResultFrame(result).setVisible(true);
EChartsUtil.showMyDimensionChart(dim.getScores());
dispose();
}
}
// 计算四大维度得分
private MBTIDimension calculateDimension() {
int ei = 0, sn = 0, tf = 0, jp = 0;
for (String ans : answers) {
switch (ans) {
case "E" -> ei++; case "I" -> ei--;
case "S" -> sn++; case "N" -> sn--;
case "T" -> tf++; case "F" -> tf--;
case "J" -> jp++; case "P" -> jp--;
}
}
return new MBTIDimension(ei, sn, tf, jp);
}
// 生成MBTI类型(比如ISTP)
private String getMbtiType(MBTIDimension dim) {
String ei = dim.getEi() > 0 ? "E" : "I";
String sn = dim.getSn() > 0 ? "S" : "N";
String tf = dim.getTf() > 0 ? "T" : "F";
String jp = dim.getJp() > 0 ? "J" : "P";
return ei + sn + tf + jp;
}
}
3. ECharts可视化(生成HTML即为跳转网页展示)
用EChartsUtil拼HTML模板,生成维度占比图
package com.mbti.chart;
import javax.swing.*;
import java.awt.Desktop;
import java.io.File;
import java.io.FileWriter;
import java.nio.charset.StandardCharsets;
public class EChartsUtil {
// 生成个人维度占比图
public static void showMyDimensionChart(int[] scores) {
String html = "<!DOCTYPE html><html>" +
"<head><meta charset='UTF-8'><script src='https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js'></script></head>" +
"<body><div id='chart' style='width:800px;height:600px;margin:0 auto'></div>" +
"<script>" +
"var chart = echarts.init(document.getElementById('chart'));" +
"var option = {" +
" title: {text: '你的MBTI维度占比'}, " +
" xAxis: {data: ['E/I', 'S/N', 'T/F', 'J/P']}, " +
" yAxis: {type: 'value'}, " +
" series: [{type: 'bar', data: ["+scores[0]+","+scores[1]+","+scores[2]+","+scores[3]+"]}]" +
"};" +
"chart.setOption(option);" +
"</script></body></html>";
// 写HTML到桌面
String path = System.getProperty("user.home") + "/Desktop/my_mbti.html";
try (FileWriter writer = new FileWriter(path, StandardCharsets.UTF_8)) {
writer.write(html);
// 自动打开
Desktop.getDesktop().open(new File(path));
} catch (Exception e) {
JOptionPane.showMessageDialog(null, "图表生成失败:"+e.getMessage());
}
}
}
三、项目亮点
- JSON替代数据库:免安装、轻量,直接存桌面,IDEA/JAR运行都能读
- ECharts可视化:不用Java原生图表,前端可视化更美观
- Swing界面交互:答题流程丝滑,按钮/题目切换无卡顿
- 面向对象设计:分层包结构,后续修改代码定位更加便捷
四、效果展示
- 答题界面:简洁选项,自动切换题目
- 结果界面:显示人格类型+鼓励语
- 图表界面:桌面生成HTML,打开是ECharts柱状图

图2.1进入系统的首要介绍界面

图2.2答题界面

图2.3页面跳转,可视化人格各维度占比

图2.4参与过测试的所有人的人格占比,不会有有信息显示,直观占比
五、学习心得
- 初步选择的是文件存储,用 JSON 直接存储在桌面,跨 Windows/macOS 系统运行无压力,Gson 解析更加简洁,更适合小型桌面单机程序的轻量化需求
- 分层设计:将实体、数据操作、界面、可视化模块分层解耦,后期作出修改,仅需在 dao 层扩展 JSON 读写方法,无需修改其他模块代码,效率与准确定位修改时效性大幅增加
- 可视化前端的设计:不同于以往课设,想追求一个美观的可视化前端,记得老师所提及的ECharts,我选择用 ECharts 生成 HTML 文件,跳转网页,满足我所想要的可视化美观呈现
- 异常处理阶段:最为难磨的时期,JSON 文件缺失、界面乱码各种问题,先找到问题根源,一步一步解决;后续通过补充文件,找到异常弹窗相关代码修改等逻辑体系,最后成功运行到理想化程度
- 优化提升用户体验:通过JAR打包至桌面直接应用程序,其中乱码以及页面跳转问题,编码的不一致的修改,以及网页的跳转可视化,解决在如今时代下,人们很难静下心做一件事;题量相对较少,言简意赅,
可视化的面向互动,无论你是什么人格,我希望你都别被所谓的标签所束缚,做自己的主人!

浙公网安备 33010602011771号