# JPanel zeichnen, dynamische Figuren



## Skandel (4. Mrz 2014)

Hallo,

die Aufgabe ist wie folgt. Wir sollen anhand von Panels mehrere Objekte dynamisch zeichnen. Hier das Beispiel jetzt einen Schmetterling, der beim ziehen des Schiebereglers größer und kleiner wird. Der Schmetterling ist nicht das Problem, die Formeln haben wir. Die Schieberegler sind auch implementiert und er verändert auch die Schmetterlingsgröße...ABER: er malt den Schmetterling sehr oft übereinander (eig sollte er den repainten) und er malt das irgendwie nicht in das dafür vorgesehene Panel (weil da der Hintergrund weiß sein sollte). Außerdem gibt der die Schieberegler nach der ersten Betätigung nochmal in den rechten Panel aus, was ich absolut nicht nachvollziehen kann. (Ja, bisher ist das schlecht gelöst, eig sollte es mit INterface und drawFunctions sein, aber wir wollten überhaupt erstmal etwas haben.

tl;dr version:
Problem1: Schmetterling zu oft gezeichnet
Problem2: Schmetterling nicht im "ZeichenPanel"
Problem3: ZeichenPanel existiert scheinbar nicht (kein weißer Hintergrund)
Problem4: die Sliders werden kopiert auf das rechte Panel..WARUM?

Main Methode:


```
package project;

public class Mantest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new SliderFrame();
	}
}
```

FRAME Klasse 


```
package project;

import java.awt.BorderLayout;
import javax.swing.JFrame;
public class SliderFrame extends JFrame {
	public SliderFrame() {
		this.setSize(400, 400);
		this.setLayout(new BorderLayout());
		this.add(new OverPanel(),BorderLayout.CENTER);
		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}	
}
```

Hier der MasterPanel, der zwei innere Klassen hat, welche 2 Panels darstellen die rechts (SLider) und rest (Center, zeichenpanel) darstellen sollen.


```
package project;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;



public class OverPanel extends JPanel {
	JSlider rSlider = new JSlider(0, 255, 100);
	JSlider bSlider = new JSlider(0, 255, 100);
	JSlider gSlider = new JSlider(0, 255, 100);
	ZeichenPanel test = new ZeichenPanel();
	static int[] param = new int[3];
	//Butterfly butterfly = new Butterfly();

	public OverPanel() {
		this.setLayout(new BorderLayout());
		this.add(new OverPanel$SliderPanel(), BorderLayout.WEST);
		this.add(test, BorderLayout.CENTER);
	}

	// Klasse zum erzeugen der Sliders / Innere Klasse
	public class OverPanel$SliderPanel extends JPanel {

		public OverPanel$SliderPanel() {
			this.setLayout(new GridLayout(3, 1));
			initSliders();
		}

		// Erzeugt die Slider für SliderPanel
		public void initSliders() {

			this.add(rSlider);
			this.add(bSlider);
			this.add(gSlider);
			rSlider.addChangeListener(new SliderListener());
			bSlider.addChangeListener(new SliderListener());
			gSlider.addChangeListener(new SliderListener());
		}
		
		
		}
		private class SliderListener implements ChangeListener {

			public void stateChanged(ChangeEvent arg0) {
				param[0] = rSlider.getValue();
				param[1] = bSlider.getValue();
				param[2] = gSlider.getValue();
				
				
				test.butterfly(param[0]);
				
				//test.setBackground(new Color(param[0],param[1],param[2]));
			
				
			}

		}
	// Erzeugt innere Klasse zum zeichnen
	public class ZeichenPanel extends JPanel {
		
		private int get=1;
		Graphics g;

		public ZeichenPanel() {
				
			
			this.setBackground(new Color(255,255,255));
			
		}
		
		
		public void paintComponent(Graphics g) {
			super.paintComponents(g);
			
			double x,y;
			g.setColor(Color.blue);
			double t = (-20)*Math.PI;
			for (double i = t; i<=(-1)*t ;i+=0.001){
			x = get*(Math.sin(i)*(Math.pow(Math.E,Math.cos(i))-2*Math.cos(4*i)-Math.pow(Math.sin(i/12),5)) /10 +0.5);
			y = get*(Math.cos(i)*(Math.pow(Math.E,Math.cos(i))-2*Math.cos(4*i)-Math.pow(Math.sin(i/12),5)) /10 +0.5);
			g.drawLine((int)x, (int)y, (int)x+1, (int)y+1);
			//test.repaint();
			}
		}
		
		public void butterfly(int a){
			
			this.get = a;
			repaint();

		
	}
	}
}
```

atm sieht die AUsgabe ungefähr so aus:

Image einbinden geht irgendwie nicht, daher hier der Link:

butterfly.JPG - directupload.net


----------



## Flown (9. Mrz 2014)

Ahja das ist nicht sehr gut gelöst.

Hier meine Verbesserungsvorschläge:

* Class$innerclass sollte vermieden werden, da die JVM selbst die Instanzen der inneren Klassen so benennt
* Von Klassen nur dann ableiten, wenn man explizit ihr Verhalten ändern will, dass heißt bei dir dass du JFrame und die JPanel nicht ableiten sollst sondern einfach nur benutzen (außer das ZeichenPanel, das hast du richtig gemacht)


Der Fehler liegt bei:
[JAVA=81]
    public void paintComponent(Graphics g) {
        super.paintComponents(g);
[/code]

Es sollte aber heißen (ohne das 's' am Schluss):
[JAVA=82]
        super.paintComponent(g);
[/code]


----------

