JAVA怎么做一个排序的动画演示
1、Demo.java
2、import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
public class Demo extends Canvas
{
private final int NO_START = -1;
private final int HAS_START = 0;
private final int HAS_OVER = 1;
private final int BX = 20;
private final int BY = 20;
private int DX = 30;
private final int DY = 15;
private final int WIDTH = 20;
private final int HEIGHT = 30;
private int m_nNum;
private int m_nIIndex;
private int m_nJIndex;
private int m_nTemp;
//private int m_nLast;
private int m_nCur;
private String m_sOldData;
private char[] m_sData = new char[12];
private int m_nStatus = -1;
private boolean m_bSortType = true;
private Graphics m_Graph;
private Graphics m_offG;
private Image m_offImg;
public void paint(Graphics g)//根据状态值m_nStatus来绘图,并且通过m_nIIndex,m_nJIndex和m_nTemp来控制箭头
{
this.m_offG.clearRect(0, 0, getSize().width, getSize().height);
switch (this.m_nStatus)
{
case -1:
break;
case 0:
drawData(false, this.m_offG);
for (int i = 1; i < this.m_nNum + 1; i++)
{
if (this.m_nCur == i)
continue;
Color color;
if ((i != this.m_nIIndex) && (i != this.m_nJIndex))
color = Color.black;
else
color = Color.yellow;
drawNode(this.m_sData[i], i, 10, getBackground(), color, this.m_offG);
}
if (this.m_nIIndex <= this.m_nNum){
drawArrow('i', this.m_nIIndex, 10, Color.red, this.m_offG);
}
if ((this.m_nJIndex > this.m_nIIndex) && (this.m_nJIndex <= this.m_nNum)) {
drawArrow('j', this.m_nJIndex, 10, Color.red, this.m_offG);
}
if ((this.m_nTemp >= 1) && (this.m_nTemp <= this.m_nNum)){
drawArrow1('t', this.m_nTemp, 10, Color.green, this.m_offG);
}
g.drawImage(this.m_offImg, 0, 0, this);
break;
case 1:
drawData(true, this.m_offG);
g.drawImage(this.m_offImg, 0, 0, this);
break;
}
}
public int proceed(int nStep)//这是算法执行的主要逻辑,其中case中的值要与Applet1.java中的showSource的nStep相对应起来
{ //这里的逻辑主要是简单的选择排序
int nextStep = -1;
//int j = 0;
switch (nStep)
{
case -1:
this.m_nStatus = 0;
nextStep = 0;
break;
case 0:
nextStep = 2;
this.m_nIIndex = 0;
break;
case 2:
this.m_nIIndex += 1;
if (this.m_nIIndex > this.m_nNum)
nextStep = 10;
else
nextStep = 3;
break;
case 3:
this.m_nTemp = this.m_nIIndex;
this.m_nJIndex = this.m_nIIndex;
nextStep = 4;
break;
case 4:
this.m_nJIndex += 1;
if (this.m_nJIndex <= this.m_nNum)
nextStep = 5;
else
nextStep = 7;
break;
case 5:
//j = this.m_nJIndex;
for (int i = 0; i < 3; i++)
{ //显示一下动态效果
drawNode(this.m_sData[this.m_nTemp], this.m_nTemp, 10, Color.red, Color.yellow, getGraphics());
drawNode(this.m_sData[this.m_nJIndex], this.m_nJIndex, 10, Color.red, Color.yellow, getGraphics());
delay(120);
drawNode(this.m_sData[this.m_nTemp], this.m_nTemp, 10, Color.cyan, Color.yellow, getGraphics());
drawNode(this.m_sData[this.m_nJIndex], this.m_nJIndex, 10, getBackground(), Color.yellow, getGraphics());
delay(120);
}
if (compare(this.m_sData[this.m_nJIndex],this.m_sData[this.m_nTemp]))
nextStep = 6;
else
nextStep = 4;
break;
case 6:
this.m_nTemp = this.m_nJIndex;
nextStep = 4;
break;
case 7:
if (this.m_nIIndex != this.m_nTemp)
nextStep = 8;
else
nextStep = 2;
break;
case 8:
//交换节点
swapNode(this.m_nIIndex,this.m_nTemp,Color.lightGray,Color.yellow);
//j = this.m_nJIndex;
char ch = this.m_sData[this.m_nTemp];
this.m_sData[this.m_nTemp] = this.m_sData[this.m_nIIndex];
this.m_sData[this.m_nIIndex] = ch;
nextStep = 2;
break;
case 10:
this.m_nStatus = 1;
nextStep = -1;
break;
case 1:
case 9:
break;
} repaint();
return nextStep;
}
public void addNotify()
{
super.addNotify();
this.m_offImg = createImage(getSize().width, getSize().height);
this.m_offG = this.m_offImg.getGraphics();
}
private void drawNode(char ch, int i, int j, Color bkColor, Color fgColor, Graphics g)
{ //绘制节点
Color old = g.getColor();
g.drawRect(20 + i * this.DX, 20 + j * 15, 20, 30);
g.setColor(bkColor);
g.fillRect(20 + i * this.DX + 1, 20 + j * 15 + 1, 19, 29);
char[] c = { ' ', ' ' }; c[0] = ch;
g.setColor(fgColor);
g.drawChars(c, 0, 1, 20 + i * this.DX + 6 + 1, 20 + j * 15 + 20);
g.setColor(old);
}
private void drawNode(char ch, float i, float j, Color bkColor, Color fgColor, Graphics g) {//绘制节点
Color old = g.getColor();
g.drawRect((int)(20.0F + i * this.DX), (int)(20.0F + j * 15.0F), 20, 30);
g.setColor(bkColor);
g.fillRect((int)(20.0F + i * this.DX + 1.0F), (int)(20.0F + j * 15.0F + 1.0F), 19, 29);
char[] c = { ' ', ' ' }; c[0] = ch;
g.setColor(fgColor);
g.drawChars(c, 0, 1, (int)(20.0F + i * this.DX + 6.0F + 1.0F), (int)(20.0F + j * 15.0F + 20.0F));
g.setColor(old);
}
public void swapNode(int I,int Temp, Color bkColor, Color fgColor)
{ //交换节点,I和Temp分别为两个互相交换节点的索引
Graphics g = getGraphics();
Color bk = getBackground();
Color old = g.getColor();
char ch1 = this.m_sData[I];
char ch2 = this.m_sData[Temp];
int y = 10;
g.setColor(bk);
g.fillRect(20 + I * this.DX - 1, 20 + y * 15 - 1, 22, 32);
g.setColor(old);
drawNode(ch1, (float)(I + 0.5D), y - 3, bk, fgColor, g);
delay(150);
g.setColor(bk);
g.fillRect(20 + Temp * this.DX - 1, 20 + y * 15 - 1, 22, 32);
g.setColor(old);
drawNode(ch2, I, y, bk, fgColor, g);
delay(150);
g.setColor(bk);
g.fillRect((int)(20.0D + (I + 0.5D) * this.DX - 1.0D), 20 + (y - 3) * 15 - 1, 22, 32);
g.setColor(old);
drawNode(ch1, Temp, y, bk, fgColor, g);
delay(150);
}
public void drawArrow(char ch, int i, int j, Color color, Graphics g)
{ //画箭头
Color old = g.getColor();
g.setColor(color);
char[] c = { ' ', ' ' };
c[0] = ch;
int x = 15 + i * this.DX + 6 + 4;
int y = 20 + j * 15 + 30 + 5;
g.drawChars(c, 0, 1, x - 8, y + 15);
g.drawLine(x, y, x, y + 25);
g.drawLine(x, y, x + 2, y + 5);
g.drawLine(x, y, x - 3, y + 5);
g.setColor(old);
}
public void drawArrow1(char ch, int i, int j, Color color, Graphics g)
{ //和上面的一样。就是x的坐标值不一样
Color old = g.getColor();
g.setColor(color);
char[] c = { ' ', ' ' };
c[0] = ch;
int x = 25 + i * this.DX + 6 + 4;
int y = 20 + j * 15 + 30 + 5;
g.drawChars(c, 0, 1, x - 8, y + 15);
g.drawLine(x, y, x, y + 25);
g.drawLine(x, y, x + 2, y + 5);
g.drawLine(x, y, x - 3, y + 5);
g.setColor(old);
}
public void setData(String sData, boolean bool)
{ //设置数据
this.m_sOldData = sData;
this.m_bSortType = bool;
this.m_nStatus = -1;
this.m_nNum = this.m_sOldData.length();
this.m_sData[0] = ' ';
if (this.m_nNum != 0)
this.DX = (300 / this.m_nNum);
else {
this.DX = 300;
}
for (int i = 1; i <= this.m_nNum; i++) {
this.m_sData[i] = sData.charAt(i - 1);
}
//this.m_nLast = 0;
this.m_nTemp = 0;
this.m_nJIndex = 0;
this.m_nIIndex = 0;
this.m_nCur = 0;
if (this.m_Graph == null) this.m_Graph = getGraphics();
}
public void update(Graphics g)
{ //更新视图
paint(g);
}
private void drawData(boolean bool, Graphics g)
{ //绘制数据
g.drawString("初始数据:", 20, 20);
Color bk = getBackground();
for (int i = 0; i < this.m_sOldData.length(); i++)
{
drawNode(this.m_sOldData.charAt(i), i + 1, 1, bk, Color.black, g);
}
if (bool)
{
g.drawString("排序结果:", 20, 150);
for (int i = 1; i < this.m_nNum + 1; i++)
drawNode(this.m_sData[i], i, 10, getBackground(), Color.black, g);
}
}
private boolean compare(char ch1, char ch2)
{ //比较,两种顺序
if (this.m_bSortType)
return ch1 < ch2;
return ch1 > ch2;
}
private void delay()
{
try
{
Thread.sleep(80L); } catch (InterruptedException e) {
}
}
private void delay(int time) {
try {
Thread.sleep(time);
}
catch (InterruptedException e)
{
}
}
public void init()
{ //初始化
setData("", true);
this.m_Graph.clearRect(0, 0, getSize().width, getSize().height);
}
}
3、Applet1.java
4、import java.applet.Applet;
import java.awt.Button;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.TextComponent;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.EventObject;
public class Applet1 extends Applet
implements ActionListener, ItemListener
{
public Button m_btnNext; //定义界面控件
public Button m_btnReset;
public Button m_btnGo;
public TextField m_tfData;
public Checkbox m_Radio1;
public Checkbox m_Radio2;
public CheckboxGroup m_Group = new CheckboxGroup();
public int m_nStep;
private TextArea m_taSource;
public Demo m_Demo;
public GoThread m_Go;
private Label m_lblData;
private Label m_lblSortType;
private String m_sDefault = "SDLJ923SD9";
private boolean m_bSortType = true;
public boolean m_bPaused = true;
private String[] m_sCode = { //创建一个数组,并把算法代码加进去
"void BubbleSort(Elem R[], int n){ ",
" int i,j,temp; ",
" for(i=0;i<n;i++){ ",
" temp = i; ",
" for (j = i+1; j < n; j++){ ",
" if (compare(A[temp],A[j])) ",
" temp = j; } ",
" if (i!=temp)",
" Swap(A[i],A[temp]); } ",
"} " };
public void showSource() //这个主要是在程序运行中演示运行到哪一行代码,和上面的数组对应
{
if (this.m_nStep == -1)
{
this.m_taSource.select(0, 0);
return;
}
int nStart = 0;
int nEnd = 0;
if(this.m_nStep < 9)
{
for (int i = 0; i < this.m_nStep; i++)
nStart += this.m_sCode[i].length() + 1; //选择高亮部分的首地址
nEnd = nStart + this.m_sCode[this.m_nStep].length() + 1;//选择高亮部分的尾地址
this.m_taSource.select(nStart, nEnd);
this.m_taSource.requestFocus(); //聚焦
}
}
private void addComponent(Component c, int x, int y, int width, int height)
{ //按照一定的坐标位置添加控件
c.setLocation(x, y);
c.setSize(width, height);
add(c);
}
public void reset()
{ //重置,主要让数据恢复到初始阶段
this.m_nStep = -1;
this.m_bPaused = true;
this.m_bSortType = true;
setInputStatus(true);
this.m_Radio1.setState(this.m_bSortType);
this.m_Radio2.setState(!this.m_bSortType);
showSource();
this.m_Demo.init();
this.m_Go = new GoThread(this);
this.m_Go.start();
}
public void itemStateChanged(ItemEvent e)//控制状态
{
if ((e.getSource() == this.m_Radio1) && (e.getStateChange() == 1))
this.m_bSortType = true;
else if ((e.getSource() == this.m_Radio2) && (e.getStateChange() == 1))
this.m_bSortType = false;
}
private void setInputStatus(boolean bool)//设置状态
{
this.m_Radio1.setEnabled(bool);
this.m_Radio2.setEnabled(bool);
this.m_tfData.setEnabled(bool);
}
public void actionPerformed(ActionEvent e) {//事件执行
if (e.getSource() == this.m_btnReset)
{
reset();
this.m_tfData.setText(this.m_sDefault);
}
else if (e.getSource() == this.m_btnNext)
{
if (this.m_nStep == -1)
{
String str = this.m_tfData.getText();
if (str.length() > 10)
str = str.substring(0, 10);
else if (str.length() <= 1)
str = this.m_sDefault;
this.m_tfData.setText(str);
this.m_Demo.setData(str, this.m_bSortType);
setInputStatus(false);
}
this.m_nStep = this.m_Demo.proceed(this.m_nStep);//why here invoke the proceed();
if (this.m_nStep == -1)
setInputStatus(true);
showSource();
}
else if (e.getSource() == this.m_btnGo)
{
if (this.m_nStep == -1)
{
String str = this.m_tfData.getText();
if (str.length() > 10)
str = str.substring(0, 10);
else if (str.length() <= 1)
str = this.m_sDefault;
this.m_tfData.setText(str);
this.m_Demo.setData(str, this.m_bSortType);
setInputStatus(false);
}
if (this.m_bPaused)
{
this.m_Go.resume();
this.m_bPaused = false;
this.m_btnGo.setLabel("暂停执行");
this.m_btnReset.setEnabled(false);
this.m_btnNext.setEnabled(false);
setInputStatus(false);
}
else
{
this.m_Go.suspend();
this.m_bPaused = true;
this.m_btnGo.setLabel("连续执行");
this.m_btnReset.setEnabled(true);
this.m_btnNext.setEnabled(true);
}
}
}
public void init()//界面初始化
{
setLayout(null);
this.m_taSource = new TextArea(18, 50);
this.m_taSource.setEditable(false);
this.m_taSource.setBackground(Color.white);
setSource();
this.m_Demo = new Demo();
this.m_btnNext = new Button("单步执行");
this.m_btnReset = new Button("重置环境");
this.m_btnGo = new Button("连续执行");
this.m_tfData = new TextField(this.m_sDefault);
this.m_lblData = new Label("输入数据:");
this.m_lblSortType = new Label("排序类型:");
this.m_Radio1 = new Checkbox("正序", this.m_Group, true);
this.m_Radio2 = new Checkbox("逆序", this.m_Group, false);
this.m_btnNext.addActionListener(this);
this.m_btnReset.addActionListener(this);
this.m_btnGo.addActionListener(this);
this.m_Radio1.addItemListener(this);
this.m_Radio2.addItemListener(this);
int nHeight = 20;
int nWidth = 15;
addComponent(this.m_taSource, 20, 20, 300, 280);
addComponent(this.m_Demo, 320, 20, 380, 280);
addComponent(this.m_btnReset, 20, 320, nWidth * 5, nHeight);
addComponent(this.m_btnNext, 120, 320, nWidth * 5, nHeight);
addComponent(this.m_btnGo, 240, 320, nWidth * 5, nHeight);
addComponent(this.m_lblData, 350, 320, nWidth * 5, nHeight);
addComponent(this.m_tfData, 450, 320, nWidth * 8, nHeight);
addComponent(this.m_lblSortType,
350, 350, nWidth * 5, nHeight);
addComponent(this.m_Radio1, 450, 350, nWidth * 3, nHeight);
addComponent(this.m_Radio2, 450 + nWidth * 5, 350, nWidth * 3, nHeight);
this.m_Go = new GoThread(this);
this.m_Go.start();
reset();
}
public void setSource()
{
this.m_taSource.setText("");
for (int i = 0; i < this.m_sCode.length; i++)
this.m_taSource.append(this.m_sCode[i] + "\r\n");
}
}
5、import java.awt.Button;
import java.awt.Component;
import java.io.PrintStream;
public class GoThread extends Thread
{
private int m_nSleepTime = 800;
private Applet1 parent;
GoThread(Applet1 p)
{
this.parent = p;
}
public void run() {//创建一个线程并运行
suspend();
while (true)
{
this.parent.m_nStep = this.parent.m_Demo.proceed(this.parent.m_nStep);//连续执行
this.parent.showSource();
try
{
Thread.sleep(this.m_nSleepTime);
}
catch (InterruptedException exception)
{
System.err.println("Exception:" + exception.toString());
}
if (this.parent.m_nStep == -1)
{
this.parent.m_btnGo.setLabel("连续执行");
this.parent.m_bPaused = true;
this.parent.m_btnNext.setEnabled(true);
this.parent.m_btnReset.setEnabled(true);
this.parent.m_tfData.setEnabled(true);
this.parent.m_Radio1.setEnabled(true);
this.parent.m_Radio2.setEnabled(true);
suspend();
}
}
}
}