java的多个图形 [英] java multiple graphics

查看:180
本文介绍了java的多个图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好了,所以我一直对这个code一段时间,显示如何排序算法的工作。现在我有工作在那里排序具有相同排序多个图形,但我需要每个图在同一时间做不同的排序。我一直在研究并试图解决这个好几天,现在我只是有隧道视野。我会后我的code的情况下,我的解释是混乱。我觉得这可能有利于很多人用java图形工作,任何帮助,将AP preciated。

 进口java.applet.Applet中;
进口java.awt中的*。
java.awt.event中导入*。
进口了java.util.Random;
进口java.util.StringTokenizer的;
进口java.util.Scanner中;
公共类排序扩​​展的Applet {/ **构造函数。仅用于启动排序的动画小程序。 * /
公众排序(){}
/ **为了启动排序动画作为应用程序。 * /
公共静态无效的主要(字符串[] argv的){
    帧_aFrame =新帧(排序动画);
    _aFrame.setBackground(Color.white);
    _aFrame.set preferredSize(新尺寸(2700,1000));    扫描仪在=新的扫描仪(System.in);
    INT sizeOfArray;
    的System.out.println(你要排序多少数量呢?);
    sizeOfArray = in.nextInt();
    _aFrame.addWindowListener(
                              新WindowAdapter的(){
        公共无效的windowClosing(WindowEvent五){System.exit(0); }
    }
                              );    _aFrame.setLayout(新的BorderLayout());
    _aFrame.add(新SortPanel(sizeOfArray));
    _aFrame.pack();
    _aFrame.setVisible(真);
}}类SortPanel扩展面板实现Runnable {/ **按钮触发排序动画* /
私人按钮aSortButton_ =新按钮(排序);
/ **选择排序算法的选择项* /
私人选择aChoice_ =新选择();
/ **用于处理动画组件* /
私人ArrayCanvas anArrayCanvas_;
////////////////////////////////////////////////// //////////////////////////// **
 *构造函数。
 *
 的数组的元素的* @参数长度没有
 * @参数aBarColor色彩元素重新presenting条将被绘制
 *
 抛出IllegalArgumentException如果阵列< code>长度LT; / code>是
 *要大,以显示(即< code>长度LT; / code基比大
 *< code基BAR_WIDTH< / code>或LT; code基BAR_HEIGHT< / code取代)。
 * /
公共SortPanel(INT ARRAYSIZE){
    的setLayout(新的BorderLayout());
    aSortButton_.addActionListener(
                新的ActionListener(){
        公共无效的actionPerformed(ActionEvent的五){
            新的Thread(SortPanel.this)。开始();
        }
    }
                );
    anArrayCanvas_ =新ArrayCanvas(ARRAYSIZE);
    的for(int i = 0; I< ArrayCanvas.SORT_NAMES.length ++ I)
        aChoice_.add(ArrayCanvas.SORT_NAMES [I]);    //在顶部添加按钮:
    面板_aTopPanel =新面板();
    _aTopPanel.add(aSortButton_);
    加(_aTopPanel,BorderLayout.NORTH);    //下面添加选择ArrayCanvas:
    面板_aPanel =新面板();
    _aPanel.setLayout(新的BorderLayout());
    面板_aChoicePanel =新面板();
    _aChoicePanel.add(aChoice_);
    _aPanel.add(_aChoicePanel,BorderLayout.NORTH);
    _aPanel.add(anArrayCanvas_,BorderLayout.CENTER);    加(_aPanel,BorderLayout.CENTER);    面板_aBottomPanel =新面板();
    加(_aBottomPanel,BorderLayout.SOUTH);
}////////////////////////////////////////////////// //////////////////////////// **运行排序动画。 * /
公共无效的run(){
    aSortButton_.setEnabled(假);
    双倍时间= System.currentTimeMillis的();
    anArrayCanvas_.sort(aChoice_.getSelectedItem());
    aSortButton_.setEnabled(真);
}
}类ArrayCanvas扩展画布{/ **可用排序算法的标签。 * /
公众最终静态的String [] = SORT_NAMES {冒泡排序,插入排序,壳类,堆排序,分类合并,快速排序,};/ **中的X方向的酒吧和边界之间的偏移(左和右)* /
公众最终静态INT OFFSET_X = 5;
/ **在y方向酒吧和边界(顶部和底部)之间的偏移* /
公众最终静态INT OFFSET_Y = 5;
/ **所有酒吧的水平大小在一起* /
公众最终静态INT BAR_WIDTH = 350;
/ **(最大值)条纵向横向尺寸在一起* /
公众最终静态INT BAR_HEIGHT = 250;
/ **毫秒到在分拣动画交换后睡* /
公众最终静态INT SLEEP_AFTER_SWAP = 20;/ **用于数组元素的随机置换* /
私有静态随机aRandom_ =新的随机(System.currentTimeMillis的());
/ **阵列显示* /
私人诠释[] anArrayOfInt_;
/ **脱屏缓冲区* /
私人形象image_;
/ **屏幕外缓冲区的图形* /
私有图形offscreenGraphics_;
////////////////////////////////////////////////// //////////////////////////// **
 *构造函数。
 *
 的数组的元素的* @参数长度没有
 *
 抛出IllegalArgumentException如果阵列< code>长度LT; / code>是
 *要大,以显示(即< code>长度LT; / code基比大
 *< code基BAR_WIDTH< / code>或LT; code基BAR_HEIGHT< / code取代)。
 * /
公共ArrayCanvas(INT长度){
    如果(长度GT; BAR_WIDTH ||长度GT; BAR_HEIGHT)
        抛出新抛出:IllegalArgumentException(数组大:+长);
    anArrayOfInt_ =新INT [长度]
    的for(int i = 0; I<长度; ++ I)
        anArrayOfInt_ [I] I + 1 =;
    置换();
    addMouseListener将(
                     新MouseAdapter(){
        公共无效的mouseClicked(的MouseEvent E){
            重绘();
        }
    }
                     );
}////////////////////////////////////////////////// ///////////////////////////
//重载双缓冲
公共无效更新(图形aGraphics){
    油漆(aGraphics);
}/ **显​​示数组* /
公共无效漆(图形aGraphics){
    INT _deltaX = 0;
    INT W = BAR_WIDTH / anArrayOfInt_.length;
    如果(并且R w 1){
        --w;
        ++ _ DELTAX;
    }
    INT _heightFactor = BAR_HEIGHT / anArrayOfInt_.length;
    如果(offscreenGraphics_ == NULL){
        image_ =的createImage(的getSize()宽的getSize()的高度。);
        offscreenGraphics_ = image_.getGraphics();
    }    offscreenGraphics_.setColor(的getBackground());
    offscreenGraphics_.fillRect(0,0,的getSize()宽度-1,的getSize()高度-1);    offscreenGraphics_.setColor(Color.black);
    //offscreenGraphics_.drawRect(0,0,的getSize()宽度-1,的getSize()高度-1)。。
    offscreenGraphics_.translate(OFFSET_X,OFFSET_Y);
    的for(int i = 0; I< anArrayOfInt_.length ++我){
        INT H = _heightFactor * anArrayOfInt_ [I]
        offscreenGraphics_.setColor(Color.blue);
        offscreenGraphics_.fillRect((W + _deltaX)* I,BAR_HEIGHT-H,W,H);
        如果(anArrayOfInt_ [Ⅰ] ==第(i + 1)){
            offscreenGraphics_.setColor(Color.red);
            offscreenGraphics_.fillRect((W + _deltaX)* I,BAR_HEIGHT-H,W,_heightFactor);
        }
    }    offscreenGraphics_.translate(-OFFSET_X,-OFFSET_Y);
    aGraphics.drawImage(image_,0,0,这一点);
    aGraphics.drawImage(image_,475,0,这一点);
    aGraphics.drawImage(image_,950,0,这一点);
    aGraphics.drawImage(image_,0,350,这一点);
    aGraphics.drawImage(image_,475,350,这一点);
    aGraphics.drawImage(image_,950,350,这一点);}公共尺寸getMinimumSize的(){
    返回新的Dimension(BAR_WIDTH + 2 * OFFSET_X,BAR_HEIGHT + 2 * OFFSET_Y);
}公共尺寸的get preferredSize(){
    返回的getMinimumSize();
}////////////////////////////////////////////////// // **阵列项随机置换* /
公共无效置换(){
    对(INT I = anArrayOfInt_.length-1; ​​I&≠0; --i){
        诠释J = Math.abs(aRandom_.nextInt())%第(i + 1);
        掉期(anArrayOfInt_,I,J);
    }
}
/ **动画排序* /
公共无效排序(字符串aSortNameString){
    mySort(aSortNameString);
}////////////////////////////////////////////////// /
私人无效mySort(字符串aSortNameString){    如果(aSortNameString.equals(冒泡排序)){
        冒泡(anArrayOfInt_);    }    如果(aSortNameString.equals(插入排序)){
        插入排序(anArrayOfInt_);
    }    如果(aSortNameString.equals(选择排序)){
        选择排序(anArrayOfInt_);
    }    如果(aSortNameString.equals(壳类)){
        希尔(anArrayOfInt_);    }
    如果(aSortNameString.equals(堆排序)){
        堆排序(anArrayOfInt_);    }
    如果(aSortNameString.equals(合并排序)){
        合并排序(anArrayOfInt_,0,anArrayOfInt_.length-1);    }
    如果(aSortNameString.equals(快速排序)){
        的qsort(anArrayOfInt_,0,anArrayOfInt_.length-1);    }}/ **
 *交换两个数组元素,重新显​​示阵列中的帆布,
 *并等待片刻。
 * /
私人无效掉期(INT [] anArrayOfInt,INT I,诠释J){
    INT X = anArrayOfInt [I]
    anArrayOfInt [I] = anArrayOfInt [J]。
    anArrayOfInt [J] = X;
    重绘();
    尝试{视频下载(SLEEP_AFTER_SWAP); }赶上(InterruptedException的E){}
}
////////////////////////////////////////////////// ///////////////////////////
//排序算法//
////////////////////////////////////////////////// //////////////////////////// **冒泡排序* /
私人无效冒泡(INT [] anArrayOfInt){
    的for(int i = 0; I< anArrayOfInt.length ++ I)
        对于(INT J = 1; J< anArrayOfInt.length-I; ++ j)条
            如果(anArrayOfInt [J-1]> anArrayOfInt [J]){
                掉期(anArrayOfInt,J-1,J);
            }
}/ **插入排序* /
私人无效插入排序(INT [] anArrayOfInt){
    的for(int i = 0; I< anArrayOfInt.length ++ I)
        为(中间体J = I-1; J> = 0&放大器;&放大器; anArrayOfInt [J]≥anArrayOfInt [J + 1]; --j)
            交换(anArrayOfInt,J,J + 1);
}
/ **选择排序* /
私人无效选择排序(INT [] anArrayOfInt){
    的for(int i = 0; I< anArrayOfInt.length-1 ++ I){
        对于(INT J = I + 1; J< anArrayOfInt.length ++ j)条
            如果(anArrayOfInt [J]< anArrayOfInt [I])
                掉期(anArrayOfInt,I,J);
    }
}/ **希尔排序* /
私人无效希尔(INT [] anArrayOfInt){
    // TODO:计算所需的步骤元素,而不是使用数组
    //(STEPS [I + 1] = 3 *步骤[I] +1)
    的for(int i = 0; I< STEPS.length ++我){
        INT _delta = STEPS [I]
        如果(_delta> = anArrayOfInt.length)
            继续;
        对于(INT J = _delta; J< anArrayOfInt.length ++ j)条
            对于(INT K =焦耳; K-_delta> = 0&放大器;&安培; anArrayOfInt [K]< anArrayOfInt [K- _delta]
                 期k - = _三角洲)
                掉期(anArrayOfInt,K,K-_delta);
    }
}/ **使用希尔排序* /
私人最终静态INT [] = STEPS 1093 {,364,121,40,13,4,1};/ **堆排序* /
私人无效堆排序(INT [] anArrayOfInt){
    INT R = anArrayOfInt.length-1;
    为(中间体L = anArrayOfInt.length / 2 L个; = 0; --L)
        筛(anArrayOfInt,L,R);
    而(R 0){
        掉期(anArrayOfInt,0,R);
        筛(anArrayOfInt,0,--R);
    }
}/ **堆排序辅助功能。 * /
私人无效筛(INT [] anArrayOfInt,诠释L,INT R){
    如果(R = = L)
        返回;
    INT I = 1,J = 2 * l;和
    INT X = anArrayOfInt [I]
    如果(J< R&放大器;&安培; anArrayOfInt [J]< anArrayOfInt [J + 1])
        ++焦耳;
    而(J< = R&放大器;&安培; X< = anArrayOfInt [J]){
        掉期(anArrayOfInt,I,J);
        我= j的; J = 2 *焦耳;
        如果(J< R&放大器;&安培; anArrayOfInt [J]< anArrayOfInt [J + 1])
            ++焦耳;
    }
}/ **快速排序(枢轴=(L + R)/ 2)* /
私人无效的qsort(INT [] anArrayOfInt,诠释L,INT R){
    如果(L> = r)的
        返回;
    交换(anArrayOfInt,L,(L + R)/ 2); // TODO:更聪明支点
    INT _last = 1;
    的for(int i = L + 1; I< = R; + I)
        如果(anArrayOfInt [1] - ; anArrayOfInt [L])
            掉期(anArrayOfInt,++ _最后,我);
    掉期(anArrayOfInt,L,_last);
    的qsort(anArrayOfInt,L,_last-1);
    的qsort(anArrayOfInt,_last + 1,R);
}
/ **归并排序* /
私人无效归并排序(INT [] anArrayOfInt,诠释L,INT R){
    INT [] [] B =新INT [2] [R + 1];
    mergeSort16(anArrayOfInt,B,L,R);
}私人无效mergeSort16(INT [] anArrayOfInt,INT [] [] B,INT L,INT R){
    如果(L> = r)的
        返回;
    INT _last =(L + R)/ 2;
    mergeSort16(anArrayOfInt,B,L,_last);
    mergeSort16(anArrayOfInt,B,_last + 1,R);
    merge6(anArrayOfInt,B,L,_last,R);
}
/ **为合并排序辅助功能* /
保护无效merge6(INT [] anArrayOfInt,INT [] [] B,INT L,INT Q,INT R){
    的for(int i = L,I< = Q;我++){
        B [0] [I] = I;
        B〔1〕[I] = I;
    }
    对于(INT I = R; I>问;我 - ){
        B [0] [I] = R + Q + 1-i的;
        B〔1〕[I] = R + Q + 1-i的;
    }
    INT I = 1;
    诠释J = R;
    对于(时int k = 1; K< R; k ++){
        的int = B [0] [I];
        INT T = B [0] [J]。
        如果(anArrayOfInt [S]< = anArrayOfInt [T]){
            我++;
        }其他{
            S =吨;
            j--;
        }
        交换(anArrayOfInt,S,K);
        T = B〔1] [k]的;
        B [0] [T] = S;
        B〔1] [S] = T;
    }
}}


