Swing Funktion animieren

lavatar

Mitglied
Hallo zusammen,

habe das Problem das in meiner Klasse "Animator" das als Thread abläuft und ein JComponent beinhaltet, keine aktualisierte Zeichnung darstellt.

Java:
public class Animator extends JPanel implements Runnable{
	
	private Image dbImage;
	private Graphics dbGraphics;
	private double tMin;
	private double tMax;
	private double xMin;
	private double xMax;
	private double deltaX;
	private double deltaT;
	private double [] y1Werte = {0,1};
	private double [] y2Werte = {0,1};
	private double [] y3Werte = {0,1};
	private double [] y4Werte = {0,1};
	private double [] xWerte = {0,1};
	private double t;
	private Evaluate evaluate1;
	private Evaluate evaluate2;
	private Evaluate evaluate3;
	private boolean flag = true;
	private DecimalFormat decimalFormat = new DecimalFormat("0.00000000");
	
	public Animator(){
		   Locale.setDefault(Locale.US);
       }
	   public void run(){
		   while(true){		   
		       if(t>tMax){
		    	   t = tMin;
		       }
			   evaluate1.berechnenY(t);
			   evaluate2.berechnenY(t);
			   evaluate3.berechnenY(t);
			   y1Werte = evaluate1.gibYwerte();
			   y2Werte = evaluate2.gibYwerte();
			   y3Werte = evaluate3.gibYwerte();
			   xWerte = evaluate1.gibXwerte();
			   summe();
			   t += deltaT;
			   System.out.println(t);
			   repaint();
		   }
	   }
	   /* Initalisierung aller Variablen */
	   public void init(double argTmin,double argTmax,double argXmin,double argXmax,
			            double argDeltaT,double argDeltaX,String argAusdruck1,
			                          String argAusdruck2,String argAusdruck3){
		   t = argTmin;
		   tMin = argTmin;
		   tMax = argTmax;
		   xMin = argXmin;
		   xMax = argXmax;
		   deltaX = argDeltaX;
		   deltaT = argDeltaT;	
		   evaluate1 = new Evaluate();
		   evaluate2 = new Evaluate();
		   evaluate3 = new Evaluate();
		   initEvaluate(evaluate1,argAusdruck1);	
		   initEvaluate(evaluate2,argAusdruck2);
		   initEvaluate(evaluate3,argAusdruck3);
	   }private void initEvaluate(Evaluate argEvaluate, String argAusdruck){
	        argEvaluate.setDeltaX(deltaX);
	        argEvaluate.berechneXindex(xMin, xMax);
	        argEvaluate.initArrays();
	        argEvaluate.einsortierenX();	          
			try {
				argEvaluate.initParser(argAusdruck);
			} catch (IllegalNameException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	   }
	   public void stop(){
		   flag = false;
	   }
	   private void summe(){
		   y4Werte = new double [evaluate1.gibArrayLaenge()];
		   for(int i=0;i<=evaluate1.gibArrayLaenge()-1;i++){
			   y4Werte[i] = Double.parseDouble(decimalFormat.format(y1Werte[i]+y2Werte[i]+y3Werte[i]));
		   }
	   }
		public void paint(Graphics g){
	           g.setColor(Color.red);
	           if(y1Werte != null){
	           funktionZeichnen(g,y1Werte,xWerte,1,5,20);
	           funktionZeichnen(g,y2Werte,xWerte,2,5,20);
	           funktionZeichnen(g,y3Werte,xWerte,3,5,20);
	           funktionZeichnen(g,y4Werte,xWerte,4,5,20);	           
	           }   
		}		public void funktionZeichnen(Graphics g,double [] argYfunktion,double [] argXfunktion,
				                                           int argTeil,int argAufteilung,int deltaX){
			for(int i = 0;i < argYfunktion.length -1;i += 1){
				/* Abfrage ob Y-Grenzen eingehalten werden in beide Richtungen */
				if((argTeil * this.getHeight()/argAufteilung) - (int)(argYfunktion[i+1]*deltaX) >= (argTeil * this.getHeight()/argAufteilung)- ((this.getHeight()/argAufteilung)/2)){
					if((argTeil * this.getHeight()/argAufteilung) - (int)(argYfunktion[i+1]*deltaX)<= (argTeil * this.getHeight()/argAufteilung)+ ((this.getHeight()/argAufteilung)/2))
					g.drawLine(this.getWidth()/2 +(int)(argXfunktion[i]*deltaX), (argTeil * this.getHeight()/argAufteilung)- (int)(argYfunktion[i]*deltaX), this.getWidth()/2 + (int)(argXfunktion[i+1]*deltaX), (argTeil * this.getHeight()/argAufteilung)- (int)(argYfunktion[i+1]*deltaX));
				}			
			}
		}

Es erfolgt immer wieder eine neu Berechnung von y1Werte-y4Werte double Array, die geht auch ohne Probleme, aber es wird bei der Zeichnung nicht berücksichtigt, sonder immer die alten Werte genommen ({0,1}).

Kann mir bitte jemand bei diesem Problem helfen?
 
Zuletzt bearbeitet von einem Moderator:
wenn immer die alten Werte genommen werden, woher erkennst du überhaupt, dass neu gezeichnet wird?
vielleicht ist nur der Anfang zu sehen und das neue nicht, weil überhaupt nicht gezeichnet wird oder nicht im sichtbaren Bereich (!),

dadurch dass du paint() überschreibst statt üblicherweise paintComponent() werden alte Zeichnungen bei dir nicht gelöscht,

dein Programm ist für Fremde unverständlich und nicht auszuprobieren,
ich habe hier eine einfachere Version zusammengestellt, die viele Linien recht nahe zusammen übereinander malt
Java:
public class TestGUI   extends JFrame {
    public TestGUI()  {
        Animator2 a = new Animator2();
        add(a);

        setSize(450, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        new Thread(a).start();
    }

    public static void main(String[] args)  {
        new TestGUI();
    }
}

class Animator2  extends JPanel  implements Runnable {
    private double[] y1Werte =   {50, 100};
    private double[] xWerte = {70, 100};

    public void run() {
        while (true)    {
            try  {     Thread.sleep(400);  }   catch (Exception e){    }
            y1Werte = new double[2];
            y1Werte[0] = 50 + Math.random() * 50;
            y1Werte[1] = 50 + Math.random() * 50;
            repaint();
        }
    }

    public void paint(Graphics g)  {
        g.setColor(Color.red);
        g.drawLine((int)xWerte[0], (int)y1Werte[0], (int)xWerte[1], (int)y1Werte[1]);
    }
}
 
Ja, tut mir leid das mit dem Nachvollziehen.

Also dein Beispiel funktioniert einwandfrei. Im Prinzip soll das genau so ablaufen,
nur sollten die alten Zeichnungen nicht stehen bleiben, Stichwort PaintComponent.
Du liegst sehr richtig mit deiner Vermutung, es wird einfach nichts neu gezeichnet oder nicht sichtbares.
Ich probier schon einige Zeit dieses Problem in den Griff zu bekommen, aber ich bin echt am verzweifeln.:rtfm:



Als Anhang Eclipse Quellcode!

Zur Erklärung man gibt 3 Funktionen ein, und diese werden dann grafisch dargestellt.
Zum testen einfach x, 1 , 2 eingeben und start drücken bei "Surface" Instanz.
 
Zuletzt bearbeitet:
ich widerstrebe, 120kb Code anzuschauen,
logge in funktionZeichnen(), was da an Linien gemalt wird
Java:
System.out.println("male Linie von x/y nach x/y");
wenn da negative Werte oder zu hohe oder immer die gleichen rauskommen, dann musst du da eben was ändern
 
Ok, würd ich auch nicht gerne machen.

Also hab gerade mir die array Werte ausgeben lassen.
Die alten Werte bleiben bestehen, ich versteh nicht warum?


ich widerstrebe, 120kb Code anzuschauen,
logge in funktionZeichnen(), was da an Linien gemalt wird
Java:
System.out.println("male Linie von x/y nach x/y");
wenn da negative Werte oder zu hohe oder immer die gleichen rauskommen, dann musst du da eben was ändern
 
debuggen debuggen debuggen,

es fängt an mit der Animator-Klasse, gib im Konstruktor etwas aus um zu erkennen ob du vielleicht mehrere Objekte davon hast,
dann verfolge eines der Arrays genauer,

in der paint-Methode glaubst du schon zu erkennen, dass die Werte dieselben sind,
gib das Array-Objekt an sich aus, dann bekommt du eine kyptische Ausgabe mit Hashcode, nur gut um es von anderen zu unterscheiden, den Array-Inhalt kannst du mit Schleife oder Arrays.toString() ausgeben, falls nicht zu lang,
bleibt es eigentlich bei zwei Werten oder werden es mehr?

wichtig ist nun, an anderer Stelle genauso zu verfahren, in der Schleife in der das Array aktualisiert werden soll,
auch dort das Array + den Inhalt ausgeben, ist es dort auch immer das gleiche (dann davor schauen was Evaluate nun macht)
oder ist es dort geändert aber später wieder das alte?
nur inhaltlich oder auch das Array-Objekt selber, der Hashcode,

genau im Code schauen, welche Stellen auf das Array Zugriff haben, ruhig mal dieses Klassenattribut umbenennen,
prüfen ob nicht irgendwo gleichnamige lokale Variablen vorliegen usw.
 
Also Evaluate und Animator wurden mittels JUnit schon getestet, beide berechnen richtig.

Hab nun aber nochmals in der Berechnungsschleife mit die Werte ausgeben lassen.
Alles in Ordnung.
Bei paintComponent(), vormals paint(), hat immer noch die alten Werte. Egal welche Funktion ich eingebe es bleibt immer bei {0,1}.
 
Ich hatte das ganze schonmal programmiert aber ohne Testgetriebene Software Entwicklung.
Aber das mich das so aufhält mit dem zeichnen verwundert mich immer noch.
 
ganz schön schlimmes Programm, deine von dir vorgeschlagene Eingabe x, 1, 2 funktioniert gar nicht
die Funktion x führt zu einer Expression [c]LEFT_PARENTHESIS;VAR_0;RIGHT_PARENTHESIS;[/c],
diese dann zu einer filterParenthesis()-Map mit 0 -> VAR_0 sowie 1 -> P_0,
letzterer Term wird vom Translator in [c]tM.lex2MathtreeList[/c] nicht gefunden..

als ich den aus der Map entfernt habe gings weiter,
Fehler war letzlich leicht zu finden, so dass ich mich frage was du überhaupt selber getestet hast?
wenn man in funktionZeichnen() Ausgaben reinsetzt sind diese nicht zu sehen trotz laufender run-Schleife des Threads,
(bei Schleifen immer Thread.sleep() einbauen, 1 Mio. mal pro Sekunde bringt doch nix)

selbst direkt in paint als erste Zeile [c]System.out.println("paint");[/c]
bring gar nicht, was hast du dahingehend gemacht?
Aussagen wie "Bei paintComponent(), vormals paint(), hat immer noch die alten Werte. " erscheinen fraglich, aber strenggenommen schreibst du auch gar nicht dass du da irgendwas getestet hättest..

der Grund für kein paint() liegt recht bald auf der Hand: der Animator ist überhaupt nicht in die GUI eingebunden,
auch dafür hatte ich schon einen Hinweis gepostet
debuggen debuggen debuggen,

es fängt an mit der Animator-Klasse, gib im Konstruktor etwas aus um zu erkennen ob du vielleicht mehrere Objekte davon hast,
so ist es,

Klassenattribut animator1 ist in der GUI zu sehen, neues Objekt animator wird als Thread ausgeführt
 
Zuletzt bearbeitet von einem Moderator:
Hast du überhaupt Eclipse benutzt?
Das Beispiel funktioniert so wie ich es geschrieben habe!

Thread.sleep() war eingebaut, kann sein das ich ihn als ich den Export gemacht habe entfernt hatte!

Ich wollte dir nicht deine Zeit stehlen.
Danke, werde mir deine Lösung zu den Problem jetzt genau anschauen.

EDIT:
Ja du hattest Recht, es verblüfft mich gerade.
Weil ich die GUI mehrmals neu aufgesetzts habe.

Danke Dir!
 
Zuletzt bearbeitet:

Zurück
Oben