# BubbleSort mit Hilfe einer Balkengrafik visualisieren



## Guest (26. Jun 2007)

Hallo,

ich möchte den BubbleSort Algorithmus mit Hilfe einer Balkengrafik darstellen.
Die Höhe der Balken stellt die Größe einer Zahl dar.
Nach jedem Vertauschvorgang soll nun die Balkengrafik neu gezeichnet werden.
Habe bis jetzt folgenden Code dazu, mit dem ich aber alles andere als zufrieden bin.
Denn:

- ich kann die Methode repaint() nicht aus der Klasse BubbleSort aufrufen.
- irgendwie unsauber programmiert

Wer kann mir helfen, so dass ich auch die Methode repaint() aus der Klasse BubbleSort aufrufen kann.
Und dem Algorithmus ohne viel Aufwand weitere Sortieralgorithmen hinzufügen kann.

Hier erstmal mein Code:

```
package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.image.ImageObserver;
import java.text.AttributedCharacterIterator;

import javax.swing.JComponent;

public class MeinCanvas extends JComponent {
    
    Graphics mG = getGraphics();
    MeinRandom random = new MeinRandom();
    BubbleSort verbBubble = new BubbleSort();
    QuickSort verbQuick = new QuickSort();
    
    int[] array = new int[100];
    int[] array1 = new int[100];
    
    
    protected int
            breite,
            hoehe;
    
    public MeinCanvas(int breite,int hoehe) {
        this.hoehe = hoehe;
        this.breite = breite;
        
        
        // fülle arrays mit Zufallszahlen von 1-100
        for (int i = 0; i < array.length; i++) {
            
            array[i] = random.nextInt(1, 100);
        }
        array1 = array.clone();
        sortieren();
    }
    
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(breite,hoehe);
    }
    
    @Override
    public Dimension getSize(Dimension arg0) {
        return new Dimension(breite,hoehe);
    }
    
    @Override
    public Dimension getMinimumSize() {
        return getPreferredSize();
    }

    
    
    @Override
    public void paint(Graphics g) {
        //Farbe vom rectangle
        g.setColor(Color.white);
        g.fillRect(0,0,breite,hoehe);  //wie weit des rectangle mit der farbe (weiß) gefüllt werden soll
        
        
        g.setColor(Color.black);
        g.setFont(new Font("SansSerif",Font.BOLD,12));
        //Überschrift
        //g.drawString("Zeichenfläche",2,23);
        
        int abstandLinks = 0;
        
        //zeichne Balken zu den Zufallszahlen im array
        //Balken ,hoehe-... und letzte zahl müssen immer gleich sein!
        for (int i = 0; i < array.length; i++) {
            
            g.fillRect(abstandLinks, hoehe-array[i], 3, array[i]);
            abstandLinks = abstandLinks +5;
            
        }
               
        
        //int liObX = 160;
        //int liObY = 0;
        //int reUnX = 6;
        //int reUnY = hoehe;
        //g.drawRect(liObX, liObY, reUnX, reUnY);
        
        g.setColor(Color.black);
        g.draw3DRect(0,0,breite-1,hoehe-1,true); // schwarzer rand vom weißen feld
        
        g.setColor(Color.black);
        g.draw3DRect(300,400,150,150,true);
        
        
        
        /* 
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }
        */
        sortieren();
    }
    
    public void sortieren() {
        
        verbBubble.bubbleSort(array);
        repaint();
        
    }
    
    
}
```


```
package gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GrafikFenster extends JFrame {
    
    protected JButton
            btStart = new JButton("start"), // Button "Start"
            btStop = new JButton("stop");   // Button "Stop"
    
    //	 Konstruktor
    public GrafikFenster() throws HeadlessException {
        this("Hauptfenster");
    }
    
    
    //	 Konstruktor
    public GrafikFenster(String arg0) throws HeadlessException {
        super(arg0);
        this.setLocation(200, 200); //platzierung vom fenster
        this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); // Schließmechanismus
        
        Container cpane = this.getContentPane();
        GridBagLayout grid = new GridBagLayout();
        cpane.setLayout(grid);
        
        // ---------------------------------------------
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
        buttonPanel.add(btStart);
        buttonPanel.add(btStop);
        buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
        
        addComponent(cpane,buttonPanel,0,10,GridBagConstraints.REMAINDER,1);
        
        // ---------------------------------------------
        JPanel drawPanel = new JPanel();
        //System.out.println("OK4");
        MeinCanvas canvas = new MeinCanvas(505,100); // Breite / Hoehe
        drawPanel.add(canvas);
        drawPanel.setBorder(BorderFactory.createLineBorder(Color.black));
        
        addComponent(cpane,drawPanel,10,200,GridBagConstraints.REMAINDER,1);
        
        //canvas.repaint();
        
        // alles schön packen
        this.pack();
    }
    

    
    //	 Hilfsmethoden zum Hinzufuegen von Komponenten zu GridBagLayout
    protected void addComponent(Container container,
            Component component, int gridx, int gridy,
            int gridwidth, int gridheight) {
        addComponent(container,component,gridx,gridy,
                gridwidth,gridheight,GridBagConstraints.WEST);
    }
    
    protected void addComponent(Container container,
            Component component, int gridx, int gridy,
            int gridwidth, int gridheight,
            int anchor) {
        GridBagConstraints constr = new GridBagConstraints();
        constr.gridx = gridx;
        constr.gridy = gridy;
        constr.gridwidth = gridwidth;
        constr.gridheight = gridheight;
        constr.fill = GridBagConstraints.NONE;
        constr.anchor = anchor;
        
        container.add(component, constr);
    }
    
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        GrafikFenster fenster = new GrafikFenster();
        fenster.setVisible(true);
    }
    
}
```


