JAVA怎么做一个排序的动画演示

2025-10-28 14:54:25

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();

      }

    }

  }

}

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