解决方案

有关您需要某种模式,这应该持有每个排序的当前状态,每个排序图。这可能意味着你加入的 INT 列表,每样一个单独的列表。

您还需要某种机制,它会让你遍历每个排序算法的告诉它移动到下一个步骤,在它的算法,从而使您能够控制在每个排序算法更新,从而控制画面时被更新。

更新

基于来自OP评论

,基本上,我已经拆出来的排序算法作为一个单独的接口。每个算法都需要从这个接口扩展,但它提供了基本的要求,让用户界面渲染的那种动画。

·贝娄是基本的实现,同时它是基于Swing的,如果需要的话,它不会是一个夸张地把它与AWT工作。

 进口java.awt.BorderLayout中;
进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口的java.util.ArrayList;
进口的java.util.List;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.Timer中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;
进口javax.swing.event.ChangeEvent;
进口javax.swing.event.ChangeListener;公共类TestSort {    公共静态无效的主要(字串[] args){
        新TestSort();
    }    公共TestSort(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                }                SortPane sortPane =新SortPane();
                INT值[] =新INT [10];
                对于(INT指数= 0;指数 - LT; values​​.length;指数++){
                    值[指数] =(INT)Math.round(的Math.random()* 100F);
                }
                冒泡分类器=新冒泡(值);
                sortPane.setSorter(分拣机);                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的BorderLayout());
                frame.add(sortPane);
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
                sorter.sort();
            }
        });
    }    公共类SortPane继承JPanel {        私人分拣机分拣机;
        私人ChangeHandler changeHandler;
        私人诠释包括maxValue;        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            Graphics2D的G2D =(Graphics2D的)g.create();
            int值中[] = getSorter()的GetValues​​();
            INT宽度=的getWidth() - 1;
            INT高度=的getHeight() - 1;
            INT列表ColWidth = Math.round((浮点)宽/(浮点)values​​.length);
            INT X = 0;
            颜色填充= Color.YELLOW;
            颜色的亮点= NULL;
            开关(getSorter()。的getState()){
                案例排序:
                    填写= Color.BLUE;
                    突出= Color.RED;
                    打破;
                完成情况:
                    填写= Color.GREEN;
                    打破;
            }
            对于(INT指数= 0;指数 - LT; values​​.length;指数++){
                g2d.setColor(补);
                int值=值[指数]
                INT colHeight =(INT)((浮点)高度*((浮点)值/(浮点)包括maxValue));
                g2d.fillRect(X,身高 - colHeight,列表ColWidth - 1,colHeight);
                如果(getSorter()isActiveIndex(指数)及&安培;突出!= NULL){
                    g2d.setColor(亮点);
                    g2d.drawRect(X,身高 - colHeight,列表ColWidth - 1,colHeight);
                }
                X + =列表ColWidth;
            }
            g2d.dispose();
        }        公共分拣机getSorter(){
            返回分拣机;
        }        公共无效setSorter(分拣值){
            如果(分拣机!=值){
                如果(分拣机!= NULL){
                    sorter.removeChangeListener(getChangeHandler());
                }
                分拣机=价值;
                如果(分拣机!= NULL){
                    sorter.addChangeListener(getChangeHandler());
                    maxValue分别= 0;
                    对(INT的intValue:sorter.getValues​​()){
                        包括maxValue = Math.max(包括maxValue,的intValue);
                    }
                }
                重绘();
            }
        }        公共ChangeHandler getChangeHandler(){
            如果(changeHandler == NULL){
                changeHandler =新ChangeHandler();
            }
            返回changeHandler;
        }        公共类ChangeHandler实现的ChangeListener {
            @覆盖
            公共无效stateChanged(的ChangeEvent发送){
                重绘();
            }
        }    }    公共接口分拣机{        公共枚举国家{
            等候,
            排序,
            做
        }        公共无效addChangeListener(的ChangeListener监听器);
        公共无效removeChangeListener(的ChangeListener监听器);
        公众诠释[]的GetValues​​();
        公共无效的sort();
        公共状态的getState();
        公共布尔isActiveIndex(INT指数);
    }    公共抽象类AbstracSorter实现了分拣机{        私人列表<&的ChangeListener GT;听众;
        私人诠释[]值;
        私有状态状态= State.Waiting;
        私人列表<整数GT; activeIndices;        公共AbstracSorter(INT []值){
            this.values​​ =值;
            听众=新的ArrayList<>(25);
            activeIndices =新的ArrayList<>(2);
        }        @覆盖
        公共状态的getState(){
            返回状态;
        }        公共无效的setState(状态值){
            如果(值!=状态){
                状态=价值;
                fireStateChanged();
            }
        }        @覆盖
        公众诠释[]的GetValues​​(){
            返回值;
        }        @覆盖
        公共无效addChangeListener(的ChangeListener监听){
            listeners.add(监听);
        }        @覆盖
        公共无效removeChangeListener(的ChangeListener监听){
            listeners.remove(监听);
        }        保护无效fireStateChanged(){
            如果(listeners.size()大于0){
                EVT的ChangeEvent =新的ChangeEvent(本);
                对于(的ChangeListener监听器:监听器){
                    listener.stateChanged(EVT);
                }
            }
        }        @覆盖
        公共布尔isActiveIndex(INT指数){
            返回activeIndices.contains(索引);
        }        保护无效setActiveIndicies(INT下,诠释上部){
            activeIndices.clear();
            activeIndices.add(低级);
            activeIndices.add(上部);
            fireStateChanged();
        }        保护无效掉期(INT [] anArrayOfInt,INT I,诠释J){
            setActiveIndicies(I,J);
            INT X = anArrayOfInt [I]
            anArrayOfInt [I] = anArrayOfInt [J]。
            anArrayOfInt [J] = X;
            fireStateChanged();
        }
    }    公共类冒泡扩展AbstracSorter {        私人INT outter = 0;
        私人INT内部= 0;        公共冒泡(INT []值){
            超(值);
        }        @覆盖
        公共无效的sort(){
            的setState(State.Sorting);
            outter = 0;
            内= 1;
            定时器定时器=新定时器(250,新的ActionListener(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    INT [] =值的GetValues​​();
                    内部++;
                    如果(内> = values​​.length - outter){
                        outter ++;
                        内= 1;
                    }                    如果(outter< values​​.length){
                        如果(值[内 - 1]≥值[内]){
                            掉期(价值观,内心 - 1,内部);
                        }其他{
                            setActiveIndicies(内 - 1,内部);
                        }
                    }其他{
                        ((定时器)e.getSource())停止();
                        的setState(State.Done);
                    }
                }
            });
            timer.setRepeats(真);
            timer.start();
        }
    }
}

