java多个graphics
好,所以我一直在研究这个代码,显示了sortingalgorithm是如何工作的。 现在我有它在同一sorting多个图表sorting的工作,但我需要每个图表在同一时间做不同的sorting。 我一直在研究和试图解决这个问题,现在我只是拥有隧道视野。 我会发布我的代码,以防我的解释混乱。 我觉得这可能会使很多使用javagraphics的人受益,任何帮助都将不胜感激。
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; } } }
对于每个sorting图,您需要某种模型,它应该保持每种sorting的当前状态。 这可能意味着将你的int
列表添加到一个单独的列表中。
您还需要某种机制,使您可以遍历每个sortingalgorithm,并告诉它移动到其algorithm中的下一个步骤,从而允许您控制每个sortingalgorithm何时更新,从而控制何时更新屏幕。
更新
基于OP的评论,基本上,我已经把sortingalgorithm作为一个单独的接口进行了挖掘。 每个algorithm都需要从这个接口扩展,但是它提供了允许UI呈现sortinganimation的基本要求。
贝娄是基本的实现,而它是基于Swing的,如果需要的话,要使它与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(); } } }
使用源数组的示例
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(); } } }
示例插入式分拣机
这是使用Thread
作为主sorting引擎而不是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); } }); } } }