múltiples gráficos java

Está bien, así que he estado trabajando en este código por un tiempo que muestra cómo funcionan los algoritmos de clasificación. En este momento lo tengo funcionando donde ordena múltiples gráficos con el mismo tipo, pero necesito que cada gráfico haga un tipo diferente al mismo tiempo. He estado investigando e intentando resolver esto durante días y ahora solo tengo una visión de túnel. Publicaré mi código en caso de que mi explicación fuera confusa. Siento que esto podría beneficiar a muchas personas que trabajan con gráficos de Java y cualquier ayuda sería apreciada.

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 length is * to big to display (ie length is bigger than * BAR_WIDTH or BAR_HEIGHT). */ 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 length is * to big to display (ie length is bigger than * BAR_WIDTH or BAR_HEIGHT). */ 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 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; i0; --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; janArrayOfInt[j]) { swap(anArrayOfInt, j-1, j); } } /** insertion sort */ private void insertionSort(int[] anArrayOfInt) { for (int i=0; i=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= anArrayOfInt.length) continue; for (int j=_delta; j=0 && anArrayOfInt[k]=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]= 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] = 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;iq;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; } } } 

Para cada tipo de gráfico, necesita algún tipo de modelo, que debe contener el estado actual de cada tipo. Esto probablemente significaría agregar su lista de int a una lista separada por género.

También necesitaría algún tipo de mecanismo que le permita recorrer cada algoritmo de ordenamiento e indicarle que avance al siguiente paso en su algoritmo, lo que le permitirá controlar cuándo se actualizará cada algoritmo de ordenación y, por lo tanto, cuándo se actualizará la pantalla.

Actualizado

Basado en un comentario de la OP, básicamente, he eliminado el algoritmo de ordenación como una interfaz separada. Cada algoritmo debería extenderse desde esta interfaz, pero proporciona los requisitos básicos para permitir que la interfaz de usuario represente la animación de clasificación.

Bellow es una implementación básica, mientras que está basado en Swing, si es necesario, no sería difícil lograr que funcione con AWT.

enter image description here

 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 listeners; private int[] values; private State state = State.Waiting; private List 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(); } } } 

Ejemplo utilizando la matriz fuente

 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 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 listeners; private int[] values; private State state = State.Waiting; private List 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(); } } } 

Ejemplo de clasificador de inserción

Este es un ejemplo del uso de un Thread como el motor de clasificación principal en lugar de un Timer swing

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