使用源阵列示例

 进口java.awt.Color中;
进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.GridLayout中;
进口java.awt.Insets中;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口的java.util.ArrayList;
进口的java.util.List;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.Timer中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;
进口javax.swing.border.CompoundBorder;
进口javax.swing.border.EmptyBorder中;
进口javax.swing.border.LineBorder中;
进口javax.swing.event.ChangeEvent;
进口javax.swing.event.ChangeListener;公共类TestSort {    公共静态无效的主要(字串[] args){
        新TestSort();
    }
    私人列表<&分拣机GT;分拣;    公共TestSort(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                }                分拣机=新的ArrayList<>(2);
                INT值[] =新INT [10];
                对于(INT指数= 0;指数 - LT; values​​.length;指数++){
                    值[指数] =(INT)Math.round(的Math.random()* 100F);
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(新的GridLayout(0,2));
                frame.add(createBubbleSortPane(值));
                frame.add(createBubbleSortPane(值));
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);                对于(分拣机分拣机:分拣机){
                    sorter.sort();
                }
            }
        });
    }    保护SortPane createBubbleSortPane(INT []值){
        SortPane sortPane =新SortPane();
        冒泡分类器=新冒泡(值);
        sortPane.setSorter(分拣机);        sortPane.setBorder(新CompoundBorder(新LineBorder(Color.GRAY),新EmptyBorder(8,​​8,8,8)));        sorters.add(分拣机);        返回sortPane;
    }    公共类SortPane继承JPanel {        私人分拣机分拣机;
        私人ChangeHandler changeHandler;
        私人诠释包括maxValue;        @覆盖
        公共尺寸的get preferredSize(){
            返回新尺寸(200,200);
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            Graphics2D的G2D =(Graphics2D的)g.create();
            int值中[] = getSorter()的GetValues​​();
            插图插图=的getInsets();
            INT宽度=的getWidth() - 1 - (insets.left + insets.right);
            INT高度=的getHeight() - 1 - (insets.top + insets.bottom);
            INT列表ColWidth = Math.round((浮点)宽/(浮点)values​​.length);
            INT X = insets.left;
            颜色填充= Color.YELLOW;
            颜色的亮点= NULL;
            开关(getSorter()。的getState()){
                案例排序:
                    填写= Color.BLUE;
                    突出= Color.RED;
                    打破;
                完成情况:
                    填写= Color.GREEN;
                    打破;
            }
            对于(INT指数= 0;指数 - LT; values​​.length;指数++){
                g2d.setColor(补);
                int值=值[指数]
                INT colHeight =(INT)((浮点)高度*((浮点)值/(浮点)包括maxValue));
                g2d.fillRect(X,insets.top +高 - colHeight,列表ColWidth - 1,colHeight);
                如果(getSorter()isActiveIndex(指数)及&安培;突出!= NULL){
                    g2d.setColor(亮点);
                    g2d.drawRect(X,insets.top +高 - colHeight,列表ColWidth - 1,colHeight);
                }
                X + =列表ColWidth;
            }
            g2d.dispose();
        }        公共分拣机getSorter(){
            返回分拣机;
        }        公共无效setSorter(分拣值){
            如果(分拣机!=值){
                如果(分拣机!= NULL){
                    sorter.removeChangeListener(getChangeHandler());
                }
                分拣机=价值;
                如果(分拣机!= NULL){
                    sorter.addChangeListener(getChangeHandler());
                    maxValue分别= 0;
                    对(INT的intValue:sorter.getValues​​()){
                        包括maxValue = Math.max(包括maxValue,的intValue);
                    }
                }
                重绘();
            }
        }        公共ChangeHandler getChangeHandler(){
            如果(changeHandler == NULL){
                changeHandler =新ChangeHandler();
            }
            返回changeHandler;
        }        公共类ChangeHandler实现的ChangeListener {            @覆盖
            公共无效stateChanged(的ChangeEvent发送){
                重绘();
            }
        }
    }    公共接口分拣机{        公共枚举国家{            等候,
            排序,
            做
        }        公共无效addChangeListener(的ChangeListener监听器);        公共无效removeChangeListener(的ChangeListener监听器);        公众诠释[]的GetValues​​();        公共无效的sort();        公共状态的getState();        公共布尔isActiveIndex(INT指数);
    }    公共抽象类AbstracSorter实现了分拣机{        私人列表<&的ChangeListener GT;听众;
        私人诠释[]值;
        私有状态状态= State.Waiting;
        私人列表<整数GT; activeIndices;        公共AbstracSorter(INT []值){
            this.values​​ =新INT [values​​.length]
            System.arraycopy(值,0,this.values​​,0,values​​.length);
            听众=新的ArrayList<>(25);
            activeIndices =新的ArrayList<>(2);
        }        @覆盖
        公共状态的getState(){
            返回状态;
        }        公共无效的setState(状态值){
            如果(值!=状态){
                状态=价值;
                fireStateChanged();
            }
        }        @覆盖
        公众诠释[]的GetValues​​(){
            返回值;
        }        @覆盖
        公共无效addChangeListener(的ChangeListener监听){
            listeners.add(监听);
        }        @覆盖
        公共无效removeChangeListener(的ChangeListener监听){
            listeners.remove(监听);
        }        保护无效fireStateChanged(){
            如果(listeners.size()大于0){
                EVT的ChangeEvent =新的ChangeEvent(本);
                对于(的ChangeListener监听器:监听器){
                    listener.stateChanged(EVT);
                }
            }
        }        @覆盖
        公共布尔isActiveIndex(INT指数){
            返回activeIndices.contains(索引);
        }        保护无效setActiveIndicies(INT下,诠释上部){
            activeIndices.clear();
            activeIndices.add(低级);
            activeIndices.add(上部);
            fireStateChanged();
        }        保护无效掉期(INT [] anArrayOfInt,INT I,诠释J){
            setActiveIndicies(I,J);
            INT X = anArrayOfInt [I]
            anArrayOfInt [I] = anArrayOfInt [J]。
            anArrayOfInt [J] = X;
            fireStateChanged();
        }
    }    公共类冒泡扩展AbstracSorter {        私人INT outter = 0;
        私人INT内部= 0;        公共冒泡(INT []值){
            超(值);
        }        @覆盖
        公共无效的sort(){
            的setState(State.Sorting);
            outter = 0;
            内= 1;
            定时器定时器=新定时器(250,新的ActionListener(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    INT [] =值的GetValues​​();
                    内部++;
                    如果(内> = values​​.length - outter){
                        outter ++;
                        内= 1;
                    }                    如果(outter< values​​.length){
                        如果(值[内 - 1]≥值[内]){
                            掉期(价值观,内心 - 1,内部);
                        }其他{
                            setActiveIndicies(内 - 1,内部);
                        }
                    }其他{
                        ((定时器)e.getSource())停止();
                        的setState(State.Done);
                    }
                }
            });
            timer.setRepeats(真);
            timer.start();
        }
    }
}

