[音乐]
好,我们来看一个应用示例 就是获取建议词,我们知道输入的时候呢
经常呢可以让它自动的列出我们 想要的那种词语,我们称为是suggestion,我们先演示一下效果
请看这里,我们在文本框里面呢,输入的时候呢它会自动的
提示出我们这个想要的这个词语,我们输入中文或者输入英文都可以,那这样的程序呢
实际上我们需要呢把这个网络里面的 这种建议词呢获取实时的获取下来
并且呢显示到这个列表里头 那这个列表呢还有滚动条。
所以我们看看这个程序怎么设计
这个程序设计呢分两方面,一方面呢是界面,当然另一方面就是我们核心的
要去获取这样的建议词并且呢显示出来 那从界面的角度呢比较简单,我们整个界面呢是
extends Jframe是一个框架窗口,然后里面有两个,一个是文本框
txtInput,一个呢底下是一个列表框,嗯,这是一个列表框
这是两个主要的界面对象。
那我们看看这个界面怎么书写的 那在构造方法里面调用super
是一个标题,然后呢我们用add方法,用add方法呢 把这个文本框和列表框添加进去
那么在添加列表框的时候我们用到JScrollPane 嗯,这样一个对象呢它目的呢就是使得它自动
具有滚动条,我们讲呢JScrollPane呢很方便,把一个对象 自动加上滚动的功能。
还有呢其它的 比如说设定大小呀,设定这个嗯 关闭,可以关闭的时候退出
嗯,Visible显示出来,然后在这里边呢当然 比较重要的就是我们下面的业务逻辑,那么这里面就是有一个文本框
在输入的时候我们就要做处理,所以我们要添加一个时间处理 就addKeyListener,就键盘的这个
监听事件,那键盘的监听事件呢我们可以KeyListener 嗯用起来呢,KeyListener有好几个方法,所以我们用Adapter
更方便一点,那么Adapter我们只需要Override我们关心的 就是keyPressed就是键盘
键按掉了按下去了,并且抬起来了,就是按了一次键。
那这里面 我们做的事情是什么呢?这里面就是要从网络
去获取这个建议词,根据我们的输入获取建议词
由于网络信息的获取呢,它是一个比较耗时的操作,所以我们经常呢用线程 new
一个Thread然后呢里面有个runnable对象,我们这里呢用那 拉姆达表达式更方便一点。
好,这个线程的主体呢要做的事情就在这里 先从文本框里面得到文本,放到一个word变量里头
然后下面呢我们就fetchSuggestion就取得 变量的建议词。
那么这个取得建议词呢是一个独立的功能,所以呢我们最好呢单独写成函数
我讲的程序呢尽量多写函数,这样使得我们程序的可读性更好一些
然后等一下我们再看这个函数,我们假定了取 到了这个suggestion它是一个字符串的一个数组
然后呢我们再把这个数组呀要放到这个列表框里头去,看就是这个
列表框,那这个列表框我们在放的时候呢,要注意到这是因为我们是在线程做完了一件事- 情以后呢
要处理界面了,那我们一定要用invokelater 这个我们也讲过,invokelater里面也带一个runnable对象
那我们这里呢用一个拉姆达表达式更方便 就是去掉原先所有的列表项,然后呢设定这个listData
那就是我们这里的列表,然后updateUI呢可以把它 显示出来,更新出来。
所以这样一个过程呢就是一个线程然后呢线程
取完了以后呢再把界面更新,用到了 invokelater。
好,我们下面看了一个另外一个 事件处理,就是我们在列表框里面
如果选取了某一项那怎么办呢 所以我们就添加了一个listSelectionListener
就是选项选定了以后的 监听器,这里面呢又是一个
接口,我们这里有拉姆达表达式,这个拉姆达表达式里面呢做了些什么事呢
就是当选中了以后,我们就把这个文本框里的文本setText
取得这个列表框里边的选择的这一项放到这个文本框里头 所以这个也好理解。
主函数呢当然是new这样一个对象,也要用 invokelater,因为这是界面的事情。
好,我们下面看看核心的这个代码 就是取得建议词,取得建议词呢给定一个参数怎么去取呢?
在这里面我们首先呢函数里面 一般的说来首先要检查这个参数啊,对
特殊字要进行特殊处理,这个呢我们以后会讲的,这叫 保卫语句,guard
clause或者guard statement,就是保卫语句,所以对于这个
参数进行检查,就好像我们说你进来一个人,进到一个单位或者进到一间房间,我们首先
在进来的时候要检查这些参数啊就是 好,对特殊值呢我们做了一些特殊处理,比如说
这个词为空或者是空串,那我们做了一些 直接返回一个0,就是0个元素的数组
好,下面获取的方法呢是用了 用了这个HttpClient
,在这里面我们设的网址呢从这里呢我是从百度去获取的 当然也可以从google啊或者其他网站去获取。
这里面的参数要注意一下 参数呢,网址一般说呢参数后面都是一个问号,然后用一个变量名等于一个什么
等于后面的值呢我们一般都要用 URLEncoder.encode,就是要进行
编码,要进行编码,比如说汉字要编成百分号什么什么
同时要注意的编码的这个字符的 比如说这里用的是utf-8。
另外呢我们访问网址如果要强制让它每次访问
呢最好加上一些随机的数,使得这个网址呢每次不一样,我这里呢加一个random 好,这是关于网址。
下面我们获取,获取呢用Request.Get,然后呢
要execute,然后就returnContent().asString()就是 所以它这种是流线式操作啊,这也是很方便的。
其中呢我们注意到 用到一个addHeader,添加一些Header呢就是说我们在向
网络发起获取信息的时候我们要向它 添加一些信息,这个添加呢头信息呢
就是变量名,这里用的是cookie,cookie简单的说是我们在
向服务器发信息的时候呢,我们在本地记录了 一点点信息,下一次呢再发送到服务器
使得服务器知道我们一些信息,比如我们在购物的时候 它记住我们上次购买的东西等等,所以这个称为cookie。
所以要根据 你的需要来添加这些变量。
好 这是关于获取信息,那么获取完了以后我们下面看看 那么获取了信息呢它实际上是一个什么呢?实际上是一个文本
这个文本呢,实际上是JavaScript的文本,那这个文本里面呢 有我们所需要的信息,比如说我们用一个人去查询
然后呢它的结果呢suggestion呢是一系列的这个 文本。
所以这个文本我们想获取出来我这里呢用到一个 正则表达式,嗯,正则表达式因为它是一种模式嘛
那这个正则表达式我们要获取什么呢?从s:开始,所以我们这里正则表达式是一个,s:
然后呢一个[,那要注意到的是
这个方括号呢就表示我们要的结果,这个方括号呢我们在写的时候正则表达式呢 因为方括号有特定含义,所以我们要用\[,
但是这个\呢,在Java这里面的字符串呢就要写成\\,所以我们
\\一个[,才表示一个真正的[。
好了这里面呢就是非[ 我们这是^\\]
*呢表示任意字,所以也就是说一个以[开始然后无数个字符,但是这个无数个字符呢
它一定不是[,然后呢 截到后面才是一个真正的[。
所以用 这样的一个方式呢我们就能用正则表达式获取到它里面的内容
然后我们用个( )括起来就表示我们要找的那个 这里呢用个replace
$1,就是一对( ) 第一对( ),也就是我们要找的这个[
]里的内容 那用正则表达式就,总的说来正则表达式目的呢是要得到这个
我们要的这个[ ]里面的内容,好,[ ]里面的内容呢
但是这个" "又不是我们需要的,所以我们这个字符串replaceAll把" "呢
替换成空,就是去掉" ",再用split 逗号分隔,那么就得到呢一系列的String的数组
所以总的来说呢我们看看这个获取的过程,先有一个网址 然后呢,再用HttpClient这个库啊
得到它,得到以后呢我们再分析和处理,那分析和处理呢用了正则表达式
和文本的替换以及呢split分隔,得到一系列这个建议词,这个建议词呢
那就用到我们上面这个程序了,添加到这个列表框里头。
所以这样一个程序呢还是很有意思的 嗯,那有的可能要问了,就说我怎么知道这些网址
怎么知道这个我要添加的一些比如说这个Header这些变量呢?
那我们就可以呢用浏览器,用各种浏览器包括IE啊
chrome浏览器,还有Firefox浏览器,这些浏览器呢它都有一个
查看这个的功能,查看这个 跟服务器通讯的功能,你就可以看到网址,也可以看到呢
跟服务端发送的这些信息,还有发送的这些信息
比如说,请看这里,我用一个浏览器 这个浏览器呢,然后我想看它这个
跟服务器的通讯过程,那一般呢我们很多浏览器呢可以按这个F12
或者说呢打开这个程序源工具,然后呢在这里面我输入网址以后
那么我每
输入一个网址呢,我们在服务端呢,它就跟服务端通讯了很多次了
那可以看到呢每一次通讯的过程,所以这里面我们可以包括
网页包括图,我们都可以看到 那每一次呢通讯呢,我们都可以从这里面看到Header的这些变量
以及呢响应的这个结果,这些呢,我们通过这个呢
就可以查看就跟服务端的通讯过程,然后我们在程序
里面呢根据需要然后来处理这些信息
那我们在回顾一下,一般说来呢这网络信息一个是要获取,然后呢
取得的字符串呢要进行处理,我们经常用正则表达式 把这些信息呢要通过界面、
布局 和事件然后放到我们的界面上面
并且呢在大部分时候呢我们都需要用线程这个工具,所以把我们前面的一些章节的内容呢
都综合到这个例子里头了。
类似的我们可以写出 大量的这种网络应用的例子