Graphics2D - zeichnen und undo

mercur118

Grünschnabel
Moinsens zusammen!

Ich soll eine kleine Visualisierung von Graphen schreiben. Ich bin soweit in der Lage, Graphen und Knoten mittels Graphics2D in ein JPanel zu zeichnen.
Nun ist die Aufgabe, einen Graphen schrittweise zu zeichnen, es soll also nach jeder Linie eine Pause sein. Ich hab bisher so angefangen, wie oben und mache jeweils nach einer While schleife eine Pause.

Mein Problem kommt jetzt beim zuirück gehen. Man soll nämlich mit einem Klick einfach einen Schritt zurück gehen können. Es soll also sowas wie UNDO implementiert werden. Ich habe dazu das ausgangs JPanel und das schonmal gezeichnet wurde (Dieses soll nicht geändert werden) nochmals mit einem JPanel, welches durchsichtig ist, überlagert und zeichne die neuen Kanten in anderer Farbe in dieses Panel. Man soll nämlich den darunterliegenden Graphen sehen können.

Meine eigentliche Frage ist nun, wie ich es schaffen kann, in Graphics2D das zuletzt gezeichnete Objekt verwerfen kann. Ich habe es versucht, immer den ganzen Kontext mit clear() zu löschen und dann einfach neu zu zeichnen, aber dann ist das JPanel nicht mehr durchsichtig. ..

Ich wäre für einen kleinen Hinweis zum weiteren Vorgehen sehr Dankbar
Gruß
mercur118
 
Ok, ich hab jetzt mal den Code der Klasse gepostet, der das transparente Panel zeichnen soll. Vielleicht hilft das irgendwem.

Code:
package jebt.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;

import javax.swing.JLabel;
import javax.swing.JPanel;

import jebt.AlgorithmsException;
import jebt.Edge;
import jebt.EdgeQueue;

