1 基本信息
1.1 系统名称
中华字典
1.2 开发运行环境
开发环境:Windows 10 专业版,JDK 1.8,AndroidStudio
运行环境:Java SE Runtime Environment (JRE) 8
1.3 使用的核心技术
JFrame:作为实现界面的窗体类,用于创建图形用户界面。
Random:用来产生随机数,为系统提供随机性支持。
Swing:用于构建丰富的图形用户界面组件。
JDBC:Java Database Connectivity,用于Java程序与数据库之间的连接。
SQL:结构化查询语言,用于管理和查询数据库。
2 系统功能设计
2.1 系统总体功能
中华字典是一款基于Java开发的字典查询系统。该系统旨在为用户提供便捷、准确的汉字、词语查询服务,支持拼音查询、部首查询等多种查询方式。同时,系统还提供了详细的词语解释、例句、同义词、反义词等扩展信息,帮助用户更深入地理解词语的含义和用法。
2.2 系统模块详细设计
2.2.1 拼音查询功能模块
用户通过输入拼音来查询对应的汉字或词语。系统根据输入的拼音在数据库中检索,并返回相关结果。结果页面将展示匹配的汉字或词语列表,并提供详细的解释、例句、同义词、反义词等信息。
2.2.2 部首查询模块功能模块
用户通过选择部首来查询含有该部首的汉字。系统根据选择的部首在数据库中检索,并返回相关结果。用户可进一步筛选查询结果,以便快速定位到所需汉字。
2.2.3 成语查询功能模块
用户通过输入成语或成语的关键词来查询相关的成语信息。系统根据输入的关键词在数据库中检索,并返回相关成语列表。用户可查看成语的解释、出处、用法示例等信息。
2.2.4 成语接龙小游戏功能模块
用户可参与成语接龙小游戏,通过输入成语的最后一个字来寻找下一个成语的开头字,以完成接龙。
3 系统实现
3.1 拼音查询功能实现
3.1.1 功能描述
用户输入拼音后,系统通过调用后端接口进行数据库查询,并将查询结果返回给前端页面进行展示。前端页面提供输入框供用户输入拼音,同时展示查询结果列表和相关解释信息。
3.1.2 核心代码
package com.example.dict;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.ExpandableListView;
import com.example.dict.adapter.SearchLeftAdapter;
import com.example.dict.bean.PinBuBean;
import com.example.dict.bean.PinBuWordBean;
import com.example.dict.db.DBManager;
import com.example.dict.utils.AssetsUtils;
import com.example.dict.utils.CommonUtils;
import com.example.dict.utils.URLUtils;
import com.google.gson.Gson;
import com.handmark.pulltorefresh.library.PullToRefreshGridView;
import java.util.ArrayList;
import java.util.List;
public class SearchPinyinActivity extends BaseSearchActivity {
String url; //获取指定拼音对应的网址
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//加载文件数据
initData(CommonUtils.FILE_PINYIN,CommonUtils.TYPE_PINYIN);
setExLvListener(CommonUtils.TYPE_PINYIN);
exLv.expandGroup(0); //默认展开第一组
word = "a"; //默认进去时获取的是第一个 a
url = URLUtils.getPinyinurl(word,page,pagesize);
// 加载网络数据
loadData(url);
setGVListener(CommonUtils.TYPE_PINYIN);
}
/**
* 网络获取失败时会调用的接口
* 因为拼音查询和部首查询使用的获取数据的方法不一样,所以需要分开写。
* 所以就把onError的方法写入到子类当中
* */
@Override
public void onError(Throwable ex, boolean isOnCallback) {
List<PinBuWordBean.ResultBean.ListBean> list = DBManager.queryPyWordFromPywordtb(word, page, pagesize);
refreshDataByGV(list);
}
}
3.1.3 运行截图
3.2 部首查询模块功能实现
3.2.1 功能描述
用户通过选择部首来查询含有该部首的汉字。系统根据选择的部首在数据库中检索,并返回相关结果。用户可进一步筛选查询结果,以便快速定位到所需汉字。
3.2.2 核心代码
package com.example.dict;
import android.os.Bundle;
import com.example.dict.bean.PinBuWordBean;
import com.example.dict.db.DBManager;
import com.example.dict.utils.CommonUtils;
import com.example.dict.utils.URLUtils;
import java.util.List;
public class SearchBuShouActivity extends BaseSearchActivity {
String url; //获取指定部首对应的网址
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 页面跳转,Title也要一起改变
titleTv.setText(R.string.main_tv_bushou);
//加载文件数据
initData(CommonUtils.FILE_BUSHOU,CommonUtils.TYPE_BUSHOU);
//开启部首的监听事件
setExLvListener(CommonUtils.TYPE_BUSHOU);
exLv.expandGroup(0); //默认展开第一组
word = "丨"; //默认进去时获取的是第一个
url = URLUtils.getBushouurl(word,page,pagesize);
// 加载网络数据
loadData(url);
setGVListener(CommonUtils.TYPE_BUSHOU);
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
List<PinBuWordBean.ResultBean.ListBean> list = DBManager.queryBsWordFromPywordtb(word, page, pagesize);
refreshDataByGV(list);
}
}
3.2.3 运行截图
3.3 成语查询模块功能实现
3.3.1 功能描述
3.3.2 核心代码
package com.example.dict;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.dict.bean.ChengyuBean;
import com.example.dict.db.DBManager;
import com.example.dict.utils.MyGridView;
import com.example.dict.utils.URLUtils;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
public class ChengyuInfoActivity extends BaseActivity {
// 页面中的是个textView
TextView ziTv1,ziTv2,ziTv3,ziTv4,pyTv,jsTv,fromTv,exampleTv,yufaTv,yinzhengTv,yinghangTv;
MyGridView tyGv,fyGv;
ImageView collectIv;
private String chengyu;
List<String> tongyiList,fanyinList; //GridView的数据源
ArrayAdapter<String> tyAdapter,fyAdapter;
// 设置标志位,表示汉字是否被收藏
boolean isCollect = false;
boolean isExist = false; //判断这个汉字是否已经存在
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chengyu_info);
initView();
initAdapter();
// 获取上一个页面传递的数据
Intent intent = getIntent();
chengyu = intent.getStringExtra("chengyu");
String url = URLUtils.getChengyuurl(chengyu);
loadData(url);
isExist = DBManager.isExistCyuInCollcyutb(chengyu);
isCollect = isExist;
setCollectIvStyle();
}
/* 根据收藏的状态,改变星星的颜色*/
private void setCollectIvStyle() {
if (isCollect) {
collectIv.setImageResource(R.mipmap.ic_collection_fs);
}else{
collectIv.setImageResource(R.mipmap.ic_collection);
}
}
/**
* 为GridView设置加载数据的适配器和数据源
*/
private void initAdapter() {
tongyiList = new ArrayList<>();
fanyinList = new ArrayList<>();
tyAdapter = new ArrayAdapter<>(this, R.layout.item_word_jslv, R.id.item_wordlv_tv, tongyiList);
fyAdapter = new ArrayAdapter<>(this, R.layout.item_word_jslv, R.id.item_wordlv_tv, fanyinList);
tyGv.setAdapter(tyAdapter);
fyGv.setAdapter(fyAdapter);
}
/** 网络数据加载成功时回调用的方法*/
@Override
public void onSuccess(String result) {
// 使用Gson反序列化映射成为javaBean
ChengyuBean bean = new Gson().fromJson(result, ChengyuBean.class);
ChengyuBean.ResultBean cyBean = bean.getResult();
if (cyBean!=null) {
// 因数据源当中不包括成语本身,但是后期要插入数据库,所以需要保存这个成语
cyBean.setChengyu(chengyu);
// 插入到数据库当中
DBManager.insertCyToCyutb(cyBean);
// 显示数据
showDataToView(cyBean);
}else{
Toast.makeText(this,"此成语无法查到,请重新查询!",Toast.LENGTH_SHORT).show();
}
}
/* 网络加载数据失败时,会调用的方法*/
@Override
public void onError(Throwable ex, boolean isOnCallback) {
// 获取数据库当中缓存的数据
ChengyuBean.ResultBean bean = DBManager.queryCyFromCyutb(chengyu);
if (bean!=null) {
showDataToView(bean);
}
}
/**
* 将获取到的数据显示在View上
* */
private void showDataToView(ChengyuBean.ResultBean cyBean) {
String chengyu = cyBean.getChengyu();
ziTv1.setText(String.valueOf(chengyu.charAt(0)));
ziTv2.setText(String.valueOf(chengyu.charAt(1)));
ziTv3.setText(String.valueOf(chengyu.charAt(2)));
ziTv4.setText(String.valueOf(chengyu.charAt(3)));
pyTv.setText("拼音 : "+cyBean.getPinyin());
jsTv.setText(cyBean.getChengyujs());
fromTv.setText(cyBean.getFrom_());
exampleTv.setText(cyBean.getExample());
yufaTv.setText(cyBean.getYufa());
yinzhengTv.setText(cyBean.getYinzhengjs());
String ciyujs = cyBean.getCiyujs();
if (!TextUtils.isEmpty(ciyujs)) {
ciyujs = ciyujs.replace("]", "\n").replace("[", "").replace(":", "");
yinghangTv.setText(ciyujs);
}
List<String> tList = cyBean.getTongyi();
// 判断是否有同义词
if (tList!=null&&tList.size()!=0) {
tongyiList.addAll(tList);
tyAdapter.notifyDataSetChanged();
}
List<String> fList = cyBean.getFanyi();
if (fList!=null&&fList.size()!=0) {
fanyinList.addAll(fList);
fyAdapter.notifyDataSetChanged();
}
}
/**
* 查找控件的方法
* */
private void initView() {
ziTv1 = findViewById(R.id.cyinfo_tv_zi1);
ziTv2 = findViewById(R.id.cyinfo_tv_zi2);
ziTv3 = findViewById(R.id.cyinfo_tv_zi3);
ziTv4 = findViewById(R.id.cyinfo_tv_zi4);
pyTv = findViewById(R.id.cyinfo_tv_py);
jsTv = findViewById(R.id.cyinfo_tv_js);
fromTv = findViewById(R.id.cyinfo_tv_from);
exampleTv = findViewById(R.id.cyinfo_tv_example);
yufaTv = findViewById(R.id.cyinfo_tv_yufa);
yinzhengTv = findViewById(R.id.cyinfo_tv_yinzheng);
yinghangTv = findViewById(R.id.cyinfo_tv_yinghan);
tyGv = findViewById(R.id.cyinfo_gv_tongyi);
fyGv = findViewById(R.id.cyinfo_gv_fanyi);
collectIv = findViewById(R.id.cyinfo_iv_collection);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.cyinfo_iv_back:
finish();
break;
case R.id.cyinfo_iv_collection:
isCollect = !isCollect;
setCollectIvStyle();
break;
}
}
protected void onDestroy() {
super.onDestroy();
if (isExist&&!isCollect) {
DBManager.deleteCyuToCollcyutb(chengyu);
}
if (!isExist&&isCollect) {
DBManager.insertCyuToCollcyutb(chengyu);
}
}
}
3.3.3 运行截图
3.4 成语接龙小游戏功能实现
3.4.1 功能描述
用户可参与成语接龙小游戏,通过输入成语的最后一个字来寻找下一个成语的开头字,以完成接龙。
3.4.2 核心代码
package com.example.dict;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.dict.BaseActivity;
import com.google.gson.Gson;
import com.example.dict.bean.ChengYuJieLongBean;
import com.example.dict.bean.ChengyuBean;
import com.example.dict.bean.WordBean;
import com.example.dict.db.DBManager;
import com.example.dict.filter.LimitInputTextWatcher;
import com.example.dict.utils.URLUtils;
public class ChengYuJieLongActivity extends BaseActivity {
EditText chengyu_et;
Button sure;
TextView word1,word2,word3,word4,word5,word6,word7,word8,timeout,level;
ImageView back;
LinearLayout chengjiebg;
char myChar[],newChar[];
String str,chengyu="";
int i=1;
Intent intent;
CountDownTimer timer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_cheng_yu_jie_long);
inital();
chengyu_et.addTextChangedListener(new LimitInputTextWatcher(chengyu_et));
intent = getIntent();
i = intent.getIntExtra("level",1);
chengyu=intent.getStringExtra("accchengyu");
if(chengyu!=""){
String url = URLUtils.getChengyujielongurl(chengyu);
loadData(url);
}
chengjiebg.setBackgroundResource(getResources().getIdentifier("gufeng"+i, "drawable", getApplicationInfo().packageName));
level.setText("关卡:"+i);
String url = URLUtils.getChengyujielongurl(str);
loadData(url);
// 设置倒计时
timer = new CountDownTimer(300000, 1000) {
public void onTick(long millisUntilFinished) {
timeout.setText(String.valueOf(millisUntilFinished / 1000));
}
public void onFinish() {
showEndingNormalDialog();
}
};
//调用 CountDownTimer 对象的 start() 方法开始倒计时,也不涉及到线程处理
timer.start();
}
public void inital(){
chengyu_et=findViewById(R.id.chengyu_et);
sure=findViewById(R.id.sure);
back=findViewById(R.id.chengyujielong_iv_back);
word1=findViewById(R.id.word_1);
word2=findViewById(R.id.word_2);
word3=findViewById(R.id.word_3);
word4=findViewById(R.id.word_4);
word5=findViewById(R.id.word_5);
word6=findViewById(R.id.word_6);
word7=findViewById(R.id.word_7);
word8=findViewById(R.id.word_8);
timeout=findViewById(R.id.timeout);
level=findViewById(R.id.level);
chengjiebg=findViewById(R.id.chengjiebg);
}
public void onClick(View view) {
switch (view.getId()){
case R.id.chengyujielong_iv_back:
Intent intent3 = new Intent(ChengYuJieLongActivity.this, MainActivity.class);
startActivity(intent3);
break;
case R.id.sure:
str=chengyu_et.getText().toString();
if(str.length()!=4){
// Toast.makeText(getApplicationContext(), "您需要输入四个汉字",
// Toast.LENGTH_SHORT).show();
Toast toast=new Toast(ChengYuJieLongActivity.this);
//创建一个填充物,用于填充Toast
LayoutInflater inflater = LayoutInflater.from(ChengYuJieLongActivity.this);
//填充物来自的xml文件,在这个改成一个view
//实现xml到view的转变哦
View view2 =inflater.inflate(R.layout.toast,null);
//不一定需要,找到xml里面的组件,设置组件里面的具体内容
ImageView imageView1=view2.findViewById(R.id.iv_toast);
TextView textView1=view2.findViewById(R.id.tv_toast);
imageView1.setImageResource(R.drawable.input);
textView1.setText("您需要输入四个汉字");
//把填充物放进toast
toast.setView(view2);
toast.setDuration(Toast.LENGTH_SHORT);
// toast位置居中
toast.setGravity(Gravity.CENTER,0,0);
//展示toast
toast.show();
}
else {
myChar = str.toCharArray();
word5.setText(Character.toString(myChar[0]));
word6.setText(Character.toString(myChar[1]));
word7.setText(Character.toString(myChar[2]));
word8.setText(Character.toString(myChar[3]));
Intent intent = new Intent(ChengYuJieLongActivity.this, IsChengYuActivity.class);
intent.putExtra("chengyu", str);
startActivityForResult(intent, 3);
break;
}
}
}
/* 网络数据加载成功时回调用的方法*/
public void onSuccess(String json) {
ChengYuJieLongBean cyjlBean = new Gson().fromJson(json, ChengYuJieLongBean.class);
ChengYuJieLongBean.ResultBean resultBean = cyjlBean.getResult();
String mychengyu=resultBean.getData().get(0);
newChar = mychengyu.toCharArray();
word1.setText(Character.toString(newChar[0]));
word2.setText(Character.toString(newChar[1]));
word3.setText(Character.toString(newChar[2]));
word4.setText(Character.toString(newChar[3]));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 3 && resultCode == RESULT_OK) {
String chengyuvalue = data.getStringExtra("chengyu");
if (chengyuvalue.equals("否")) {
Toast.makeText(getApplicationContext(), "您输入的不是成语!",
Toast.LENGTH_SHORT).show();
} else {
if(Character.toString(myChar[0]).equals(word4.getText()) && chengyuvalue.equals("是")){
// String url = URLUtils.getChengyujielongurl(str);
// loadData(url);
// Toast.makeText(getApplicationContext(), "您回答正确!", Toast.LENGTH_SHORT).show();
word5.setBackground(getResources().getDrawable(R.drawable.tianzige));
word6.setBackground(getResources().getDrawable(R.drawable.tianzige));
word7.setBackground(getResources().getDrawable(R.drawable.tianzige));
word8.setBackground(getResources().getDrawable(R.drawable.tianzige));
showNormalDialog();
}
else {
if (Integer.parseInt(timeout.getText().toString()) > 150) {
// Toast.makeText(getApplicationContext(), "您输入的成语不正确哦!还有时间哦加油加油",Toast.LENGTH_SHORT).show();
Toast toast = new Toast(getApplicationContext());
LayoutInflater inflater = LayoutInflater.from(ChengYuJieLongActivity.this);
View view2 = inflater.inflate(R.layout.toast, null);
ImageView imageView1 = view2.findViewById(R.id.iv_toast);
TextView textView1 = view2.findViewById(R.id.tv_toast);
imageView1.setImageResource(R.drawable.fighting);
textView1.setText("您输入的成语不正确哦!还有时间哦加油加油!");
toast.setView(view2);
toast.setDuration(Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
} else{
// Toast.makeText(getApplicationContext(), "您输入的成语不正确哦!",Toast.LENGTH_SHORT).show();
Toast toast = new Toast(ChengYuJieLongActivity.this);
LayoutInflater inflater = LayoutInflater.from(ChengYuJieLongActivity.this);
View view2 = inflater.inflate(R.layout.toast, null);
ImageView imageView1 = view2.findViewById(R.id.iv_toast);
TextView textView1 = view2.findViewById(R.id.tv_toast);
imageView1.setImageResource(R.drawable.wrong);
textView1.setText("您输入的成语不正确哦");
toast.setView(view2);
toast.setDuration(Toast.LENGTH_SHORT);
toast.setGravity(Gravity.CENTER, 0, 0);
toast.show();
}
}
}
}
}
private void showNormalDialog(){
/* @setIcon 设置对话框图标
* @setTitle 设置对话框标题
* @setMessage 设置对话框消息提示
* setXXX方法返回Dialog对象,因此可以链式设置属性
*/
timer.cancel();
final AlertDialog.Builder normalDialog =
new AlertDialog.Builder(ChengYuJieLongActivity.this);
normalDialog.setIcon(R.drawable.like);
normalDialog.setTitle("恭喜您通过本关");
String s=String.valueOf(300-Integer.parseInt(timeout.getText().toString()));
normalDialog.setMessage("仅用了"+s+"秒");
normalDialog.setPositiveButton("下一关",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ChengYuJieLongActivity.this, ChengYuJieLongActivity.class);
i++;
intent.putExtra("level", i);
intent.putExtra("accchengyu", str);
startActivity(intent);
}
});
normalDialog.setNegativeButton("退出游戏",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new
private void showEndingNormalDialog(){
final AlertDialog.Builder normalDialog =
new AlertDialog.Builder(ChengYuJieLongActivity.this);
normalDialog.setIcon(R.drawable.heartbroken);
normalDialog.setTitle("游戏结束啦,恭喜您通关到第"+i+"关");
normalDialog.setPositiveButton("重玩",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ChengYuJieLongActivity.this, ChengYuJieLongActivity.class);
startActivity(intent);
}
});
normalDialog.setNegativeButton("退出游戏",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(ChengYuJieLongActivity.this, MainActivity.class);
startActivity(intent);
}
});
// 显示
normalDialog.show();
}
}
3.4.3 运行截图
4 总结体会
在开发中华字典系统的过程中,我深刻体会到了Java编程的魅力和挑战性。通过设计并实现拼音查询、部首查询、成语查询等多个功能模块,我不仅提升了自己的编程能力,还加深了对数据库操作、前后端交互等技术的理解。同时,成语接龙小游戏的加入为系统增加了趣味性,也提升了用户的参与度和满意度。整个开发过程虽然充满了挑战,但收获颇丰,让我更加坚定了继续深入学习Java编程的决心。
5 附录
源码文件清单 |
Java代码、Layout布局 |