```
package gui;

import java.security.spec.MGF1ParameterSpec;

//import javax.swing.RepaintManager;

public class BubbleSort {
    
    public int y = -1;
    //MeinCanvas can = new MeinCanvas(400,100);
    public int[] bubbleSort(int array[])
    
    
// pre: array is full, all elements are valid integers (not null)
// post: array is sorted in ascending order (lowest to highest)
    {
        boolean swappedOnPrevRun = true;
        while(swappedOnPrevRun) {
            swappedOnPrevRun = false;  // this variable keeps track of whether to continue sorting or exit
            
            
            for( ; y < array.length -1; y++)	// loop through every element in the array,
                // except for the last one
                
            {
                
                y++;
                if (y > 98) {
                    y = 0;
                }
                if(array[y] > array[y + 1])		// if current element is greater than the next
                {
                    // swap the two elements
                    swappedOnPrevRun = true;	// we don't want the loop to end just yet, we're not done
                    int temp = array[y];		// store element i in a temporary variable
                    array[y] = array[y + 1];	// set element i+1 to where i used to be
                    array[y + 1] = temp;		// release the old i from temp into i+1 slot
                    
                    return array;
                }
                
                try {
                    Thread.sleep(1);
                    //can.sortieren();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
                //can.sortieren();
                break;
                
            }
        //break;
        }
        return array;
    }
    
}
```


----------



## Marco13 (26. Jun 2007)

Hast du dir schonmal sowas wie
http://java.sun.com/applets/jdk/1.4/demo/applets/SortDemo/example1.html
angesehen? Ein bißchen "Inspiration holen"? :wink:


----------



## Guest (26. Jun 2007)

jaa danke, aber hilft mir im moment noch nicht weiter!

Wie kann ich denn verdammt nochmal aus der klasse BubbleSort die repaint() methode aufrufen?
Ich bekomm das nicht hin!


----------



## Marco13 (26. Jun 2007)

```
BubbleSort verbBubble = null;
    QuickSort verbQuick = new QuickSort();
   
...
    public MeinCanvas(int breite,int hoehe) {
        this.hoehe = hoehe;
        this.breite = breite; 
        verbBubble  = new BubbleSort(this); //--------------------------- Canvas übergeben

public class BubbleSort {

    private MeinCanvas meinCanvas = null;
   
    public BubbleSort(MeinCanvas meinCanvas)
    {
        this.meinCanvas=meinCanvas;  //--------------------------- Canvas speichern
    }



    public int[] bubbleSort(int array[])
    {
         ...
         meinCanvas.repaint();  //--------------------------- Canvas repainten
...
```

Es gibt aber noch andere (evtl. auch "bessere") Alternativen (Model-View-Controller-Pattern oder so...)


----------



## Guest (26. Jun 2007)

@Marco13

super genau das brauchte ich, jetzt geht es schonmal mit dem aufruf von repaint() aus bubblesort.


----------



## Guest (26. Jun 2007)

wie bekomme ich denn den methodenaufruf sortieren() aus der paint() methode raus?

Ich möchte, dass wenn er die paint methode abgearbeitet hat wieder in den BubbleSort Algorithmus reinspringt!?


----------



## Guest (27. Jun 2007)

PROBLEM:

er aktualisiert die ansicht nur aufgrund des returns im Bubblesort (return array).
das ganze funktioniert im moment auch ohne den repaint aufruf aus bubblesort.
Ich will aber das es mit repaint funktioniert?
Also ich bin ratlos...????


----------



## Marco13 (27. Jun 2007)

Ich nehme an, dass du bubblesort startest, wenn z.B. ein Button geklickt wurde, und das ganze im Event-Dispatch-Thread gemacht wurde, und du es eigentlich in einem eigenen Thread machen müßtest (gäääähhhn...) aber mangels aussagekräftigem Code ist das natürlich nur geraten.


----------



## Guest (27. Jun 2007)

ja es sollte ursprünglich so werden, dass wenn ich den button drücke bubblesort startet. Aber der button ist im moment noch ohne funktion!
Das sind bis jetzt alle klassen zum programm!  :shock:
Was vermisst du denn?

Ja genau es sollte im prinzip alles übern thread laufen.


----------



## Marco13 (27. Jun 2007)

Wahrg - hab grad nochmal drübergeschaut: Die sortieren-Funktion in der paint-Methode aufzurufen ist gröbster Unfug - aber das war ja auch deine Frage :wink: Die sortieren-Funktion wird ja auch im Konstruktor schonmal aufgerufen. EIN Aufruf sollte ja eigentlich reichen. Allerdings sollte der auch nicht im Konstruktor des Canvas gemacht werden. (Dass die Sortierer im Canvas liegen ist auch ziemlich häßlich, aber ... du wolltest dir ja keine Inspiration von dem Link holen, den ich gepostet hatte (machmal habe ich den Eindruck, die Leute glauben, man würde irgendwelche Antworten nicht schreiben, um jemandem zu helfen, sondern weil einem so schrecklich langweilig ist....)). 


Also: Rufe an einer geeigeneten Stelle

```
Thread t = new Thread(new Runnable()
{
    public void run()
    {
        sortierer.sortieren();
    }
});
t.start();
```
auf. Welches die "geeignete Stelle" ist, darfst du selbst herausfinden. Im Konstruktor würde es vmtl. schon gehen, aber schön wäre das nicht.


----------

