Zeichnen nach button-klick.

Status
Nicht offen für weitere Antworten.

Soahc

Aktives Mitglied
Hallo,

ich habe mir ein kleines Programm geschrieben um die Vektor-Matrix-Multiplikationen mit Rotationsmatritzen aus der Mathe-Vorlesung besser nachvollziehen zu können. Grundidee ist, dass ein Würfel aus 8 Punkten im Raum (Vektoren) besteht und wenn ich den ganzen Würfel um einen bestimmten Winkel rotieren lassen möchte, dann muss ich alle Vektoren mit einer bestimmten Rotationsmatrix multiplizieren. Das zu implementieren war jetzt auch nicht weiter wild, aber nun bin ich auf ein (warscheinlich sehr banals) Problem gestoßen und bekomme es irgendwie nicht hin. Also ich habe jetzt eine Art animations-Methode geschrieben, die den Würfel jeweils einmal 360° um x-, y- und die z-achse drehen lässt, wobei nach jedem grad rotation eine pause von 100milisekunden eingelegt wird. Rufe ich diese methode im Konstruktor meiner Fensterklasse auf, dann funktioniert auch alles prima... aber wenn ich sie im Action-Listener aufrufe, dann wird erstmal gar nichts gezeichnet... und erst dann wieder wenn die animations-methode komplett durchgelaufen ist. Ich schätze, ich muss dem Fenster dann noch irgendwie sagen, dass es auch jedes mal neugezeichnet werden soll, oder so? Hat da jemand einen Tip?!

Mein Code:

Java:
// Würfelfenster.java:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Wuefelfenster extends JFrame {
	
	public class Diagramm extends JPanel {
		   private Vektor3[] wuerfel = {
				   new Vektor3(0,0,0),
				   new Vektor3(100,0,0),
				   new Vektor3(0,100,0),
				   new Vektor3(100,100,0),
				   new Vektor3(0,0,100),
				   new Vektor3(100,0,100),
				   new Vektor3(0,100,100),
				   new Vektor3(100,100,100)};
		   
		   private Vektor3[] rotationswuerfel = new Vektor3[wuerfel.length];
		   
		   JLabel label = new JLabel("adsasd"); 
		   
		   public Diagramm(){
			   this.reset();
			   this.setBackground(Color.black);
			   label.setForeground(Color.white);
			   this.add(label);
		   }
		
		   private Vektor2 getKoordinatenursprung(){
			   return new Vektor2(this.getWidth()/2,this.getHeight()/2);
		   }
		   
		   private Vektor2 vec2toVec3(Vektor3 vec3){
			   Vektor2 ku = getKoordinatenursprung();
			   return new Vektor2(ku.getX() + vec3.getX() + (vec3.getZ()/ 2), ku.getY() - vec3.getY() - (vec3.getZ()/ 2));
		   }
		   
		   public void drawLine(Graphics g, Vektor2 a, Vektor2 b){
			   g.drawLine(a.getX(), a.getY(), b.getX(), b.getY());
		   }
		   
	       @Override
	        public void paintComponent(Graphics g) {
	        super.paintComponent(g);
			
	        wuerfelZeichnen(g);

	       }
	       
	       public void rotierenZ(int grad){
	    	   label.setText("Z-Rotation");
	    	   for (int i = 0; i<wuerfel.length;i++){
	    		   rotationswuerfel[i] = wuerfel[i].rotateZ(grad);
	    	   }
	       }
	       
	       public void reset(){
	    	   label.setText("");
	    	   for (int i = 0; i<wuerfel.length;i++){
	    		   rotationswuerfel[i] = wuerfel[i];
	    	   }
	    	   this.repaint();
	       }
	       
	       public void rotierenX(int grad){
	    	   label.setText("X-Rotation");
	    	   for (int i = 0; i<wuerfel.length;i++){
	    		   rotationswuerfel[i] = wuerfel[i].rotateX(grad);
	    	   }
	       }
	       
	       public void rotierenY(int grad){
	    	   label.setText("Y-Rotation");
	    	   for (int i = 0; i<wuerfel.length;i++){
	    		   rotationswuerfel[i] = wuerfel[i].rotateY(grad);
	    	   }
	       }
	       
	       public void rotierenXYZ(int grad){
	    	   label.setText("XYZ-Rotation");
	    	   for (int i = 0; i<wuerfel.length;i++){
	    		   rotationswuerfel[i] = wuerfel[i].rotateXYZ(grad);
	    	   }
	       }
	       
	       private void wuerfelZeichnen(Graphics g) {
	    	    g.setColor(Color.red);
	    	    drawLine(g,vec2toVec3(rotationswuerfel[0]),vec2toVec3(rotationswuerfel[1]));
		        drawLine(g,vec2toVec3(rotationswuerfel[0]),vec2toVec3(rotationswuerfel[2]));
		        drawLine(g,vec2toVec3(rotationswuerfel[1]),vec2toVec3(rotationswuerfel[3]));
		        drawLine(g,vec2toVec3(rotationswuerfel[2]),vec2toVec3(rotationswuerfel[3]));
		        g.setColor(Color.blue);
		        drawLine(g,vec2toVec3(rotationswuerfel[0]),vec2toVec3(rotationswuerfel[4]));
		        drawLine(g,vec2toVec3(rotationswuerfel[1]),vec2toVec3(rotationswuerfel[5]));
		        drawLine(g,vec2toVec3(rotationswuerfel[2]),vec2toVec3(rotationswuerfel[6]));
		        drawLine(g,vec2toVec3(rotationswuerfel[3]),vec2toVec3(rotationswuerfel[7]));
		        g.setColor(Color.green);
		        drawLine(g,vec2toVec3(rotationswuerfel[4]),vec2toVec3(rotationswuerfel[5]));
		        drawLine(g,vec2toVec3(rotationswuerfel[4]),vec2toVec3(rotationswuerfel[6]));
		        drawLine(g,vec2toVec3(rotationswuerfel[5]),vec2toVec3(rotationswuerfel[7]));
		        drawLine(g,vec2toVec3(rotationswuerfel[6]),vec2toVec3(rotationswuerfel[7]));
	       }
	}
	

	
	public static void main(String[] args) {
		new  Wuefelfenster();
	}
	
	
	private Diagramm diagramm = new Diagramm();	
	private JLabel label = new JLabel("");
	
	public  Wuefelfenster(){
		this.setBounds(50, 50, 500, 500);
		JButton button = new JButton("Rotieren...");
		label.setBackground(Color.black);
		this.setBackground(Color.black);
		
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				animation();	
			}
		});
		
		this.setLayout(new BorderLayout());
		this.add(diagramm,BorderLayout.CENTER);
		this.add(button,BorderLayout.SOUTH);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
		animation();
	}
	
	private void animation(){
		diagramm.reset();
		try 
		{ 
			for (int e=1;e<=4;e++){
				for (int i=0;i<=360;i++){
					if (e==1) diagramm.rotierenX(i);
					else if (e==2) diagramm.rotierenY(i);
					else if (e==3) diagramm.rotierenZ(i);
					else if (e==4) diagramm.rotierenXYZ(i);
					diagramm.repaint();
					Thread.currentThread().sleep(10); 
				}
			}
		} 
		catch (InterruptedException e){}
		diagramm.reset(); 
	}

}