示例插入排列

这是一个使用主题的一个例子作为主排序引擎,而不是一个Swing 定时

 公共类InsertionSorter扩展AbstracSorter {    公共InsertionSorter(INT []值){
        超(值);
    }    @覆盖
    公共无效的sort(){
        的setState(State.Sorting);
        新主题(新的SortRunnable())开始()。
    }    @覆盖
    保护无效掉期(INT [] anArrayOfInt,INT I,诠释J){
        setActiveIndicies(I,J);
        INT X = anArrayOfInt [I]
        anArrayOfInt [I] = anArrayOfInt [J]。
        anArrayOfInt [J] = X;
        尝试{
            SwingUtilities.invokeAndWait(新的Runnable(){
                @覆盖
                公共无效的run(){
                    fireStateChanged();
                }
            });
        }赶上(InterruptedException的|的InvocationTargetException EXP){
            exp.printStackTrace();
        }
    }    公共类SortRunnable实现Runnable {        @覆盖
        公共无效的run(){
            INT [] =值的GetValues​​();
            的for(int i = 0; I< values​​.length ++我){
                为(中间体J = - 1; J> = 0&放大器;&放大器;值[J]≥值[J + 1]; --j){
                    尝试{
                        视频下载(250);
                    }赶上(InterruptedException的前){
                    }
                    交换(值,J,J + 1);
                }
            }
            SwingUtilities.invokeLater(Runnable的新(){
                @覆盖
                公共无效的run(){
                    的setState(State.Done);
                }
            });
        }
    }
}

