AWT Artefakte bei AWT-Rendering durch parallelen Thread

jface

Mitglied
Hi,
ich hab folgendes Szenario. In meinem Programm gibt es zwei Tabs. Tab A stellt ein Signal dar, in Tab B wird ein Chronospektrum des Signals angezeigt (FFT). Soblad sich das Signal ändert (z.B. weiterscrollen in der Zeitachse) werden beide Tabs neu gezeichnet. Da die FFT einige Sekunde zur Berechnung braucht, hab ich sie in einen eigenen Thread ausgelagert, was auch wie erwartet im Hintergrund mein Tab B updatet. Das Problem dabei ist nur, das bis der Thread fertig ist, meine AWT-Darstellung des Signals mit Artefaktenuebersät wird. Ohne langwierige FFT-Berechnung sieht man das Problem natuerlich nicht. Ich weis nicht woher dieses Verhalten stammt....

Hier mal der Code:

Java:
public void displayedRecordModified() {
       
        //Die Grafik im Tab A
        polysomnograph.repaint();
        
        // Grafik in Tab B
        polysomnograph.repaint3D();
      
        
    }
                 
 public void repaint3D(){
               JPanel parent = (JPanel) this.mainWindow.jTabbedPane.getComponent(1);
	        
	        if(fft3d == null)
		        fft3d = new FFT3D(graph,graph2, navigationSlider.getValue(),
		        		getEpochDuration(),
		                (double) 0.0 ,
		                (double) 1.0, this,parent );
	        //else
	        	fft3d.update(graph,graph2, navigationSlider.getValue(),
			    		getEpochDuration(),
			            (double) 0.0 ,
			            (double) 1.0, this,parent ); 
		    
	        Thread th = new Thread(fft3d);
	        th.start();
	 }

und hier die run methode von FFT3D:

Java:
public void run() {    
        parent.removeAll();    
        JPanel tmp = new JPanel(new FlowLayout(FlowLayout.CENTER));
        tmp.add(new JLabel("FFT wird erstellt"));
        parent.add(tmp,BorderLayout.CENTER);  
        generate3DFFLR(graph, graph2, startSecond, duration, startPosition, endPosition, polysomnograph);
        parent.removeAll();
        parent.add(fft3DArea,BorderLayout.CENTER); 
        parent.getParent().repaint();
        
    }

Ich hab noch zwei Scrrenshots angehängt. Das erste bild zeigt die Ausgabe wie sie sein sollte und auch ist , nachdem die FFT fertig ist. Das zweite Bild zeigt das Signal wie es aussieht, während der andere Thread die FFt prozessiert. (Zum Teil gibt es noch mehr dieser rechteckigen Ausreisser )


Viele Grüsse

jface
 
Zuletzt bearbeitet:
Öhm. Bezeichnest du mit "Fraktale" diese Rechteckigen Dinger?
Anhand des geposteten ist es schwer, das was zu sagen. Wer berechnet und Zeichnet denn diese Blaue Linie (und wie) ?
 
üps. mein natürlich Artefakte.

Hier mal der code, der eine der blauen Linien letztendlich zeichnet.


Java:
private void displayData(Graphics2D g, int[] x, int[] y, Color color) {
        Color originalColor = g.getColor();
        g.setColor(color);

        g.drawPolyline(x, y, x.length);
        g.setColor(originalColor);
    }



Aufgerufen wird das ganze ueber:

Java:
public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g;
        
        //drawYAxis(g2D);

        JEDFGraph[] tabGraph = montage.getAllGraph();

        float heightOfAGraph = getGraphHeight();
        
           //malt eine linie (im beispielbild sinds insgesamt 4)
        for (int i = 0; i < tabGraph.length; i++) {
            tabGraph[i].draw(g2D, i * heightOfAGraph);
}

die letzte Zeile ruft diese Methode auf


Java:
public void draw(Graphics2D g, float yOffset) {
        double width = SwingUtilities.calculateInnerArea(polysomnograph,
                new Rectangle()).getWidth();
        double height = polysomnograph.getGraphHeight();

       // drawXAxis(g, yOffset, width, height);
        drawGraph(g, yOffset, width, height);
        //drawHighlightedPart(g, yOffset, width, height);
    }

drawGraph holt die Daten und lässt schliesslich das Signal malen:

Java:
 private void drawGraph(Graphics2D g2D, float yOffset, double width,
                           double height) {
        short[] rawData = signal.readSecondsAndAPoint(polysomnograph.
                getStartSecond(), polysomnograph.getEpochDuration());
        if (rawData.length == 0) {
            return;
        }
        int[][] processedData = processData(rawData, 0f, yOffset, (float) width,
                                            (float) height); //processNormalData(rawData,yOffset);

        boolean useNormalColor = true;
        PreciseScoring preciseScoring = polysomnograph.getPreciseScoring();

        if (preciseScoring != null) {
            useNormalColor = !preciseScoring.hasFocus();
        }
         
        //siehe anfang des Beitags
        displayData(g2D, processedData[0], processedData[1],
                    (useNormalColor ? drawColor : fadedColor));
    }

Was vielleicht noch von Interesse ist:
Wenn die Zeile
Java:
parent.getParent().repaint();
in der run() Methode weggelassen wird, dann bleiben die Artefakte bestehen. Das ganze muss also nochmal gezeichnet werden , damits wie gewuenscht aussieht.
 
Wenn ich einen Breakpoint in der Zeile

Java:
generate3DFFLR(graph, graph2, startSecond, duration, startPosition, endPosition, polysomnograph);

in der Methode run() setze, also gerade vor dem Abschnitt der das Problem mit den Artefakten erzeugt, dann gibts keine Artefakte, wenn ich das Programm nach der Pause wieder weiter laufen lasse.

Hab versucht, den Brakpoint durch ein
Java:
try {
			sleep(500);
		} catch (InterruptedException e) {			
			e.printStackTrace();
		}
zu ersetzen, hat aber leider nicht funktioniert. (FFT3D erbt hier von Thread, statt einem Runnable interface).

Oder mit was könnte man eine Breakpoint "simulieren"?
 
Am besten gar nichts. Das ganze gepostete hilft einem nicht weiter, weil keiner auch nur einen Hauch eines Überblicks darüber hat, was dort passiert. (Wer zeichnet die Linie? - Das wird mit drawPolyline gemacht! - Wer berechet die Linie? - Das wird in processData gemacht! - Was macht processData? Das-und-das! Und in welchem Thread, und was hat das mit dem Zeichnen zu tun? ...)

Veranlasse nach der Berechnung ein neues "repaint", und hoffe, dass es dann funktioniert... :bahnhof:
 

Zurück
Oben