java multiple graphics [closed]

跟風遠走 提交于 2019-12-17 03:44:07

问题


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;
    }
}

}

回答1:


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 and tell it to move to the next step in its 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);
                }
            });
        }
    }
}


来源:https://stackoverflow.com/questions/15756210/java-multiple-graphics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!