Okay so I have been working on this code for awhile that shows how the sorting algorithms work. Right now I have it working where it sorts multiple graphs with the same sort but I need each graph to do a different sort at the same time. I have been researching and trying to solve this for days and now I just have tunnel vision. I'll post my code in case my explanation was confusing. I feel like this could benefit a lot of people working with java graphics and any help would be appreciated.

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Scanner;


public class Sort extends Applet {

/** Constructor. Only for starting the sorting animation as applet. */
public Sort() {}


/** For starting the sorting animation as application. */
public static void main(String[] argv) {
    Frame _aFrame = new Frame("Sort Animations");
    _aFrame.setBackground(Color.white);
    _aFrame.setPreferredSize(new Dimension(2700,1000)); 

    Scanner in = new Scanner(System.in);
    int sizeOfArray;
    System.out.println("How many numbers do you want to sort?");
    sizeOfArray = in.nextInt();


    _aFrame.addWindowListener(
                              new WindowAdapter() {
        public void windowClosing(WindowEvent e) { System.exit(0); }
    }
                              );

    _aFrame.setLayout(new BorderLayout());
    _aFrame.add(new SortPanel(sizeOfArray));
    _aFrame.pack();
    _aFrame.setVisible(true);
}

}



class SortPanel extends Panel implements Runnable {

/** button triggering the sort animation */
private Button aSortButton_    = new Button("sort");
/** choice item for selecting the sort algorithm */
private Choice aChoice_ = new Choice();
/** component for handling the animation */
private ArrayCanvas anArrayCanvas_;


/////////////////////////////////////////////////////////////////////////////

/**
 * Constructor.
 *
 * @param length    no of elements of the array
 * @param aBarColor the color the elements representing bars will be drawn in
 *
 * @exception IllegalArgumentException if the array <code>length</code> is
 *            to big to display (ie <code>length</code> is bigger than
 *            <code>BAR_WIDTH</code> or <code>BAR_HEIGHT</code>).
 */
public SortPanel(int arraySize) {
    setLayout(new BorderLayout());


    aSortButton_.addActionListener(
                new     ActionListener() {
        public void actionPerformed(ActionEvent e) {
            new Thread(SortPanel.this).start();
        }
    }
                );


    anArrayCanvas_ = new ArrayCanvas(arraySize);
    for (int i=0; i<ArrayCanvas.SORT_NAMES.length; ++i)
        aChoice_.add(ArrayCanvas.SORT_NAMES[i]);

    // add buttons at top:
    Panel _aTopPanel = new Panel();
    _aTopPanel.add(aSortButton_);
    add(_aTopPanel, BorderLayout.NORTH);

    // add choice and ArrayCanvas below:
    Panel _aPanel = new Panel();
    _aPanel.setLayout(new BorderLayout());
    Panel _aChoicePanel = new Panel();
    _aChoicePanel.add(aChoice_);
    _aPanel.add(_aChoicePanel, BorderLayout.NORTH);
    _aPanel.add(anArrayCanvas_, BorderLayout.CENTER);

    add(_aPanel, BorderLayout.CENTER);

    Panel _aBottomPanel = new Panel();
    add(_aBottomPanel, BorderLayout.SOUTH);
}

/////////////////////////////////////////////////////////////////////////////

/** Runs the sorting animation. */
public void run() {
    aSortButton_.setEnabled(false);
    double time = System.currentTimeMillis();
    anArrayCanvas_.sort(aChoice_.getSelectedItem());
    aSortButton_.setEnabled(true);
}
}

class ArrayCanvas extends Canvas {

/** Labels of available sorting algorithms. */
public final static String[] SORT_NAMES = { "bubble sort", "insertion sort", "shell  sort", "heap sort", "merge sort", "quick sort",};

/** offset between bars and border in x-directions (left and right) */
public final static int OFFSET_X         = 5;
/** offset between bars and border in y-directions (top and bottom) */
public final static int OFFSET_Y         = 5;
/** horizontal size of all bars together */
public final static int BAR_WIDTH        = 350;
/** (max) vertical horizontal size of bars together */
public final static int BAR_HEIGHT       = 250;
/** milliseconds to sleep after a swap in the sorting animation */
public final static int SLEEP_AFTER_SWAP = 20;

/** used for random permutation of the array elements */
private static Random aRandom_ = new Random(System.currentTimeMillis());
/** the array to display */
private int[] anArrayOfInt_;
/** offscreen buffer */
private Image image_;
/** graphics of the offscreen buffer */
private Graphics offscreenGraphics_;




/////////////////////////////////////////////////////////////////////////////

/**
 * Constructor.
 *
 * @param length    no of elements of the array
 *
 * @exception IllegalArgumentException if the array <code>length</code> is
 *            to big to display (ie <code>length</code> is bigger than
 *            <code>BAR_WIDTH</code> or <code>BAR_HEIGHT</code>).
 */
public ArrayCanvas(int length) {
    if (length > BAR_WIDTH || length > BAR_HEIGHT)
        throw new IllegalArgumentException("array to big: "+length);
    anArrayOfInt_ = new int[length];
    for (int i=0; i<length; ++i)
        anArrayOfInt_[i] = i+1;
    permute();
    addMouseListener(
                     new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            repaint();
        }
    }
                     );
}

