笑傲江湖之人物分析
题目:
自行下载自己最喜欢的小说1部。存储为文本文档。要求长篇小说,20万字以上。
任取其中10个人物,考虑他们的姓名、别名等等一系列因素。
(1)统计每个人在小说中出现的次数并排序。
(2)统计每个人在小说中出现的篇幅跨度(第一次出现距最后一次出现的篇幅)并排序。
(3) 如果两人在相距较短的一段文字中出现,我们认为两人有关系,距离越短,关系越近。自行设计统计标准,找出10个人中:
1)关系最紧密的两个人,关系最不紧密的两个人。
2)输入一个人名,列出该人和其他人关系的紧密程度排名。
看与实际是否符合?如果不太符合,说明可能的原因。
运行环境:
程序设计语言:java
操作系统:windows 8
编程工具:eclipse
解题思路:
利用java中的输入流FileInputStream将文件读入并以字符串的形式返回,然后再对字符串进行处理。 首先利用String类中的方法indexOf(),lastIndexOf(),即可以求解出每个人物出现的次数和篇幅跨度;然后划定合适的范围,先遍历到一个人物然后利用String类中的substring(beginIndex,lastIndex)方法将此人物在指定范围的这段字符串截取下来,判断是否包含另外一个人物,循环调用即可以求出两人的亲密度;
对于排序:将返回来的人物出现次数、篇幅跨度、亲密度封装到一个类中,再将此类的每个对象添加到ArrayList中,再定义一个类实现Comparator(比较器)接口,调用系统的排序方法即可以分别按出现次数、篇幅跨度、亲密度排序了;
对于结果显示:可以用表格(Jtable)将结果显示到界面中的表格上去!
具体步骤:
文件的读取:
//读取我们指定小说的源文件
String novel = "src\\输入文件\\笑傲江湖.txt";
//构造输入流对象,做为一个InputStream对象使用
//因为创建的对象是InputStream的子类的对象,我们使用父类变量引用,方便统一使用
InputStream ins = new FileInputStream(novel);
//根据流中字节的长度,创建一个byte[]数组,保存读到的数据
byte[] contentByte = new byte[ins.available()];
//将流中的数据读到数组中
ins.read(contentByte);
//将数组byte转换为字符串
String str = new String(contentByte);
return str;//返回读取到的字符串
人物出现次数:
//得到输入的字符串
String result = readNovel();
int count=0,fromIndex=0;//计算器和索引
//将字符串便利一遍
while(fromIndex<result.length()){
//找到人物在小说中第一次出现的索引
int index= result.indexOf(personName, fromIndex);
if(index==-1)break;//找不到就退出
else{
count++;//人物出现一次就加1
fromIndex= index+personName.length();//改变索引再继续遍历
;
}
}
return count;//返回人物出现的次数
人物的篇幅跨度:
//得到字符串
String result = readNovel();
//第一次出现的索引
int firstIndex=result.indexOf(personName);
//最后一次出现的索引
int lastIndex=result.lastIndexOf(personName);
//得到人物第一次和最后一次出现的跨度
int span = lastIndex-firstIndex;
//返回得到的跨度
return span;
任意两人的亲密度:
//得到输入的字符串
String result =sn.readNovel();
//定义数组来存储本人物与其他人物的亲密度
int[]count=new int[nameArray.length];
for(int i=0;i<nameArray.length;i++){
int fromIndex=100;//开始索引
if(personName_1.equals(nameArray[i])){
count[i]=0;
}else{
while(fromIndex+100<result.length()){
//找到人物在小说中指定位置出现的索引
int index= result.indexOf(personName_1, fromIndex);
if(index==-1)break;//找不到就退出
else{
String str = result.substring(index-100, index+100);
if(str.contains(nameArray[i])){
count[i]++;//人物出现一次就加1
}
fromIndex= index+100;//改变索引再继续遍历
}
将人物名字、出现次数、篇幅跨度、亲密度封装到一个类:
public class Person<T> {
//定义属性
private String name;//名字
private int appearTimes;//出现次数
private int span;//跨度
private int intimacy;//亲密度
/**
* 构造函数
* @param name
* @param appearTimes
* @param span
*/
public Person(String name,int appearTimes,int span){
this.name=name;
this.appearTimes=appearTimes;
this.span=span;
}
/**
* 构造函数
* @param name
* @param intimacy
*/
public Person(String name,int intimacy){
this.name=name;
this.intimacy=intimacy;
}
/**
* 下面是get和set的方法
*
*/
public int getIntimacy() {
return intimacy;
}
public void setIntimacy(int intimacy) {
this.intimacy = intimacy;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAppearTimes() {
return appearTimes;
}
public void setAppearTimes(int appearTimes) {
this.appearTimes = appearTimes;
}
public int getSpan() {
return span;
}
public void setSpan(int span) {
this.span = span;
}
按分别出现次数、篇幅跨度、亲密度排序:
public class SortComparator {
/**
* 内部类
* 按出现次数排序的比较器
*
*/
class SortByAppearTimes implements Comparator<Person>{
public int compare(Person one , Person another){
return another.getAppearTimes()-one.getAppearTimes();
}
}
/**
* 内部类
* 按首尾跨度排序的比较器
*
*/
class SortBySpan implements Comparator<Person>{
public int compare(Person one ,Person another) {
return another.getSpan()-one.getSpan();
}
}
/**
* 内部类
* 按亲密度排序的比较器
*
*
*/
class SortByIntimacy implements Comparator<Person>{
public int compare(Person one ,Person another) {
return another.getIntimacy()-one.getIntimacy();
}
}
调用排序的方法:
//按出现次数将ArrayList中的person将次数多到少排序排序
Collections.sort(person,(new SortComparator()).new SortByAppearTimes());
//按首尾跨度将ArrayList中的person按跨度大到小排序
Collections.sort(person,(new SortComparator()).new SortBySpan ());
//按亲密度将ArrayList中的per将亲密度多到少排序
Collections.sort(per,(new SortComparator()).new SortByIntimacy());
分块代码及显示结果:
按出现次数排序:
/**
* 按出现次数排序的面板
* @return 返回创建好的面板
*/
public JPanel panel_1(){
//按出现次数将ArrayList中的person将次数多到少排序排序
Collections.sort(person,(new SortComparator()).new SortByAppearTimes());
//设置列名,最好用final修饰为不可变的
final Object[] columnNames={"姓名 ","出现次数(次)","排名"};
//定义二维数组存储每行中的内容,初始值默认为null
Object[][] rowData=new Object[person.size()][3];
JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格
//给表格每行赋值(也可以说更新每行的值)
for(int i=0;i<person.size();i++){
Person p = person.get(i);
jte.setValueAt(p.getName(), i, 0);
jte.setValueAt(p.getAppearTimes(), i, 1);
jte.setValueAt(i+1, i, 2);
}
jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小
jte.setRowHeight(50);//设置每行高50
jte.setSelectionBackground(Color.PINK);//设置所选择行的背景色
jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色
jte.setGridColor (Color.BLACK);//设置网格线的颜色
jte.setFont(new java.awt.Font("Dialog", 2, 15));//设置字体大小和颜色
jte.setBackground(Color.orange);
//JTable最好加在JScrollPane上
JScrollPane pane3 = new JScrollPane (jte);
//创建一个面板对象
JPanel panel_1 = new JPanel( );
panel_1.add(pane3);//将JScrollPane加到面板上
//设置面板的背景颜色
panel_1.setBackground(Color.BLACK);
return panel_1;
}
按篇幅跨度排序:
/**
* 按首尾跨度排序的面板
* @return 返回创建好的面板
*/
public JPanel panel_2(){
//按首尾跨度将ArrayList中的person按跨度大到小排序
Collections.sort(person,(new SortComparator()).new SortBySpan ());
//设置列名,最好用final修饰为不可变的
final Object[] columnNames={"姓名 ","首尾跨度(字)","排名"};
//定义二维数组存储每行中的内容,初始值默认为null
Object[][] rowData=new Object[person.size()][3];
JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格
//给表格每行赋值(也可以说更新每行的值)
for(int i=0;i<person.size();i++){
Person p = person.get(i);
jte.setValueAt(p.getName(), i, 0);
jte.setValueAt(p.getSpan(), i, 1);
jte.setValueAt(i+1, i, 2);
}
jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小
jte.setRowHeight(50);//设置每行高50
jte.setSelectionBackground(Color.PINK);//设置所选择行的背景色
jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色
jte.setGridColor (Color.BLACK);//设置网格线的颜色
jte.setFont(new java.awt.Font("Dialog", 3, 15));//设置字体大小和颜色
jte.setBackground(Color.CYAN);
//JTable最好加在JScrollPane上
JScrollPane pane3 = new JScrollPane (jte);
//创建一个面板对象
JPanel panel_2 = new JPanel( );
panel_2.add(pane3);//将JScrollPane加到面板上
//设置面板的背景颜色
panel_2.setBackground(Color.BLACK);
return panel_2;
}
出现次数与篇幅跨度的直方图:
/**
* 显示直方图的方法
* @return 返回创建好的面板
*/
public JPanel panel_3(){
//创建一个面板对象
JPanel panel_3 = new JPanel(){
//调用重绘的方法,画直方图
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
//画标签说明
g.setColor(Color.RED);
g.fillRect(30, 40,70 , 20);
g.setColor(Color.GREEN);
g.fillRect(150, 40,70 , 20);
//实例化对象并调用方法
SeekName sn = new SeekName();
for(int i=0;i<nameArray.length;i++){
int height_1 = 0;//出现次数的高度
try {
height_1 = sn.appearTimes(nameArray[i])/20;
} catch (IOException e1) {
e1.printStackTrace();
}
int height_2 = 0;//首尾跨度的高度
try {
height_2 = sn.appearSpan(nameArray[i])/3000;
} catch (IOException e) {
e.printStackTrace();
}
//画直方图
g.setColor(Color.RED);
g.fillRect(i*70+50, 400-height_1, 30, height_1);
g.setColor(Color.GREEN);
g.fillRect(i*70+80, 400-height_2, 30, height_2);
}
}
};
//将面板设置为边框布局
panel_3.setLayout(new BorderLayout());
//设置面板的背景颜色
panel_3.setBackground(Color.BLACK);
//在面板北边加标签
JLabel jl_1= new JLabel();
jl_1.setForeground(Color.RED);//设置字体颜色
jl_1.setText(" 出现次数 首尾跨度");//标签中的内容
jl_1.setPreferredSize(new Dimension(100,30));//设置标签大小
panel_3.add(jl_1,BorderLayout.NORTH);//将标签加到面板的北边
//在面板南边加标签
JLabel jl_2= new JLabel();
jl_2.setForeground(Color.RED);//设置字体颜色
jl_2.setPreferredSize(new Dimension(700,200));//设置标签大小
//标签中的内容
jl_2.setText(" "+
nameArray[0]+" "+nameArray[1]+" "
+nameArray[2]+" "+nameArray[3]+" "
+nameArray[4]+" "+nameArray[5]+" "
+nameArray[6]+" "+nameArray[7]+" "
+nameArray[8]+" "+nameArray[9]);
panel_3.add(jl_2,BorderLayout.SOUTH);
return panel_3;
}
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
任意两人的亲密度二维表:
/**
* 亲密度显示的面板
* @return 返回创建好的面板
*/
public JPanel panel_4(){
//设置列名
Object[] columnNames=new Object[nameArray.length+1];
columnNames[0]="亲密度";
for(int i=1;i<=nameArray.length;i++){
columnNames[i]=nameArray[i-1];
}
//定义二维数组存储每行中的内容,初始值默认为null
Object[][] rowData=new Object[person.size()][nameArray.length+1];
JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格
//给表格每行赋值(也可以说更新每行的值)
for(int i=0;i<nameArray.length;i++){
jte.setValueAt(nameArray[i], i, 0);
jte.setValueAt(intimacy[i][0], i, 1);
jte.setValueAt(intimacy[i][1], i, 2);
jte.setValueAt(intimacy[i][2], i, 3);
jte.setValueAt(intimacy[i][3], i, 4);
jte.setValueAt(intimacy[i][4], i, 5);
jte.setValueAt(intimacy[i][5], i, 6);
jte.setValueAt(intimacy[i][6], i, 7);
jte.setValueAt(intimacy[i][7], i, 8);
jte.setValueAt(intimacy[i][8], i, 9);
jte.setValueAt(intimacy[i][9], i, 10);
}
jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小
jte.setRowHeight(50);//设置每行高50
jte.setSelectionBackground(Color.pink);//设置所选择行的背景色
jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色
jte.setGridColor (Color.BLACK);//设置网格线的颜色
jte.setFont(new java.awt.Font("Dialog", 4, 15));//设置字体大小和颜色
jte.setBackground(Color.ORANGE);//设置背景颜色
//JTable最好加在JScrollPane上
JScrollPane pane3 = new JScrollPane (jte);
//创建一个面板对象
JPanel panel_4 = new JPanel();
panel_4.add(pane3);//将JScrollPane加到面板上
//设置面板的背景颜色
panel_4.setBackground(Color.BLACK);
return panel_4;
}
亲密度排序:
/**
* 亲密度排序表的面板
* @return 返回创建好的面板
* @throws IOException
*/
public JPanel panel_5() throws IOException{
//实例化一个亲密度类的对象
IntimacySort is = new IntimacySort(nameArray,field.getText());
this.per=is.intimacy();//调用求任意两人亲密度的方法返回一个ArrayList<Person>对象
//按亲密度将ArrayList中的per将亲密度多到少排序
Collections.sort(per,(new SortComparator()).new SortByIntimacy());
//设置列名
final Object[] columnNames={"人物 ","亲密度","排名"};
//定义二维数组存储每行中的内容,初始值默认为null
Object[][] rowData=new Object[nameArray.length][3];
JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格
//给表格每行赋值(也可以说更新每行的值)
for(int i=0;i<per.size();i++){
Person p = per.get(i);
jte.setValueAt(p.getName(), i, 0);
jte.setValueAt(p.getIntimacy(), i, 1);
jte.setValueAt(i+1, i, 2);
}
jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小
jte.setRowHeight(50);//设置每行高50
jte.setSelectionBackground(Color.PINK);//设置所选择行的背景色
jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色
jte.setGridColor (Color.BLACK);//设置网格线的颜色
jte.setFont(new java.awt.Font("Dialog", 3, 15));//设置字体大小和颜色
jte.setBackground(Color.GREEN);
//JTable最好加在JScrollPane上
JScrollPane pane3 = new JScrollPane (jte);
//创建一个面板对象
JPanel panel_5 = new JPanel();
panel_5.add(pane3);//将JScrollPane加到面板上
//设置面板的背景颜色
panel_5.setBackground(Color.BLACK);
return panel_5;
}
<!--[if gte vml 1]><v:shape id="图片_x0020_6" o:spid="_x0000_i1026" type="#_x0000_t75" style='width:415.5pt;height:311.25pt;visibility:visible; mso-wrap-style:square'> <v:imagedata src="file:///C:\Users\李育洪\AppData\Local\Temp\msohtmlclip1\01\clip_image003.png" o:title="p5"/> </v:shape><![endif]--><!--[if !vml]-->
<!--[endif]-->
总结:
此次实验收获颇深,刚开始老师出题目的时候感觉挺难的,感觉自己做不出来这题目,特别是第三题求亲密度的问题,后来听老师讲了大概思路结合自己这一学期对java面向对象的学习,渐渐地找到了解题思路,后来还因为在Eclipse控制台上输出的结果不好看,还自己额外对结果做了可视化,自己编了界面将结果实现到界面上去,结果显示出来还蛮好看的。
此次实验解题过程中需要了解的java知识有:文件操作、输入输出流、String类、数据封装类、比较器排序、界面编写、重绘、面板布局、JTable、JScrollPane、JTexfiedl等swing中的组建类
等
参考文献:
jdk1.6.CHM
《Java编程基础》 石磊 清华大学出版社
完整代码:
package lyh.笑傲江湖1204; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import lyh.笑傲江湖1204.SortComparator.SortByAppearTimes; /** * 主函数类 * */ public class MainTest { private static ArrayList<Person> person; private String[] nameArray; private int[][] intimacy; private Person p; public static void main(String[] args) throws IOException { //实例化对象并调用方法 MainTest mt = new MainTest(); mt.init(); mt.output(); } /** * 初始化 * @throws IOException 抛出可能的异常 */ public void init() throws IOException{ //将10个人 物的名字存到数组中 nameArray=new String[]{ "令狐冲","盈盈","东方不败","岳不群","田伯光","岳灵珊","林平之","仪琳","风清扬","任我行" }; //创建一个ArrayList来存储数据 person = new ArrayList<Person>(); //实例化对象并调用方法 SeekName sn = new SeekName(); //得到出现的次数与跨度 for(int i=0;i<nameArray.length;i++){ int times=sn.appearTimes(nameArray[i]);//出现的次数 int span=sn.appearSpan(nameArray[i]);//跨度 person.add(new Person(nameArray[i],times,span));//加入到ArrayList中 } //得到亲密度 intimacy=new int[nameArray.length+1][nameArray.length+1]; for(int i=0;i<nameArray.length;i++){ for(int j=i+1;j<nameArray.length;j++){ //调用求亲密度的方法 intimacy[i][j]=sn.intimacy(nameArray[i], nameArray[j]); intimacy[j][i]=intimacy[i][j]; } } } /** * 输出 * @throws IOException 抛出可能的异常 */ public void output() throws IOException{ //可视化界面 ShowUI sui = new ShowUI(person,nameArray,intimacy); sui.mainUI(); } } /*************************************************** ****************************************************/ package lyh.笑傲江湖1204; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; /** * 查找小说中的人物的方法类 * */ public class SeekName { /** * 读取指定文件名的内容,作为字行串返回 * @return 读到的内容作为字符串返回 * @throws IOException * @throws java.io.IOException可能会抛出Io异常 */ public String readNovel() throws IOException{ //读取我们指定小说的源文件 String novel = "src\\输入文件\\笑傲江湖.txt"; //构造输入流对象,做为一个InputStream对象使用 //因为创建的对象是InputStream的子类的对象,我们使用父类变量引用,方便统一使用 InputStream ins = new FileInputStream(novel); //根据流中字节的长度,创建一个byte[]数组,保存读到的数据 byte[] contentByte = new byte[ins.available()]; //将流中的数据读到数组中 ins.read(contentByte); //将数组byte转换为字符串 String str = new String(contentByte); return str;//返回读取到的字符串 } /** * 查找人物出现的次数 * @param personName人物名字 * @return 返回人物出现的次数 * @throws IOException抛出可能存在的异常 */ public int appearTimes(String personName) throws IOException{ //得到输入的字符串 String result = readNovel(); int count=0,fromIndex=0;//计算器和索引 //将字符串便利一遍 while(fromIndex<result.length()){ //找到人物在小说中第一次出现的索引 int index= result.indexOf(personName, fromIndex); if(index==-1)break;//找不到就退出 else{ count++;//人物出现一次就加1 fromIndex= index+personName.length();//改变索引再继续遍历 ; } } return count;//返回人物出现的次数 } /** * 查找人物第一次和最后一次出现的跨度 * @param personName人物名字 * @return 返回人物出现的首尾跨度 * @throws IOException抛出可能存在的异常 */ public int appearSpan(String personName) throws IOException{ //得到字符串 String result = readNovel(); //第一次出现的索引 int firstIndex=result.indexOf(personName); //最后一次出现的索引 int lastIndex=result.lastIndexOf(personName); //得到人物第一次和最后一次出现的跨度 int span = lastIndex-firstIndex; //返回得到的跨度 return span; } /** * 求任意两个人物的亲密度 * @param personName_1 其中一个人物的名字 * @param personName_2 另一个人物的名字 * @return 返回亲密度的整数值(即当一个人出现时判断第二个人也在指定的区域内出现的次数) * @throws IOException 抛出可能存在的异常 */ public int intimacy(String personName_1,String personName_2) throws IOException{ //得到输入的字符串 String result = readNovel(); int count=0,fromIndex=100;//计算器和索引 while(fromIndex+100<result.length()){ //找到人物在小说中指定位置出现的索引 int index= result.indexOf(personName_1, fromIndex); if(index==-1)break;//找不到就退出 else{ String str = result.substring(index-100, index+100); if(str.contains(personName_2)){ count++;//人物出现一次就加1 } fromIndex= index+100;//改变索引再继续遍历 } } return count; } } /**************************************************** ****************************************************/ package lyh.笑傲江湖1204; /** * 人物类 * 定义此类来封装人物的各个属性 * */ public class Person<T> { //定义属性 private String name;//名字 private int appearTimes;//出现次数 private int span;//跨度 private int intimacy;//亲密度 /** * 构造函数 * @param name * @param appearTimes * @param span */ public Person(String name,int appearTimes,int span){ this.name=name; this.appearTimes=appearTimes; this.span=span; } /** * 构造函数 * @param name * @param intimacy */ public Person(String name,int intimacy){ this.name=name; this.intimacy=intimacy; } /** * 下面是get和set的方法 * */ public int getIntimacy() { return intimacy; } public void setIntimacy(int intimacy) { this.intimacy = intimacy; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAppearTimes() { return appearTimes; } public void setAppearTimes(int appearTimes) { this.appearTimes = appearTimes; } public int getSpan() { return span; } public void setSpan(int span) { this.span = span; } } /************************************************************************************************************/ package lyh.笑傲江湖1204; import java.util.Comparator; /** * 排序类 * 此类用来封装比较器 * */ public class SortComparator { /** * 内部类 * 按出现次数排序的比较器 * */ class SortByAppearTimes implements Comparator<Person>{ public int compare(Person one , Person another){ return another.getAppearTimes()-one.getAppearTimes(); } } /** * 内部类 * 按首尾跨度排序的比较器 * */ class SortBySpan implements Comparator<Person>{ public int compare(Person one ,Person another) { return another.getSpan()-one.getSpan(); } } /** * 内部类 * 按亲密度排序的比较器 * */ class SortByIntimacy implements Comparator<Person>{ public int compare(Person one ,Person another) { return another.getIntimacy()-one.getIntimacy(); } } } /********************************************************************************************************************/ package lyh.笑傲江湖1204; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import lyh.笑傲江湖1204.SortComparator.SortByAppearTimes; /** * 输出界面 * */ public class ShowUI extends JFrame { private CardLayout card; public JTextField field; private JPanel panel; private ArrayList<Person> person; private ArrayList<Person> per; private String[] nameArray; private int[][] intimacy; /** * 构造函数用来实例化对象和传参 * @param person ArrayList中的元素对象 * @param nameArray 用来存储人物名字的数组 * @param intimacy= 用来存储亲密度的数组 */ public ShowUI(ArrayList<Person> person,String[] nameArray,int[][] intimacy){ this.person=person; this.nameArray=nameArray; this.intimacy=intimacy; } /** * 主界面的方法 * @throws IOException */ public void mainUI() throws IOException{ //创建一个具有指定的水平和垂直间隙的新卡片布局,水平间距置于左右边缘。垂直间距置于上下边缘 card = new CardLayout(0,0); panel = new JPanel(card); // JPanel的布局管理将被设置成CardLayout JPanel buttonPanel = new JPanel(); // 构造放按钮的JPanel buttonPanel.setBackground(Color.BLACK); //创建按钮和文本框加到面板上 JButton button_1 = new JButton("出现次数排序"); JButton button_2 = new JButton("首尾跨度排序"); JButton button_3 = new JButton("直方图"); JButton button_4 = new JButton("亲密度"); field = new JTextField();//文本框 field.setPreferredSize(new Dimension(100,30));//设置大小 field.setText("令狐冲");//默认搜索为令狐冲 JButton button_5 = new JButton("搜索"); //在北边面板上添加按钮和标签 buttonPanel.add(button_1); buttonPanel.add(button_2); buttonPanel.add(button_3); buttonPanel.add(button_4); buttonPanel.add(field); buttonPanel.add(button_5); //创建好的面板加到卡布局的片面板上 panel.add(panel_1(),"出现次数排序"); panel.add(panel_2(),"首尾跨度排序"); panel.add(panel_3(),"直方图"); panel.add(panel_4(),"亲密度"); panel.add(panel_5(),"亲密度排序"); //下面是翻转到卡片布局的某个组件安装监听器 button_1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {// 直接翻转到panel_1 card.show(panel, "出现次数排序"); } }); button_2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {// 直接翻转到panel_2 card.show(panel, "首尾跨度排序"); } }); button_3.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {// 直接翻转到panel_3 card.show(panel, "直方图"); } }); button_4.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {// 直接翻转到panel_4 card.show(panel, "亲密度"); } }); button_5.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) {// 直接翻转到panel_5 try {//添加新的面板 panel.add(panel_5(),"亲密度排序"); } catch (IOException e1) { e1.printStackTrace(); } card.show(panel, "亲密度排序"); } }); //设置窗体属性 this.setTitle("笑傲江湖之人物分析");//标题 this.setSize(800,600); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗体时退出程序 this.setLocationRelativeTo(null); this.getContentPane().add(panel); this.getContentPane().add(buttonPanel,BorderLayout.NORTH);//将按钮面板加到窗体上北边去 this.setResizable(false); this.setVisible(true);//设置窗体可见 } /** * 按出现次数排序的面板 * @return 返回创建好的面板 */ public JPanel panel_1(){ //按出现次数将ArrayList中的person将次数多到少排序排序 Collections.sort(person,(new SortComparator()).new SortByAppearTimes()); //设置列名,最好用final修饰为不可变的 final Object[] columnNames={"姓名 ","出现次数(次)","排名"}; //定义二维数组存储每行中的内容,初始值默认为null Object[][] rowData=new Object[person.size()][3]; JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格 //给表格每行赋值(也可以说更新每行的值) for(int i=0;i<person.size();i++){ Person p = person.get(i); jte.setValueAt(p.getName(), i, 0); jte.setValueAt(p.getAppearTimes(), i, 1); jte.setValueAt(i+1, i, 2); } jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小 jte.setRowHeight(50);//设置每行高50 jte.setSelectionBackground(Color.PINK);//设置所选择行的背景色 jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色 jte.setGridColor (Color.BLACK);//设置网格线的颜色 jte.setFont(new java.awt.Font("Dialog", 2, 15));//设置字体大小和颜色 jte.setBackground(Color.orange); //JTable最好加在JScrollPane上 JScrollPane pane3 = new JScrollPane (jte); //创建一个面板对象 JPanel panel_1 = new JPanel( ); panel_1.add(pane3);//将JScrollPane加到面板上 //设置面板的背景颜色 panel_1.setBackground(Color.BLACK); return panel_1; } /** * 按首尾跨度排序的面板 * @return 返回创建好的面板 */ public JPanel panel_2(){ //按首尾跨度将ArrayList中的person按跨度大到小排序 Collections.sort(person,(new SortComparator()).new SortBySpan ()); //设置列名,最好用final修饰为不可变的 final Object[] columnNames={"姓名 ","首尾跨度(字)","排名"}; //定义二维数组存储每行中的内容,初始值默认为null Object[][] rowData=new Object[person.size()][3]; JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格 //给表格每行赋值(也可以说更新每行的值) for(int i=0;i<person.size();i++){ Person p = person.get(i); jte.setValueAt(p.getName(), i, 0); jte.setValueAt(p.getSpan(), i, 1); jte.setValueAt(i+1, i, 2); } jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小 jte.setRowHeight(50);//设置每行高50 jte.setSelectionBackground(Color.PINK);//设置所选择行的背景色 jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色 jte.setGridColor (Color.BLACK);//设置网格线的颜色 jte.setFont(new java.awt.Font("Dialog", 3, 15));//设置字体大小和颜色 jte.setBackground(Color.CYAN); //JTable最好加在JScrollPane上 JScrollPane pane3 = new JScrollPane (jte); //创建一个面板对象 JPanel panel_2 = new JPanel( ); panel_2.add(pane3);//将JScrollPane加到面板上 //设置面板的背景颜色 panel_2.setBackground(Color.BLACK); return panel_2; } /** * 显示直方图的方法 * @return 返回创建好的面板 */ public JPanel panel_3(){ //创建一个面板对象 JPanel panel_3 = new JPanel(){ //调用重绘的方法,画直方图 public void paint(Graphics g) { // TODO Auto-generated method stub super.paint(g); //画标签说明 g.setColor(Color.RED); g.fillRect(30, 40,70 , 20); g.setColor(Color.GREEN); g.fillRect(150, 40,70 , 20); //实例化对象并调用方法 SeekName sn = new SeekName(); for(int i=0;i<nameArray.length;i++){ int height_1 = 0;//出现次数的高度 try { height_1 = sn.appearTimes(nameArray[i])/20; } catch (IOException e1) { e1.printStackTrace(); } int height_2 = 0;//首尾跨度的高度 try { height_2 = sn.appearSpan(nameArray[i])/3000; } catch (IOException e) { e.printStackTrace(); } //画直方图 g.setColor(Color.RED); g.fillRect(i*70+50, 400-height_1, 30, height_1); g.setColor(Color.GREEN); g.fillRect(i*70+80, 400-height_2, 30, height_2); } } }; //将面板设置为边框布局 panel_3.setLayout(new BorderLayout()); //设置面板的背景颜色 panel_3.setBackground(Color.BLACK); //在面板北边加标签 JLabel jl_1= new JLabel(); jl_1.setForeground(Color.RED);//设置字体颜色 jl_1.setText(" 出现次数 首尾跨度");//标签中的内容 jl_1.setPreferredSize(new Dimension(100,30));//设置标签大小 panel_3.add(jl_1,BorderLayout.NORTH);//将标签加到面板的北边 //在面板南边加标签 JLabel jl_2= new JLabel(); jl_2.setForeground(Color.RED);//设置字体颜色 jl_2.setPreferredSize(new Dimension(700,200));//设置标签大小 //标签中的内容 jl_2.setText(" "+ nameArray[0]+" "+nameArray[1]+" " +nameArray[2]+" "+nameArray[3]+" " +nameArray[4]+" "+nameArray[5]+" " +nameArray[6]+" "+nameArray[7]+" " +nameArray[8]+" "+nameArray[9]); panel_3.add(jl_2,BorderLayout.SOUTH); return panel_3; } /** * 亲密度显示的面板 * @return 返回创建好的面板 */ public JPanel panel_4(){ //设置列名 Object[] columnNames=new Object[nameArray.length+1]; columnNames[0]="亲密度"; for(int i=1;i<=nameArray.length;i++){ columnNames[i]=nameArray[i-1]; } //定义二维数组存储每行中的内容,初始值默认为null Object[][] rowData=new Object[person.size()][nameArray.length+1]; JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格 //给表格每行赋值(也可以说更新每行的值) for(int i=0;i<nameArray.length;i++){ jte.setValueAt(nameArray[i], i, 0); jte.setValueAt(intimacy[i][0], i, 1); jte.setValueAt(intimacy[i][1], i, 2); jte.setValueAt(intimacy[i][2], i, 3); jte.setValueAt(intimacy[i][3], i, 4); jte.setValueAt(intimacy[i][4], i, 5); jte.setValueAt(intimacy[i][5], i, 6); jte.setValueAt(intimacy[i][6], i, 7); jte.setValueAt(intimacy[i][7], i, 8); jte.setValueAt(intimacy[i][8], i, 9); jte.setValueAt(intimacy[i][9], i, 10); } jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小 jte.setRowHeight(50);//设置每行高50 jte.setSelectionBackground(Color.pink);//设置所选择行的背景色 jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色 jte.setGridColor (Color.BLACK);//设置网格线的颜色 jte.setFont(new java.awt.Font("Dialog", 4, 15));//设置字体大小和颜色 jte.setBackground(Color.ORANGE);//设置背景颜色 //JTable最好加在JScrollPane上 JScrollPane pane3 = new JScrollPane (jte); //创建一个面板对象 JPanel panel_4 = new JPanel(); panel_4.add(pane3);//将JScrollPane加到面板上 //设置面板的背景颜色 panel_4.setBackground(Color.BLACK); return panel_4; } /** * 亲密度排序表的面板 * @return 返回创建好的面板 * @throws IOException */ public JPanel panel_5() throws IOException{ //实例化一个 亲密度类的对象 IntimacySort is = new IntimacySort(nameArray,field.getText()); this.per=is.intimacy();//调用求任意两人亲密度的方法返回一个ArrayList<Person>对象 //按亲密度将ArrayList中的per将亲密度多到少排序 Collections.sort(per,(new SortComparator()).new SortByIntimacy()); //设置列名 final Object[] columnNames={"人物 ","亲密度","排名"}; //定义二维数组存储每行中的内容,初始值默认为null Object[][] rowData=new Object[nameArray.length][3]; JTable jte = new JTable(rowData,columnNames);//把行列内容加到表格 //给表格每行赋值(也可以说更新每行的值) for(int i=0;i<per.size();i++){ Person p = per.get(i); jte.setValueAt(p.getName(), i, 0); jte.setValueAt(p.getIntimacy(), i, 1); jte.setValueAt(i+1, i, 2); } jte.setPreferredScrollableViewportSize(new Dimension(600,450));//设置表格大小 jte.setRowHeight(50);//设置每行高50 jte.setSelectionBackground(Color.PINK);//设置所选择行的背景色 jte.setSelectionForeground(Color.BLUE);//设置所选择行的前景色 jte.setGridColor (Color.BLACK);//设置网格线的颜色 jte.setFont(new java.awt.Font("Dialog", 3, 15));//设置字体大小和颜色 jte.setBackground(Color.GREEN); //JTable最好加在JScrollPane上 JScrollPane pane3 = new JScrollPane (jte); //创建一个面板对象 JPanel panel_5 = new JPanel(); panel_5.add(pane3);//将JScrollPane加到面板上 //设置面板的背景颜色 panel_5.setBackground(Color.BLACK); return panel_5; } } /********************************************************************************************************************/ package lyh.笑傲江湖1204; import java.io.IOException; import java.util.ArrayList; /** * 查找亲密度类 * */ public class IntimacySort { private String[] nameArray; private String personName_1; private ArrayList<Person> per; public IntimacySort(){//用来实例化对象 } /** * 构造函数传参 * @param personName_1 文本框中输入的名字 * @param nameArray 存储人物名字的 数组 */ public IntimacySort(String[] nameArray,String personName_1){ this.personName_1=personName_1; this.nameArray=nameArray; } /** * 求任意两个人物的亲密度(即当一个人出现时判断其他人也在指定的区域内出现的次数) * @param personName_1 其中一个人物的名字 * @throws IOException 抛出可能存在的异常 */ public ArrayList<Person> intimacy() throws IOException{ //创建一个ArrayList来存储数据 per = new ArrayList<Person>(); //得到输入的字符串 SeekName sn=new SeekName(); String result =sn.readNovel(); //定义数组来存储本人物与其他人物的亲密度 int[]count=new int[nameArray.length]; for(int i=0;i<nameArray.length;i++){ int fromIndex=100;//开始索引 if(personName_1.equals(nameArray[i])){ count[i]=0; }else{ while(fromIndex+100<result.length()){ //找到人物在小说中指定位置出现的索引 int index= result.indexOf(personName_1, fromIndex); if(index==-1)break;//找不到就退出 else{ String str = result.substring(index-100, index+100); if(str.contains(nameArray[i])){ count[i]++;//人物出现一次就加1 } fromIndex= index+100;//改变索引再继续遍历 } } } per.add(new Person(nameArray[i],count[i]));//加入到ArrayList中 } return per; } }
下一篇: C语言的文件操作