Java:
//Vector3.java

public class Vektor3 {
	private int x;
	private int y;
	private int z;
	
	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}

	public int getZ() {
		return z;
	}

	public Vektor3(int x, int y, int z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
	private float winkelZuBogenmaß(int winkel){
		return (float)(winkel * Math.PI / 180);
	}
	
	public Vektor3 rotateZ(int winkel){
		float winkelmass = winkelZuBogenmaß(winkel); 
		
		int nx = (int)((Math.cos(winkelmass) * this.x) + (-Math.sin(winkelmass)*this.y));
		int ny = (int)((Math.sin(winkelmass) *this.x) + (Math.cos(winkelmass)*this.y));
		int nz = this.z;
		
		return new Vektor3(nx,ny,nz);
	}
	
	public Vektor3 rotateX(int winkel){
		float winkelmass = winkelZuBogenmaß(winkel); 
		
		int nx = this.x;
		int ny = (int)((Math.cos(winkelmass) * this.y) + (-Math.sin(winkelmass)*this.z));
		int nz = (int)((Math.sin(winkelmass) *this.y) + (Math.cos(winkelmass)*this.z));
		
		return new Vektor3(nx,ny,nz);
	}
	
	public Vektor3 rotateY(int winkel){
		float winkelmass = winkelZuBogenmaß(winkel); 
		
		int nx = (int)((Math.cos(winkelmass) * this.x) + (-Math.sin(winkelmass)*this.z));
		int ny = this.y;
		int nz = (int)((Math.sin(winkelmass) *this.x) + (Math.cos(winkelmass)*this.z));
		
		return new Vektor3(nx,ny,nz);
	}
	
	public Vektor3 rotateXYZ(int winkel){
		return rotateX(winkel).rotateY(winkel).rotateZ(winkel);
	}
}