/////////////////////////////////////////////////////////////////////////////


// overloaded for double buffering
public void update(Graphics aGraphics) {
    paint(aGraphics);
}

/** displays the array */
public void paint(Graphics aGraphics) {
    int _deltaX = 0;
    int w = BAR_WIDTH / anArrayOfInt_.length;
    if (w > 1) {
        --w;
        ++_deltaX;
    }
    int _heightFactor = BAR_HEIGHT / anArrayOfInt_.length;
    if (offscreenGraphics_ == null) {
        image_ = createImage(getSize().width, getSize().height);
        offscreenGraphics_ = image_.getGraphics();
    }

    offscreenGraphics_.setColor(getBackground());
    offscreenGraphics_.fillRect(0, 0, getSize().width-1, getSize().height-1);

    offscreenGraphics_.setColor(Color.black);
    //offscreenGraphics_.drawRect(0, 0, getSize().width-1, getSize().height-1);
    offscreenGraphics_.translate(OFFSET_X, OFFSET_Y);
    for (int i=0; i<anArrayOfInt_.length; ++i) {
        int h = _heightFactor*anArrayOfInt_[i];
        offscreenGraphics_.setColor(Color.blue);
        offscreenGraphics_.fillRect((w+_deltaX)*i, BAR_HEIGHT-h, w, h);
        if(anArrayOfInt_[i]==(i+1)){
            offscreenGraphics_.setColor(Color.red);
            offscreenGraphics_.fillRect((w+_deltaX)*i, BAR_HEIGHT-h, w, _heightFactor);
        }
    }

    offscreenGraphics_.translate(-OFFSET_X, -OFFSET_Y);
    aGraphics.drawImage(image_, 0, 0, this);
    aGraphics.drawImage(image_, 475, 0, this);
    aGraphics.drawImage(image_, 950, 0, this);
    aGraphics.drawImage(image_, 0, 350, this);
    aGraphics.drawImage(image_, 475, 350, this);
    aGraphics.drawImage(image_, 950, 350, this);

}

public Dimension getMinimumSize() {
    return new Dimension(BAR_WIDTH+2*OFFSET_X, BAR_HEIGHT+2*OFFSET_Y);
}

public Dimension getPreferredSize() {
    return getMinimumSize();
}

///////////////////////////////////////////////////

/** random permutation of array entries */
public void permute() {
    for (int i=anArrayOfInt_.length-1; i>0; --i) {
        int j = Math.abs(aRandom_.nextInt()) % (i+1);
        swap(anArrayOfInt_,i,j);
    }
}


/** animated sort */
public void sort(String aSortNameString) {
    mySort(aSortNameString);
}

///////////////////////////////////////////////////


private void mySort(String aSortNameString) {

    if (aSortNameString.equals("bubble sort")) {
        bubbleSort(anArrayOfInt_);

    }

    if (aSortNameString.equals("insertion sort")) {
        insertionSort(anArrayOfInt_);
    }

    if (aSortNameString.equals("selection sort")) {
        selectionSort(anArrayOfInt_);
    }

    if (aSortNameString.equals("shell sort")) {
        shellSort(anArrayOfInt_);

    }
    if (aSortNameString.equals("heap sort")) {
        heapSort(anArrayOfInt_);

    }
    if (aSortNameString.equals("merge sort")) {
        mergeSort(anArrayOfInt_, 0, anArrayOfInt_.length-1);

    }
    if (aSortNameString.equals("quick sort")) {
        qSort(anArrayOfInt_, 0, anArrayOfInt_.length-1);

    }

}

/**
 * swaps the two array elements, redisplays the array in its canvas,
 * and waits a moment.
 */
private void swap(int[] anArrayOfInt, int i, int j) {
    int x = anArrayOfInt[i];
    anArrayOfInt[i] = anArrayOfInt[j];
    anArrayOfInt[j] = x;
    repaint();
    try { Thread.sleep(SLEEP_AFTER_SWAP); } catch (InterruptedException e) {}
}


/////////////////////////////////////////////////////////////////////////////
//                          SORTING ALGORITHMS                             //
/////////////////////////////////////////////////////////////////////////////

/** bubble sort */
private void bubbleSort(int[] anArrayOfInt) {
    for (int i=0; i<anArrayOfInt.length; ++i)
        for (int j=1; j<anArrayOfInt.length-i; ++j)
            if (anArrayOfInt[j-1]>anArrayOfInt[j]) {
                swap(anArrayOfInt, j-1, j);
            }
}



/** insertion sort */
private void insertionSort(int[] anArrayOfInt) {
    for (int i=0; i<anArrayOfInt.length; ++i)
        for (int j=i-1; j>=0 && anArrayOfInt[j]>anArrayOfInt[j+1]; --j)
            swap(anArrayOfInt, j, j+1);
}


/** selection sort */
private void selectionSort(int[] anArrayOfInt) {
    for (int i=0; i<anArrayOfInt.length-1; ++i) {
        for (int j=i+1; j<anArrayOfInt.length; ++j)
            if (anArrayOfInt[j] < anArrayOfInt[i])
                swap(anArrayOfInt, i, j);
    }
}

/** shell sort */
private void shellSort(int[] anArrayOfInt) {
    // TODO: calculate needed STEPS-elements instead of using an array
    //       (STEPS[i+1] = 3*STEPS[i]+1)
    for (int i=0; i<STEPS.length; ++i) {
        int _delta = STEPS[i];
        if (_delta >= anArrayOfInt.length)
            continue;
        for (int j=_delta; j<anArrayOfInt.length; ++j)
            for (int k=j; k-_delta>=0 && anArrayOfInt[k]<anArrayOfInt[k-  _delta];
                 k-=_delta)
                swap(anArrayOfInt, k, k-_delta);
    }
}

/** used by shell sort */
private final static int[] STEPS = { 1093, 364, 121, 40, 13, 4, 1 };

/** heap sort */
private void heapSort(int[] anArrayOfInt) {
    int r = anArrayOfInt.length-1;
    for (int l = anArrayOfInt.length/2 ; l>=0; --l)
        sift(anArrayOfInt, l, r);
    while (r > 0) {
        swap(anArrayOfInt, 0, r);
        sift(anArrayOfInt, 0, --r);
    }
}

/** auxiliary function for heap sort. */
private void sift(int[] anArrayOfInt, int l, int r) {
    if (r==l)
        return;
    int i = l, j = 2*l;
    int x = anArrayOfInt[i];
    if (j<r && anArrayOfInt[j]<anArrayOfInt[j+1])
        ++j;
    while (j<=r && x<=anArrayOfInt[j]) {
        swap(anArrayOfInt, i, j);
        i = j; j = 2*j;
        if (j<r && anArrayOfInt[j]<anArrayOfInt[j+1])
            ++j;
    }
}

