Grafische Sortierung auf Panel

Justin Bailey

Grünschnabel
Hi an alle Mitglieder des Tutorial Forums,

Ich möchte ein Programm schreiben das mir die Funktion des Bubblesort Algorithmus grafisch darstellt, das ganze sollte mit paint auf einem panel geschehen.

Ich habe nun zb ein Array mit Zufallszahlen von 0-100 gefüllt, ich hätte gerne diese zahlen als Punkte auf dem Panel, wobei Wert und Stelle die x und y Koordinaten sein sollen, so das am Ende eine Diagonale auf dem panel entsteht.
so wie hier:
http://homepages.dcc.ufmg.br/~dorgival/applets/SortingPoints/SortingPoints.html

mein Problem: Ich weiss nicht wie ich der paint Methode die einzelnen Arrayelemente zuweise bzw ihren aktuellen und den neuen Wert, also im Prinzip wann und wie rufe ich die paint Methode erneut auf. Ich bin noch Anfänger in Sachen java2d;
 
In deiner Bubble-Sort - Schleife. Dort machst du zum Schluss eine neue Schleife in der du das Array durchgehst. Die Koordinaten, die du so erhällst zeichnest du am besten mit paintimmediately(). Aber nicht vergesse, vor dem neuzeichnen die Zeichenfläche wieder zu löschen
 
Java:
public class DrawX extends JPanel {
	int x1,y1;
	
	public void paint(Graphics g){
		Graphics2D g2 = (Graphics2D) g;
		g2.setStroke(new BasicStroke(1));
		for(int i=0;i<100;i++){
			
			x1 = DrawSort.a[i];
			g2.fillOval((x1-5)/2,(i*5)/2,10,10);
                }
        }
}
---------------------------------------------------------------------------------------

Java:
public class DrawSort{
	static int[] a = new int[100];
	static JFrame Fr = new JFrame();
	Graphics g;
	
	
//Konstruktor
	public DrawSort(){
		
		a = Array.Arrai(a); //zufallszahlen in array schreiben
		Rahmen();			// frame
		sort(a);			// sortieren
	}
	
//Frame
	public void Rahmen(){
		
		Fr.setSize(new Dimension(550, 350));
		Fr.setDefaultCloseOperation(Fr.EXIT_ON_CLOSE);
		Fr.add(new DrawX());
		Fr.setVisible(true);
		
	}

//bubble sort
		public static void sort(int a[]) {
			    int cnt = 0;
			    int n = a.length;
			    int temp; 

			    for (int i=0; i < n-1; i=i+1)          
			      for (int j=n-1; j > i; j=j-1)        
			        if (a[j-1] > a[j])                 
			         {
			            temp = a[j-1];                
			            a[j-1] = a[j];                
			            a[j] = temp; 
			        
			         }
                           }
		  
//main	
	public static void main(String[] args){
		DrawSort Dr = new DrawSort();
	}
}
 
Ich war mal so frei und hab Code-Tags eingefügt. Ich möchte dich bitten, dies das nächste mal auch zu tun.

MFG

Sascha
 
Hallo Justin,

deine Sortierungsmethode braucht vielleicht nur einige Millisekunden für den kompletten Durchlauf, deswegen siehst du auf dem Panel nur das Ergebnis. Damit du den ganzen Sortierungsprozess beobachten kannst, musst du nach jeder Sortierungsoperation die repaint() Methode aufrufen und den aktuellen Thread für eine Weile "schlafen legen", damit du die Veränderungen an dem Panel auch wahrnehmen kannst.

Und so könnte es aussehen:
Java:
/**
 * The Class SortPanel.
 */
public class SortPanel extends JFrame {
    private JPanel panel;
    private int[] a = new int[100];

    /**
     * Instantiates a new sort panel.
     */
    public SortPanel() {
        super("SortPanel");
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        for (int i = 0; i < a.length; i++) {
            a[i] = (int) (Math.random() * 500);
        }
        panel = new JPanel() {
            public void paint(Graphics g) {
                for (int i = 0; i < a.length; i++) {
                    int x1 = a[i];
                    g.fillOval((x1 - 5) / 2, (i * 5) / 2, 10, 10);
                }
            }
        };
        getContentPane().add(panel, BorderLayout.CENTER);
        // starte die Sortierungs-Methode in einem extra Thread
        // damit das UI nicht "einfriert"
        new Thread(new Runnable() {
            public void run() {
                sort();
            }
        }).start();
    }

    public void sort() {
        int n = a.length;
        for (int i = 0; i < n - 1; i = i + 1) {
            for (int j = n - 1; j > i; j = j - 1) {
                if (a[j - 1] > a[j]) {
                    int temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;
                    // ein Aufruf von UI Methoden von einem Non-UI Thread aus
                    // sollte stets über invokeLater() Methode erfolgen
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            repaint();
                        }
                    });
                    // hier legt sich der aktuelle Thread schlafen
                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException e) {
                    }
                }
            }
        }
    }

    /**
     * The main method.
     *
     * @param args the arguments
     */
    public static void main(String[] args) {
        final JFrame frame = new SortPanel();
        final Dimension frameSize = new Dimension(600, 400);
        frame.setSize(frameSize);
        final Dimension screenSize = Toolkit.getDefaultToolkit()
                .getScreenSize();
        final int frameX = (screenSize.width - frameSize.width) / 2;
        final int frameY = (screenSize.height - frameSize.height) / 2;
        frame.setLocation(frameX, frameY);
        frame.setVisible(true);
    }
}

Grüße
Vincent
 
Also erstmal herzlichen Dank für den code.
Das mit den Threads habe ich Verstanden.
Könntest du mir wohl noch erklären, wie und wo in deinem Code genau das JPanel mit dem JFrame zusammenspielt?
 
Hallo Justin,

in der Zeile
Java:
getContentPane().add(panel, BorderLayout.CENTER);
wird das Panel in den Frame eingefügt.

Grüße
Vincent
 
Zurück