Java:
//Vector2.java

public class Vektor2 {
	private int x,y;

	public int getX() {
		return x;
	}

	public int getY() {
		return y;
	}
	
	public Vektor2 (int x, int y){
		this.x = x;
		this.y = y;
	}
}
 
Zuletzt bearbeitet:

André Uhres

Top Contributor
wenn ich sie im Action-Listener aufrufe, dann wird erstmal gar nichts gezeichnet
Versuch's mal so:
Java:
...
    public static void main(final String[] args) {
        Runnable gui = new Runnable() {
            @Override
            public void run() {
                new Wuefelfenster();
            }
        };
        //GUI must start on EventDispatchThread:
        SwingUtilities.invokeLater(gui);
    }
...
    private Thread thread;
...
    private void animation() {
        if (thread == null || !thread.isAlive()) {
            thread = new Thread(new Runnable() {
                public void run() {
                    diagramm.reset();
                    try {
                        for (int e = 1; e <= 4; e++) {
                            for (int i = 0; i <= 360; i++) {
                                if (e == 1) {
                                    diagramm.rotierenX(i);
                                } else if (e == 2) {
                                    diagramm.rotierenY(i);
                                } else if (e == 3) {
                                    diagramm.rotierenZ(i);
                                } else if (e == 4) {
                                    diagramm.rotierenXYZ(i);
                                }
                                diagramm.repaint();
                                Thread.sleep(10);
                            }
                        }
                    } catch (InterruptedException e) {
                    }
                    diagramm.reset();
                }
            });
            thread.start();
        }
    }
}
 

Soahc

Aktives Mitglied
mh... Danke, funktioniert super... aber kannst Du vielleicht noch erklären, warum das nur so funktioniert?

gruß, Phill
 

icarus2

Top Contributor
Du deine Methode in einem eigenständigen Thread, der neben dem EventDispatchThread läuft aufrufen.

Was passiert nach dem Button-Klick ohne eigenen Thread:
Der Methodenaufruf kommt in die EventQueue (kannst du dir als Warteschlange für aufgerufene Methoden vorstellen). Wenn du dun das repaint() aufrufst, kommt dieses auch in diese Warteschleife. Da der Methodenaufruf, den du zu Beginn gemacht hast, jedoch noch in der Warteschlange ist, wird das repaint() noch nicht ausgeführt. Erst wenn deine Methode abgearbeitet ist, werden alle repaint()-Aufrufe abgearbeitet.

Wenn du dies nun in einem eigenen Thread erledigst, dann bleibt deine Methode nicht in der EventQueue stecken. Das repaint() wird somit zur richtigen Zeit ausgeführt.

Schau dir mal Nebenläufigkeit (Threads) an. Vielleicht auch noch kurz was mit dem EDT (EventDispatchThread). Wenn man das ganze wirklich im Detail verstehen will, dann ist es sehr kompliziert (ich verstehe auch nicht alles).