/** quick sort (pivot=(l+r)/2)*/
private void qSort(int[] anArrayOfInt, int l, int r) {
    if (l >= r)
        return;
    swap(anArrayOfInt, l, (l+r)/2); // TODO: more clever pivot
    int _last = l;
    for (int i=l+1; i<=r; ++i)
        if (anArrayOfInt[i] < anArrayOfInt[l])
            swap(anArrayOfInt, ++_last, i);
    swap(anArrayOfInt, l, _last);
    qSort(anArrayOfInt, l, _last-1);
    qSort(anArrayOfInt, _last+1, r);
}


/** merge sort */
private void mergeSort(int[] anArrayOfInt, int l, int r) {
    int[][] B = new int[2][r+1];
    mergeSort16(anArrayOfInt, B, l, r);
}

private void mergeSort16(int[] anArrayOfInt, int[][] B, int l, int r) {
    if (l >= r)
        return;
    int _last = (l+r)/2;
    mergeSort16(anArrayOfInt, B, l, _last);
    mergeSort16(anArrayOfInt, B, _last+1, r);
    merge6(anArrayOfInt, B, l, _last, r);
}
/** auxiliary function for merge sort */
protected void merge6(int[] anArrayOfInt, int[][] B, int l, int q, int r) {
    for (int i=l;i<=q;i++) {
        B[0][i] = i;
        B[1][i] = i;
    }
    for (int i=r;i>q;i--) {
        B[0][i] = r+q+1-i;
        B[1][i] = r+q+1-i;
    }
    int i = l;
    int j = r;
    for (int k=l; k<r;k++) {
        int s = B[0][i];
        int t = B[0][j];
        if (anArrayOfInt[s]<=anArrayOfInt[t]) {
            i++;
        } else {
            s = t;
            j--;
        }
        swap(anArrayOfInt, s, k);
        t = B[1][k];
        B[0][t] = s;
        B[1][s] = t;
    }
}

}

解决方案

For each sort graph you need some kind of model, which should hold the current state of each sort. This would probably mean adding your list of ints to a separate list per sort.

You would also need some kind of mechanism that would allow you to loop through each sort algorithm an tell it to move to the next step in it's algorithm, thus allowing you to control when each sort algorithm update and therefore control when the screen is updated.

Updated

Based on a comment from the OP, basically, I've ripped out the sort algorithm as a separate interface. Each algorithm would need to extend from this interface, but it provides the basic requirements to allow the UI to render the sort animation.

Bellow is basic implementation, while it's based on Swing, if required, it wouldn't be a stretch to get it to work with AWT.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestSort {

    public static void main(String[] args) {
        new TestSort();
    }

    public TestSort() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                SortPane sortPane = new SortPane();
                int values[] = new int[10];
                for (int index = 0; index < values.length; index++) {
                    values[index] = (int)Math.round(Math.random() * 100f);
                }
                BubbleSort sorter = new BubbleSort(values);
                sortPane.setSorter(sorter);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(sortPane);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
                sorter.sort();
            }
        });
    }

    public class SortPane extends JPanel {

        private Sorter sorter;
        private ChangeHandler changeHandler;
        private int maxValue;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int values[] = getSorter().getValues();
            int width = getWidth() - 1;
            int height = getHeight() - 1;
            int colWidth = Math.round((float)width / (float)values.length);
            int x = 0;
            Color fill = Color.YELLOW;
            Color highlight = null;
            switch (getSorter().getState()) {
                case Sorting:
                    fill = Color.BLUE;
                    highlight = Color.RED;
                    break;
                case Done:
                    fill = Color.GREEN;
                    break;
            }
            for (int index = 0; index < values.length; index++) {
                g2d.setColor(fill);
                int value = values[index];
                int colHeight = (int)((float)height * ((float)value / (float)maxValue));
                g2d.fillRect(x, height - colHeight, colWidth - 1, colHeight);
                if (getSorter().isActiveIndex(index) && highlight != null) {
                    g2d.setColor(highlight);
                    g2d.drawRect(x, height - colHeight, colWidth - 1, colHeight);
                }
                x += colWidth;
            }
            g2d.dispose();
        }

        public Sorter getSorter() {
            return sorter;
        }

        public void setSorter(Sorter value) {
            if (sorter != value) {
                if (sorter != null) {
                    sorter.removeChangeListener(getChangeHandler());
                }
                sorter = value;
                if (sorter != null) {
                    sorter.addChangeListener(getChangeHandler());
                    maxValue = 0;
                    for (int intValue : sorter.getValues()) {
                        maxValue = Math.max(maxValue, intValue);
                    }
                }
                repaint();
            }
        }

        public ChangeHandler getChangeHandler() {
            if (changeHandler == null) {
                changeHandler = new ChangeHandler();
            }
            return changeHandler;
        }

        public class ChangeHandler implements ChangeListener {
            @Override
            public void stateChanged(ChangeEvent e) {
                repaint();
            }
        }

    }

    public interface Sorter {

        public enum State {
            Waiting,
            Sorting,
            Done
        }

        public void addChangeListener(ChangeListener listener);
        public void removeChangeListener(ChangeListener listener);
        public int[] getValues();
        public void sort();
        public State getState();
        public boolean isActiveIndex(int index);
    }

    public abstract class AbstracSorter implements Sorter {

        private List<ChangeListener> listeners;
        private int[] values;
        private State state = State.Waiting;
        private List<Integer> activeIndices;

        public AbstracSorter(int[] values) {
            this.values = values;
            listeners = new ArrayList<>(25);
            activeIndices = new ArrayList<>(2);
        }

        @Override
        public State getState() {
            return state;
        }

        public void setState(State value) {
            if (value != state) {
                state = value;
                fireStateChanged();
            }
        }

        @Override
        public int[] getValues() {
            return values;
        }

        @Override
        public void addChangeListener(ChangeListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeChangeListener(ChangeListener listener) {
            listeners.remove(listener);
        }

        protected void fireStateChanged() {
            if (listeners.size() > 0) {
                ChangeEvent evt = new ChangeEvent(this);
                for (ChangeListener listener : listeners) {
                    listener.stateChanged(evt);
                }
            }
        }

        @Override
        public boolean isActiveIndex(int index) {
            return activeIndices.contains(index);
        }

        protected void setActiveIndicies(int lower, int upper) {
            activeIndices.clear();
            activeIndices.add(lower);
            activeIndices.add(upper);
            fireStateChanged();
        }

        protected void swap(int[] anArrayOfInt, int i, int j) {
            setActiveIndicies(i, j);
            int x = anArrayOfInt[i];
            anArrayOfInt[i] = anArrayOfInt[j];
            anArrayOfInt[j] = x;
            fireStateChanged();
        }
    }

    public class BubbleSort extends AbstracSorter {

        private int outter = 0;
        private int inner = 0;

        public BubbleSort(int[] values) {
            super(values);
        }

        @Override
        public void sort() {
            setState(State.Sorting);
            outter = 0;
            inner = 1;
            Timer timer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int[] values = getValues();
                    inner++;
                    if (inner >= values.length - outter) {
                        outter++;
                        inner = 1;
                    }

                    if (outter < values.length) {
                        if (values[inner - 1] > values[inner]) {
                            swap(values, inner - 1, inner);
                        } else {
                            setActiveIndicies(inner - 1, inner);
                        }
                    } else {
                        ((Timer)e.getSource()).stop();
                        setState(State.Done);
                    }
                }
            });
            timer.setRepeats(true);
            timer.start();
        }
    }
}