public class AnimationPainter extends JPanel implements Runnable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5716539441973013821L;

	AnimationScreen top;

	Graphics2D g2;
	Graphics2D g2Back;

	Edge actualEdge;
	
	EdgeQueue painted = new EdgeQueue();

	boolean stop = false;
	boolean runs = false;
	boolean pause = false;

	int max;

	int index = 0;

	int DELAY;
	
	// *** Ab hier Test ***
	
	// Array fuer Lines
	
	ArrayList lines = new ArrayList();
	ArrayList status = new ArrayList();
	ArrayList triangle = new ArrayList();
	
	public AnimationPainter(AnimationScreen scr) {
		this.setBackground(Color.WHITE);
		this.setOpaque(false);
		this.setPreferredSize(new Dimension(1000,1000));
		this.add(new JLabel("Hallo"));
		top = scr;
		max = top.queue.size();
		DELAY = 500;
		
		setPositions();
		
	}
	
	

	public void run() {
		
		g2 = (Graphics2D)this.getGraphics();
		g2Back = (Graphics2D)g2.create();
		
		runs = true;
		//g2 = (Graphics2D)(top.getGraphics()).create();
		
		System.out.println("ArrayList Größe: " + lines.size());
		
		while(!stop && index < lines.size()){
			// Hier die Animation pausieren
			while (pause) {
				try {
					Thread.sleep(250);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			
			paintComponent(g2);
			
			index++;
		}
		
		
		
		
		/

	}
	
	public void stepForward(){
		int tmp = DELAY;
		DELAY = 0;
//		 aktuelle Kante auslesen
		this.repaint();
		index++;
		DELAY = tmp;
	}
	
	public void stopAnim(){
		// Die Animation stoppen und den Ausgangszustand wiederherstellen
		index = 0;
		//max = top.queue.size();
		//top.queue.reset();
	}
	
	public void stepBackward(){
//		 aktuelle Kante auslesen
		int tmp = DELAY;
		DELAY = 0;
		index -= 2;
		g2.dispose();
		g2 = (Graphics2D)g2Back.create();
		this.repaint();
		//top.paintComponent(top.getGraphics());
		//paintComponent(g2);
		index++;
		DELAY = tmp;
	}

	
	
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		if(runs){
			paintThaFuck(index);
		}
	}
	
	public void paintThaFuck(int ind) {
		//g2.setBackground(Color.WHITE);
		//g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF );
		
		//g2.setBackground(Color.WHITE);
		//g2.clearRect(0,0,1000,1000);
		//top.paintComponent(g2);
		
		// Zuerstmal den alten Kram zeichnen, und vor dem letzen pausieren
		
		if(ProgVars.antialising){
			g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON );
		}
		
		int prt = 0;
		
		// Die alten Kanten Zeichnen
		while(prt < ind){
		
			// Den aktuellen Status holen
			Line2D.Double line = (Line2D.Double)lines.get(prt);
			
			int n = ((Integer)status.get(prt)).intValue();
			
			Color col = null;
			if (n == 1) {
				col = Color.GREEN;
			} else {

				if (n == 2) {
					col = Color.PINK;
				} else {
					col = Color.CYAN;
				}
			}
			
			g2.setColor(col);
			g2.draw(line);
			g2.fillPolygon((Polygon)triangle.get(prt));
			
			prt++;
		}
		
		// Dann warten
		
		try {
			Thread.sleep(DELAY);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		// Dann die neue Kante zeichnen
		
//		 Den aktuellen Status holen
		Line2D.Double line = (Line2D.Double)lines.get(prt);
		
		int n = ((Integer)status.get(prt)).intValue();
		
		Color col = null;
		if (n == 1) {
			col = Color.GREEN;
		} else {

			if (n == 2) {
				col = Color.PINK;
			} else {
				col = Color.CYAN;
			}
		}
		
		g2.setColor(col);
		g2.draw(line);
		g2.fillPolygon((Polygon)triangle.get(prt));
		this.revalidate();
		
		
	}
	
	public void setPositions(){
//		 Das Zeichenbrett erstellen
		
		lines.clear();
		status.clear();
		triangle.clear();
		
		while(max > 0){
			
			//**************************************************************
			// Jetzt erstmal Kanten nach neuem Verfahren Zeichnen

			// aktuelle Kante auslesen
			actualEdge = top.queue.get();
			

			
			Node node1 = (Node) top.nodes.get(actualEdge.getFrom() - 1);
			//node1.setPosition(node1.getX(),node1.getY() + 5);
			Node node2 = (Node) top.nodes.get(actualEdge.getTo() - 1);
			//node2.setPosition(node2.getX(),node2.getY() + 5);
			//Node node3 = (Node) top.nodes.get(actualEdge.getNode() - 1);
			
			Point2D node1P = new Point(node1.getX() + 8,node1.getY() - 5);
			Point2D node2P = new Point(node2.getX() + 8,node2.getY() - 5);
			
			
			//******************
			
//			 Die Offsets fuer den Abstand vom Mittelpunkt des Kreises berechnen
			// Abstand Linie - Startpunkt
			Point2D offN1 = top.calcOffset(node1P, node2P);
			// Abstand Linie - Endpunkt
			Point2D offN2 = top.calcOffset(node2P, node1P);

			// Punkt an dem der Endknoten der Linie liegt
			Point2D point = new Point();
			point.setLocation(node2P.getX() + offN2.getX(), node2P.getY()
					+ offN2.getY());

			// Abstand Pfeilspitze und Pfeil Anfang
			Point2D offTri = top.calcOffset(point, node1.getPoint2D());
			// System.out.println("Offset: " + offTri.getX() + "," + offTri.getY());
			Point2D point2 = new Point();
			point2.setLocation(point.getX() + offTri.getX(), point.getY()
					+ offTri.getY());
			
			
			//******************
			
			//Line2D.Double line = new Line2D.Double(node1.getX() + 8,node1.getY() - 5,node2.getX() + 8,node2.getY() - 5);
			Line2D.Double line = new Line2D.Double(node1P.getX() + (int) offN1.getX(), node1P.getY()
					+ (int) offN1.getY(), node2P.getX() + (int) offN2.getX(), node2P
					.getY()
					+ (int) offN2.getY());

			
			System.out.println("Point X: ("+offN1.getX() + "," + offN1.getY() + ")" );
			
			lines.add(line);
			try {
				Integer state = new Integer(actualEdge.getStatus());
				status.add(state);
			} catch (AlgorithmsException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			// Pfeilspitze hinzufuegen
			
			
			//point.add(node3.getPoint2D());
			triangle.add(makeTriangle(point,point2,offTri.getY()));
			
			max--;
			
			//************************************************************
			
		}
		
		max = top.queue.size();
		top.queue.reset();
	}
	
	private Polygon makeTriangle(Point2D spitze, Point2D ende, double richtung){
		Polygon p = new Polygon();
		
//		 ersten Knoten setzen
		p.addPoint((int)spitze.getX(),(int)spitze.getY());
		
		double radius = 10.0;
		double alphaX = Math.asin((spitze.getX() - ende.getX()) / radius);
		
		
		
		// die anderen beiden dinger berechnen
		
		double posX, posY;
		posX = Math.sin(alphaX + Math.toRadians(90.0)) * radius;
		posY = Math.cos(alphaX + Math.toRadians(90.0)) * radius;
		
		if(richtung > 0.0){
			p.addPoint((int)(ende.getX() + posX),(int)(ende.getY() - posY));
		}else{
			p.addPoint((int)(ende.getX() + posX),(int)(ende.getY() + posY));
		}
		posX = Math.sin(alphaX + Math.toRadians(270.0)) * radius;
		posY = Math.cos(alphaX + Math.toRadians(270.0)) * radius;
		
		if(richtung > 0.0){
			p.addPoint((int)(ende.getX() + posX),(int)(ende.getY() - posY));
		}else{
			p.addPoint((int)(ende.getX() + posX),(int)(ende.getY() + posY));
		}
		
		return p;
	}
	
}
 
Zurück