@André
Bitte korrigier mich, falls etwas nicht ganz der Wahrheit entspricht ;-)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Swing JPanel nur einmal nach mehreren Änderungen neu zeichnen AWT, Swing, JavaFX & SWT 1
P ScrollPane nach zeichnen dynamisch resize AWT, Swing, JavaFX & SWT 7
S Swing Bild auf jPanel nach Änderung von JComboBox zeichnen AWT, Swing, JavaFX & SWT 4
W Zeichnen in einem JFrame nach Resize AWT, Swing, JavaFX & SWT 7
frankred Swing Canvas nach "Window-resize" neu Zeichnen lassen wegen Anzeigefehler AWT, Swing, JavaFX & SWT 4
Sammay Swing JPanel nach dem einfügen neu zeichnen AWT, Swing, JavaFX & SWT 6
T JTable erst nach Änderung der Spaltenbreite neu zeichnen AWT, Swing, JavaFX & SWT 10
R Zeichnen nach Tastendruck AWT, Swing, JavaFX & SWT 3
G Linie nach Höhe einer Zahl zeichnen? AWT, Swing, JavaFX & SWT 3
G Applet Fenster nach Verdecken neu zeichnen? AWT, Swing, JavaFX & SWT 27
P Zeichnen nur von oben links nach unten rechts möglich AWT, Swing, JavaFX & SWT 4
M Mandelbrot mit BigDecimal erstellen und in der UI zeichnen, funktionierte nicht. AWT, Swing, JavaFX & SWT 1
H JavaFX Canvas neu zeichnen anstoßen AWT, Swing, JavaFX & SWT 34
H Transparent zeichnen mit drawImage in paintComponent Methode AWT, Swing, JavaFX & SWT 3
N JavaFX Unicode zeichnen in javafx Label verwenden AWT, Swing, JavaFX & SWT 2
G 2D-Grafik Grafik in zwei verschiedenen Fenstern gleichzeitig zeichnen AWT, Swing, JavaFX & SWT 9
S Event Handling Neu zeichnen nur wenn Berechnung fertig ist AWT, Swing, JavaFX & SWT 4
W JavaFX Ich kann keinen Kreis richtig zeichnen AWT, Swing, JavaFX & SWT 8
CptK Funktionsgraphen effizient zeichnen und nur Teile von JPanel erneuern AWT, Swing, JavaFX & SWT 2
G Dreieck aus Pixeln zeichnen AWT, Swing, JavaFX & SWT 8
N Mit KeyListener ein rechteck zeichnen AWT, Swing, JavaFX & SWT 9
B 2D-Grafik paintcomponent Probleme beim zeichnen AWT, Swing, JavaFX & SWT 10
Z Swing Graph zeichnen lassen AWT, Swing, JavaFX & SWT 16
O Kann kei neues Panel zum zeichnen aufrufen... AWT, Swing, JavaFX & SWT 4
L Swing zeichnen AWT, Swing, JavaFX & SWT 14
S GUI Kreuz zeichnen und Position ausgeben AWT, Swing, JavaFX & SWT 3
S GUI Kreis zeichnen AWT, Swing, JavaFX & SWT 13
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
L Swing Ein Rechteck in ein Grid Zeichnen AWT, Swing, JavaFX & SWT 5
L JavaFX Animation, erst zeichnen dann anzeigen AWT, Swing, JavaFX & SWT 4
K Mehrere Linien zeichnen AWT, Swing, JavaFX & SWT 8
E Transparent zeichnen AWT, Swing, JavaFX & SWT 2
S AWT Probleme beim Zeichnen AWT, Swing, JavaFX & SWT 3
T Tic Tac Toe - GUI Linien zeichnen AWT, Swing, JavaFX & SWT 14
C Applet Zeichnen über Button-Click AWT, Swing, JavaFX & SWT 13
Soloeco Graph zeichnen AWT, Swing, JavaFX & SWT 1
G Zeichnen Programm AWT, Swing, JavaFX & SWT 1
I Graph mit Swing zeichnen AWT, Swing, JavaFX & SWT 8
H Swing + Paint: Mehrere Objekte zeichnen lassen AWT, Swing, JavaFX & SWT 3
D Quadrat, Rechteck zeichnen AWT, Swing, JavaFX & SWT 3
K Probleme beim zeichnen mit paintComponent() AWT, Swing, JavaFX & SWT 1
JG12111989 mehrere Polyline-Objekte zeichnen AWT, Swing, JavaFX & SWT 3
A Swing JRadioButton zeichnen nicht AWT, Swing, JavaFX & SWT 4
J Swing Vertikales Zeichnen eines Strings mit Java2D AWT, Swing, JavaFX & SWT 1
7 JavaFX Problem beim Zeichnen eines Dreiecks in einem GUI AWT, Swing, JavaFX & SWT 6
P 2D-Grafik Bogen(Arc) zwischen zwei Punkten zeichnen AWT, Swing, JavaFX & SWT 2
F Java Swing Rechteck in JPanel zeichnen AWT, Swing, JavaFX & SWT 7
KilledByCheese Swing 2D JLabel Array Maze zeichnen AWT, Swing, JavaFX & SWT 2
S Parallele Linien zeichnen AWT, Swing, JavaFX & SWT 5
J Linien auf JPanel zeichnen AWT, Swing, JavaFX & SWT 3
P AWT Canvas freihändig zeichnen AWT, Swing, JavaFX & SWT 1
llabusch Linien in JPanel zeichnen AWT, Swing, JavaFX & SWT 6
S passende PaintComponent ? Zeichnen in TextArea mit Scrollpane ? AWT, Swing, JavaFX & SWT 2
I Applet BlueJ Applet - Bild mit if-Schleife zeichnen lassen AWT, Swing, JavaFX & SWT 16
L JavaFX JavafX Timelime zeichnen und schön stylen? AWT, Swing, JavaFX & SWT 2
I JFrame neu zeichnen, nicht überzeichnen! AWT, Swing, JavaFX & SWT 2
I Spielsteine zeichnen und entfernen AWT, Swing, JavaFX & SWT 3
H JavaFX Freezes beim Zeichnen mit Canvas AWT, Swing, JavaFX & SWT 3
H Swing BufferedImage zeichnen AWT, Swing, JavaFX & SWT 1
M JFreeChart neu zeichnen sich Wenn Jtable sich ändert AWT, Swing, JavaFX & SWT 5
S 2D-Grafik MouseDragged Linien zeichnen AWT, Swing, JavaFX & SWT 4
M Zeichnen ohne vorherige Linien zu löschen AWT, Swing, JavaFX & SWT 2
T Problem beim Zeichnen von Rechteck AWT, Swing, JavaFX & SWT 3
T Swing / Kreis zeichnen AWT, Swing, JavaFX & SWT 2
I Text zur Linie zeichnen AWT, Swing, JavaFX & SWT 1
I Pfeil zeichnen am Ende einer Linie AWT, Swing, JavaFX & SWT 1
D 2D-Grafik Inhalt eines Graphics in anderes Graphics zeichnen.... AWT, Swing, JavaFX & SWT 3
F Zeichnen des Button AWT, Swing, JavaFX & SWT 4
B Zeichnen mit paintComponent? Oder anders? AWT, Swing, JavaFX & SWT 15
C Swing Aus verschiedenen Klassen zeichnen. AWT, Swing, JavaFX & SWT 2
C Swing BufferedImage zeichnen und JLabels setzen. AWT, Swing, JavaFX & SWT 17
M Kein Zeichnen der Figuren auf JPanel AWT, Swing, JavaFX & SWT 4
J JButton neu zeichnen lassen AWT, Swing, JavaFX & SWT 9
S Quadrat auf Frame zeichnen AWT, Swing, JavaFX & SWT 2
P Image oder Icon auf Tooltip zeichnen AWT, Swing, JavaFX & SWT 4
C Graphics Objekt in Zeitschleife zeichnen AWT, Swing, JavaFX & SWT 4
X Swing JPanel mehrere Ebenen zeichnen AWT, Swing, JavaFX & SWT 13
G Zeichnen auf eine schwergewichtige Komponente? AWT, Swing, JavaFX & SWT 0
G Mehrere Strings um Kreis zeichnen und positionieren AWT, Swing, JavaFX & SWT 0
P SWT Nebula Gallery - Bildbereiche zeichnen AWT, Swing, JavaFX & SWT 3
A Swing Paint mit Button Clear den Hintergrund säubern um wieder zeichnen zu können AWT, Swing, JavaFX & SWT 2
A 2D-Grafik Zeichnen einer sich bewegenden Box mit BufferStrategy zieht Spur AWT, Swing, JavaFX & SWT 2
T AWT Bild laden und transparent zeichnen AWT, Swing, JavaFX & SWT 2
Helgon Swing Mit Swing zeichnen / NetBeans GUI AWT, Swing, JavaFX & SWT 11
M JLabel über JButtons zeichnen AWT, Swing, JavaFX & SWT 4
J JApplet und Zeichnen AWT, Swing, JavaFX & SWT 8
P 2D-Grafik NPE beim Zeichnen auf Graphics g AWT, Swing, JavaFX & SWT 8
4 Swing Graphen selber zeichnen AWT, Swing, JavaFX & SWT 2
T Über mehrere Panel zeichnen AWT, Swing, JavaFX & SWT 2
T Zeichnen von getSubimage funktioniert nicht AWT, Swing, JavaFX & SWT 7
M Bilder zeichnen, NullPointer Exception AWT, Swing, JavaFX & SWT 3
N JPanel neu zeichnen AWT, Swing, JavaFX & SWT 10
D Zeichnen eines Barplots AWT, Swing, JavaFX & SWT 2
bluerob Problem beim Image zeichnen via andere Klasse AWT, Swing, JavaFX & SWT 7
M Swing JFrame in einem Panel zeichnen AWT, Swing, JavaFX & SWT 3
M Suche Javabibliothek zum Zeichnen mathematischer Funktionen AWT, Swing, JavaFX & SWT 11
M Swing Warum öffnen sich beim Zeichnen mit Swing plötzlich zwei Fenster? AWT, Swing, JavaFX & SWT 5
M Swing In GUI-Builder-JFrame mit Menü Schreiben und Zeichnen AWT, Swing, JavaFX & SWT 4
N 2D-Grafik 2 Probleme beim zeichnen AWT, Swing, JavaFX & SWT 18
C Funktionen zeichnen AWT, Swing, JavaFX & SWT 16

Ähnliche Java Themen


Oben