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; //获取指定拼音对应的网址@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//加载文件数据initData(CommonUtils.FILE_PINYIN,CommonUtils.TYPE_PINYIN);setExLvListener(CommonUtils.TYPE_PINYIN);exLv.expandGroup(0); //默认展开第一组word = "a"; //默认进去时获取的是第一个 aurl = URLUtils.getPinyinurl(word,page,pagesize);// 加载网络数据loadData(url);setGVListener(CommonUtils.TYPE_PINYIN);}/*** 网络获取失败时会调用的接口* 因为拼音查询和部首查询使用的获取数据的方法不一样,所以需要分开写。* 所以就把onError的方法写入到子类当中* */@Overridepublic 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; //获取指定部首对应的网址@Overrideprotected 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);}@Overridepublic 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 {// 页面中的是个textViewTextView 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; //判断这个汉字是否已经存在@Overrideprotected 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);}/** 网络数据加载成功时回调用的方法*/@Overridepublic void onSuccess(String result) {// 使用Gson反序列化映射成为javaBeanChengyuBean 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();}}/* 网络加载数据失败时,会调用的方法*/@Overridepublic 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;@Overrideprotected 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);//创建一个填充物,用于填充ToastLayoutInflater 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("您需要输入四个汉字");//把填充物放进toasttoast.setView(view2);toast.setDuration(Toast.LENGTH_SHORT);// toast位置居中toast.setGravity(Gravity.CENTER,0,0);//展示toasttoast.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]));}@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {Intent intent = newprivate void showEndingNormalDialog(){final AlertDialog.Builder normalDialog =new AlertDialog.Builder(ChengYuJieLongActivity.this);normalDialog.setIcon(R.drawable.heartbroken);normalDialog.setTitle("游戏结束啦,恭喜您通关到第"+i+"关");normalDialog.setPositiveButton("重玩",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {Intent intent = new Intent(ChengYuJieLongActivity.this, ChengYuJieLongActivity.class);startActivity(intent);}});normalDialog.setNegativeButton("退出游戏",new DialogInterface.OnClickListener() {@Overridepublic 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布局 |