这是一个Java老师布置的作业,一开始做这个的时候要求不断改变,以至于最后整个框架没有任何设计模式可言,基本上需要什么就添加什么,最后还有一些调制需要的参数都没有消除。
操作界面如下:
分离了EDT线程和工作线程,不过数据量多起来后最后在JTextArea中输出数据的时候还是会出现卡屏,停顿。因为IO太多。原本打算在工作线程中动态生成一个新的JTextArea组件来替换旧的组件,但是不行,因为在其他线程更新或者创建组件都不会给EDT线程响应,估计是EDT线程已经绑定了对象。
整个程序分为3个主要类,第一个类为EDT线程类,就是主管界面。在EDT线程类上点击排序开启SwingWorker类CreateArr类,代码如下:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package homework;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
/**
*
* @author YongJW
*/
public class CreateArr extends SwingWorker<Number[],Void>{
/**
* done用来获得数据并设置排序时间并且开启数据排序线程
*/
@Override
protected void done() {
Number arr[] = null;
try {
arr = get();
} catch (Exception ignore){
ignore.printStackTrace();
}
// for(int i = 0;i < arr.length;++ i){
// JTA.append(arr[i] + " ");
// }
creaTime.setText(time / 1000 + "微秒");
if(sortArr != null && !sortArr.isDone()){
sortArr.cancel(true);
sortArr = null;
}
sortArr = new SortArr(this,sortTime,suanfa);
sortArr.addPropertyChangeListener(SFS.sortPro);
SFS.getSortPro().setIndeterminate(true);
//SFS.getSortPro().setValue(10);
sortArr.execute();//启动
}
/**
* 根据构造函数传递的参数生成相应类型的数据存于Number变量中
* @return
* @throws Exception
*/
@Override
protected Number[] doInBackground() throws Exception {
long str = System.nanoTime();
if(leixin == 0){
arr = new Integer[num];
for(int i = 0;i < arr.length;++ i){
arr[i] = (int)(Math.random() * Integer.MAX_VALUE);
}
}else if(leixin == 1){
arr = new Double[num];
for(int i = 0;i < arr.length;++ i){
arr[i] = (double)(Math.random() * Integer.MAX_VALUE);
}
}else if(leixin == 2){
arr = new Float[num];
for(int i = 0;i < arr.length;++ i){
arr[i] = (float)(Math.random() * Integer.MAX_VALUE);
}
}
long end = System.nanoTime();
time = end - str;
return arr;
}
/**
* 构造函数
* @param leixin
* @param num
* @param JTA
* @param arr
* @param creatime
* @param suanfa
* @param sortTime
* @param SFS
*/
public CreateArr(int leixin,int num,JTextArea JTA,Number arr[],JLabel creatime,int suanfa,JLabel sortTime,SwingForSort SFS){
this.num = num;
this.JTA = JTA;
JTA.setText("");
this.leixin = leixin;
this.arr = arr;
this.creaTime = creatime;
this.sortTime = sortTime;
this.suanfa = suanfa;
this.SFS = SFS;
}
public int getNum() {
return num;
}
public int getLeixin() {
return leixin;
}
public JTextArea getJTA() {
return JTA;
}
public Number[] getArr() {
return arr;
}
private int num = 0;
private int leixin = 0;
private JTextArea JTA;
private Number[] arr = null;
private JLabel creaTime = null;
private JLabel sortTime = null;
private long time = 0;
private SwingWorker sortArr = null;
private int suanfa = 0;
private SwingForSort SFS = null;
}
在生成数据线程完成后开启排序线程,根据算法和类型排序,代码如下:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package homework;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
/**
*
* @author YongJW
*/
public class SortArr extends SwingWorker<String,StringBuffer>{
/**
* 返回的STring用来更新JTextArea同时完成后设置完成时间
* @return
* @throws Exception
*/
@Override
protected String doInBackground() throws Exception {
long str = System.nanoTime();
if(createArr.isDone()){
choiceAlo();
}
long end = System.nanoTime();
time = end - str;
sortTime.setText(time / 1000 + "微秒");
createArr.getJTA().setText(" ");
StringBuffer strTem = new StringBuffer();
for(int i = 0;i < (createArr.getArr()).length;++ i){
strTem.append(createArr.getArr()[i] + " ");
//publish(createArr.getArr()[i] + " ");
//createArr.getJTA().append(createArr.getArr()[i] + " ");
// if((i % 200) == 0 && createArr.getArr().length > 200){
// //setProgress(i / (createArr.getArr().length /100));//设置进度
// publish(strTem);
// }else{
// if(i == createArr.getArr().length - 1){
// publish(strTem);
// }
// }
}
return strTem.toString();
}
/**
* 设置中途处理的数据,但是由于数据生成连续,因此没有用处
* @param chunks
*/
@Override
protected void process(List<StringBuffer> chunks) {
for(StringBuffer str:chunks){
if(isCancelled()){
break;
}
createArr.getJTA().append(str.toString());
}
}
/**
* 更新JTextArea
*/
@Override
protected void done() {
//Number arr[] = null;
if(isCancelled()){
return;
}
String str = null;
try {
str = get();
} catch (Exception ignore){
ignore.printStackTrace();
}
createArr.getJTA().setText(str);
try {
writeFile(str);
} catch (IOException ex) {
Logger.getLogger(SortArr.class.getName()).log(Level.SEVERE, null, ex);
}
setProgress(100);
}
/**
* 根据构造函数的参数来对用相应的算法来排序数据
*
* @param <T>
*/
private <T extends Comparable> void choiceAlo(){//泛型无法向上转型
if(suanfa == 0){
selectSort((T[])createArr.getArr());
}else if(suanfa == 1){
quickSort((T[])createArr.getArr());
}else if(suanfa == 2){
mergeSort((T[])createArr.getArr());
}
}
/**
* 每次生成的数据都写入文件
* @param str
* @throws IOException
*/
private void writeFile(String str) throws IOException{
FileWriter f_out = null;
f_out = new FileWriter("sortNum.txt",true);
f_out.write(str);
f_out.write("\r\n");
f_out.close();
}
/**
* 构造函数
* @param createArr
* @param sortTime
* @param suanfa
*/
public SortArr(CreateArr createArr,JLabel sortTime,int suanfa){
this.createArr = createArr;
this.sortTime = sortTime;
this.suanfa = suanfa;
}
private CreateArr createArr = null;
private JLabel sortTime = null;
private int suanfa = 0;
private long time;
private JTextArea sortArea = null;
/**
* MergeSort
* @param t
*/
public <T extends Comparable> void mergeSort(T[] t){
if(t == null || t.length <= 1)
return;
MergeSort(t, 0,t.length - 1);
}
public <T extends Comparable> void MergeSort(T[] t,int low,int high){
if(t == null || t.length <= 1||low ==high)
return;
int mid = (low + high ) / 2;
MergeSort(t,low,mid);
MergeSort(t,mid + 1,high);
MERGE(t,low,mid,high);
setProgress(100 * (high + 1) / t.length);//简化。
}
public <T extends Comparable> void MERGE(T a[],int low,int mid ,int high){
T b[] = a.clone() ;
int tem = ++mid;
int low1 = low;
int i = 0;
while(low < mid&&tem <= high){
if(a[low].compareTo(a[tem]) <= 0){
b[i ++] = a[low ++];
}else{
b[i ++] = a[tem ++];
}
}
while(low < mid ){
b[i ++] = a[low ++];
}
while(tem <= high){
b[i ++] = a[tem ++];
}
for(int j = 0;j < high - low1 + 1;++ j){
a[low1 + j] = b[j];
}
}
/**
* select
*/
public <T extends Comparable> void selectSort(T t[]){
for(int i = 0;i < t.length;++ i){
T low = t[i];
int key = i;
for(int j = i + 1;j < t.length;++ j){
if(low.compareTo(t[j]) > 0){
key = j;
low = t[j];
}
}
if(key != i){
T tem = t[key];
t[key] = t[i];
t[i] = tem;
}
setProgress(100 * (i + 1) / t.length);
}
}
/**
* Bubble
*/
public <T extends Comparable> void bubbleSort(T t[]){
if(t == null || t.length <= 1)
return;
int i = t.length;
while(i > 0){
for(int j = 0;j < i - 1;++ j){
if(t[j].compareTo(t[j + 1]) > 0){
T tem = t[j];
t[j] = t[j + 1];
t[j + 1] = tem;
}
}
-- i;
}
}
/**
* Quick
*/
public <T extends Comparable> void quickSort(T a[]){
QuickSort(a,0,a.length - 1);
}
public <T extends Comparable> void QuickSort(T a[],int low,int high){
if(low < high){
int k = SPLIT(a,low,high);
QuickSort(a,low,k - 1);
QuickSort(a,k + 1,high);
setProgress(100 * (high + 1) / a.length);
}
}
public <T extends Comparable> int SPLIT(T a[],int low ,int high){
int i = low ;
T x = a[low];
for(int j = low + 1;j <= high;++ j){
if(x.compareTo(a[j]) >= 0){
i++;
if(i != j){//通过这里不断吧大的向后推一样达到分类效果
T tem = a[i];
a[i] = a[j];
a[j] = tem;
}
}
}
T tem1 = a[low];
a[low] = a[i];
a[i] = tem1;
return i ;
}
}
代码都很乱,还没有测出测试段和引用。原本打算封装性好一点的,但是为了测试就不得不把EDT线程类引用进来