Example using the source array

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class TestSort {

    public static void main(String[] args) {
        new TestSort();
    }
    private List<Sorter> sorters;

    public TestSort() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                sorters = new ArrayList<>(2);
                int values[] = new int[10];
                for (int index = 0; index < values.length; index++) {
                    values[index] = (int) Math.round(Math.random() * 100f);
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridLayout(0, 2));
                frame.add(createBubbleSortPane(values));
                frame.add(createBubbleSortPane(values));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                for (Sorter sorter : sorters) {
                    sorter.sort();
                }
            }
        });
    }

    protected SortPane createBubbleSortPane(int[] values) {
        SortPane sortPane = new SortPane();
        BubbleSort sorter = new BubbleSort(values);
        sortPane.setSorter(sorter);

        sortPane.setBorder(new CompoundBorder(new LineBorder(Color.GRAY), new EmptyBorder(8, 8, 8, 8)));

        sorters.add(sorter);

        return sortPane;
    }

    public class SortPane extends JPanel {

        private Sorter sorter;
        private ChangeHandler changeHandler;
        private int maxValue;

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int values[] = getSorter().getValues();
            Insets insets = getInsets();
            int width = getWidth() - 1 - (insets.left + insets.right);
            int height = getHeight() - 1 - (insets.top + insets.bottom);
            int colWidth = Math.round((float) width / (float) values.length);
            int x = insets.left;
            Color fill = Color.YELLOW;
            Color highlight = null;
            switch (getSorter().getState()) {
                case Sorting:
                    fill = Color.BLUE;
                    highlight = Color.RED;
                    break;
                case Done:
                    fill = Color.GREEN;
                    break;
            }
            for (int index = 0; index < values.length; index++) {
                g2d.setColor(fill);
                int value = values[index];
                int colHeight = (int) ((float) height * ((float) value / (float) maxValue));
                g2d.fillRect(x, insets.top + height - colHeight, colWidth - 1, colHeight);
                if (getSorter().isActiveIndex(index) && highlight != null) {
                    g2d.setColor(highlight);
                    g2d.drawRect(x, insets.top + height - colHeight, colWidth - 1, colHeight);
                }
                x += colWidth;
            }
            g2d.dispose();
        }

        public Sorter getSorter() {
            return sorter;
        }

        public void setSorter(Sorter value) {
            if (sorter != value) {
                if (sorter != null) {
                    sorter.removeChangeListener(getChangeHandler());
                }
                sorter = value;
                if (sorter != null) {
                    sorter.addChangeListener(getChangeHandler());
                    maxValue = 0;
                    for (int intValue : sorter.getValues()) {
                        maxValue = Math.max(maxValue, intValue);
                    }
                }
                repaint();
            }
        }

        public ChangeHandler getChangeHandler() {
            if (changeHandler == null) {
                changeHandler = new ChangeHandler();
            }
            return changeHandler;
        }

        public class ChangeHandler implements ChangeListener {

            @Override
            public void stateChanged(ChangeEvent e) {
                repaint();
            }
        }
    }

    public interface Sorter {

        public enum State {

            Waiting,
            Sorting,
            Done
        }

        public void addChangeListener(ChangeListener listener);

        public void removeChangeListener(ChangeListener listener);

        public int[] getValues();

        public void sort();

        public State getState();

        public boolean isActiveIndex(int index);
    }

    public abstract class AbstracSorter implements Sorter {

        private List<ChangeListener> listeners;
        private int[] values;
        private State state = State.Waiting;
        private List<Integer> activeIndices;

        public AbstracSorter(int[] values) {
            this.values = new int[values.length];
            System.arraycopy(values, 0, this.values, 0, values.length);
            listeners = new ArrayList<>(25);
            activeIndices = new ArrayList<>(2);
        }

        @Override
        public State getState() {
            return state;
        }

        public void setState(State value) {
            if (value != state) {
                state = value;
                fireStateChanged();
            }
        }

        @Override
        public int[] getValues() {
            return values;
        }

        @Override
        public void addChangeListener(ChangeListener listener) {
            listeners.add(listener);
        }

        @Override
        public void removeChangeListener(ChangeListener listener) {
            listeners.remove(listener);
        }

        protected void fireStateChanged() {
            if (listeners.size() > 0) {
                ChangeEvent evt = new ChangeEvent(this);
                for (ChangeListener listener : listeners) {
                    listener.stateChanged(evt);
                }
            }
        }

        @Override
        public boolean isActiveIndex(int index) {
            return activeIndices.contains(index);
        }

        protected void setActiveIndicies(int lower, int upper) {
            activeIndices.clear();
            activeIndices.add(lower);
            activeIndices.add(upper);
            fireStateChanged();
        }

        protected void swap(int[] anArrayOfInt, int i, int j) {
            setActiveIndicies(i, j);
            int x = anArrayOfInt[i];
            anArrayOfInt[i] = anArrayOfInt[j];
            anArrayOfInt[j] = x;
            fireStateChanged();
        }
    }

    public class BubbleSort extends AbstracSorter {

        private int outter = 0;
        private int inner = 0;

        public BubbleSort(int[] values) {
            super(values);
        }

        @Override
        public void sort() {
            setState(State.Sorting);
            outter = 0;
            inner = 1;
            Timer timer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int[] values = getValues();
                    inner++;
                    if (inner >= values.length - outter) {
                        outter++;
                        inner = 1;
                    }

                    if (outter < values.length) {
                        if (values[inner - 1] > values[inner]) {
                            swap(values, inner - 1, inner);
                        } else {
                            setActiveIndicies(inner - 1, inner);
                        }
                    } else {
                        ((Timer) e.getSource()).stop();
                        setState(State.Done);
                    }
                }
            });
            timer.setRepeats(true);
            timer.start();
        }
    }
}

Example Insertion Sorter

This is an example of using a Thread as the primary sort engine instead of a Swing Timer

public class InsertionSorter extends AbstracSorter {

    public InsertionSorter(int[] values) {
        super(values);
    }

    @Override
    public void sort() {
        setState(State.Sorting);
        new Thread(new SortRunnable()).start();
    }

    @Override
    protected void swap(int[] anArrayOfInt, int i, int j) {
        setActiveIndicies(i, j);
        int x = anArrayOfInt[i];
        anArrayOfInt[i] = anArrayOfInt[j];
        anArrayOfInt[j] = x;
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {
                    fireStateChanged();
                }
            });
        } catch (InterruptedException | InvocationTargetException exp) {
            exp.printStackTrace();
        }
    }

    public class SortRunnable implements Runnable {

        @Override
        public void run() {
            int[] values = getValues();
            for (int i = 0; i < values.length; ++i) {
                for (int j = i - 1; j >= 0 && values[j] > values[j + 1]; --j) {
                    try {
                        Thread.sleep(250);
                    } catch (InterruptedException ex) {
                    }
                    swap(values, j, j + 1);
                }
            }
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    setState(State.Done);
                }
            });
        }
    }
}

这篇关于java的多个图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