# repaint() zu langsam, bitte um alternativen



## apokryphus (11. Mrz 2010)

liebe community,

dies ist mein erster post und ich möchte alle, verbunden mit meiner anfrage, grüßen.

folgender code (wiiremotej-bibliothek auf ubuntu 9.10 mit java-6-sun-1.6.0.15) führt dazu, dass beim gleichzeitigen betrachten der ausgaben, delays von gut einer halben sekunde zwischen dem bewegen der wiiremote und der ausgabe auftreten. kann mir bitte jemand dabei helfen die performance zu verbessern?

```
import java.awt.*;
import javax.swing.*;

import wiiremotej.*;
import wiiremotej.event.*;

import javax.sound.sampled.*;
import java.io.*;


public class WiiConnect extends WiiRemoteAdapter{
    public WiiConnect(WiiRemote remote)
    {
      this.remote = remote;
    }
    private static boolean accelerometerSource = true; //true = wii remote, false = nunchuk
    private static boolean lastSource = true;
    
    
    private WiiRemote remote;

    private static JFrame graphFrame;
    private static JFrame irFrame;
    private static JPanel graph;
    private static JPanel irVision;
    private static int[][] pixels;
    private static int t = 0;
    private static int x = 0;
    private static int y = 0;
    private static int z = 0;
    
    private static int lastX = 0;
    private static int lastY = 0;
    private static int lastZ = 0;

    private static int pos1x = 0;
    private static int pos1y = 0;
    private static int pos2x = 0;
    private static int pos2y= 0;
    
	public static void main(String args[]){
		System.setProperty("bluecove.jsr82.psm_minimum_off", "true");

		try{
			
		    graphFrame = new JFrame();
		    graphFrame.setTitle("Accelerometer graph: Wii Remote");
		    graphFrame.setSize(800, 600);
		    graphFrame.setResizable(false);
		    
		    t = 801;
		    pixels = new int[800][600];
		    graph = new JPanel(){
		        public void paintComponent(Graphics graphics)
		        {
		            if (t >= 800 || accelerometerSource != lastSource)
		            {
		                t = 0;
		                lastSource = accelerometerSource;
		                graphics.clearRect(0, 0, 800, 600);
		                graphics.fillRect(0, 0, 800, 600);
		                graphics.setColor(Color.WHITE);
		                graphics.drawLine(0, 300, 800, 300);
		            }
		            
		            graphics.setColor(Color.RED);
		            graphics.drawLine(t, lastX, t, x);
		            graphics.setColor(Color.GREEN);
		            graphics.drawLine(t, lastY, t, y);
		            graphics.setColor(Color.BLUE);
		            graphics.drawLine(t, lastZ, t, z);
		        }
		    };
		    graphFrame.add(graph);
		    graphFrame.setVisible(true);
		    
			}catch(Exception e){
				System.out.println("Fehler bei Draw!");
			}
		
		try{
			
		    irFrame = new JFrame();
		    irFrame.setTitle("IR-Vision: Wii Remote");
		    irFrame.setSize(400, 400);
		    irFrame.setResizable(false);
		    

		    irVision = new JPanel(){
		        public void paintComponent(Graphics graphics)
		        {
	                graphics.clearRect(0, 0, 400, 400);
	                graphics.fillRect(0, 0, 400, 400);
		            graphics.setColor(Color.WHITE);
		            graphics.drawOval(pos1x, pos1y, 10, 10);
		            graphics.drawOval(pos2x, pos2y, 10, 10);
		        }
		    };
		    irFrame.add(irVision);
		    irFrame.setVisible(true);
		    
			}catch(Exception e){
				System.out.println("Fehler bei Draw!");
			}
			
		try {
				WiiRemote remote = WiiRemoteJ.findRemote();
				System.out.println(remote.getBluetoothAddress());
	            remote.setAccelerometerEnabled(true);
	            remote.setIRSensorEnabled(true,1);
	            remote.addWiiRemoteListener(new WiiConnect(remote));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			

	}
	   

    
	public void accelerationInputReceived(WRAccelerationEvent evt)
    {
        //System.out.println("R: " + evt.getRoll());
        //System.out.println("P: " + evt.getPitch());
        if (accelerometerSource)
        {
            lastX = x;
            lastY = y;
            lastZ = z;
            
            x = (int)(evt.getXAcceleration()/5*300)+300;
            y = (int)(evt.getYAcceleration()/5*300)+300;
            z = (int)(evt.getZAcceleration()/5*300)+300;
            
            t++;

            graph.repaint();
        }
    }

    public void IRInputReceived(WRIREvent evt)
    {  
       if((evt.getIRLights()[0] != null) && (evt.getIRLights()[1] !=null)){

	        pos1x = (int) (evt.getIRLights()[0].getX()*100+140);
	        pos1y = (int) (evt.getIRLights()[0].getY()*100+140);
	        pos2x = (int) (evt.getIRLights()[1].getX()*100+140);
	        pos2y = (int) (evt.getIRLights()[1].getY()*100+140);
			
	    	irVision.repaint();
	    
       }	
       
    }
}
```


----------



## Verjigorm (11. Mrz 2010)

anstatt 

```
graphics.clearRect(0, 0, 400, 400);
graphics.fillRect(0, 0, 400, 400);
```
aufzurufen sollte man imho 

```
super.paintComponent(graphics);
```
 aufrufen.

Aber weiss nicht, ob es was bringt.
Testen kann man leider nichts


----------



## SlaterB (11. Mrz 2010)

kommen die Daten überhaupt schnell genug an, funktioniert das Programm wenn du ohne GUI nur mit System.out.println() arbeitest?
zumindest eine Links<->Rechts-Bewegung könnte man damit doch testen

Ausgabe
xxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxx
xxxxxxxx
xx
xxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
usw


----------



## apokryphus (11. Mrz 2010)

Hallo,

also die Daten kommen schon schnell genug an, wenn ich ein Fenster schließe, dann wird nach kurzer Zeit die Visualisierung zeitnah umgesetzt. Das Lag verschwindet also.

Liegt es an meinem Rechner (Asus 1201n) oder ist der Eventlistener einfach überlastet? 

Die G-Sensoren arbeiten mit 100Hz und der BluetoothStack scheint so gesehen auch in Ordnung, da ja ein Fesnter allein adäquat dargestellt wird.

@Slater: Ich versteh leider deinen Hinweiß nicht ganz: Muss ich die beiden Instanzen des Panels nicht getrennt bearbeiten?


----------



## SlaterB (11. Mrz 2010)

> Muss ich die beiden Instanzen des Panels nicht getrennt bearbeiten? 

ich hatte dir vorgeschlagen, überhaupt keine Panel oder GUIs zu verwenden, 
sondern nur einen WiiRemoteAdapter, der aus den Events bisschen x,y ausrechnet 
und diese Information per System.out.println() ganz simpel visualisiert
(-> wenn das auch verzögert, dann ist das Problem noch nicht gelöst, aber hat zumindest nichts mit der GUI zu tun)

aber du schriebst ja jetzt, dass die Daten schnell genug ankommen, wenn du dir da sicher bist, dann mag es so sein

-----

ich habe weder Wii noch die API um das zu testen,
man könnte sich den Spass machen und stattdessen eine Dummy-Datenquelle bauen, die als eigener Thread läuft und im Verlauf von ein paar Sekunden die passenden Daten liefert um eine Bewegung anzuzeigen,
dann könnte jeder testen wie schnell das ankommt, wie schnell die GUI reagiert usw.,
noch wär mir das zuviel Aufwand, aber wenn du das machen willst oder der Thread noch eine Weile dauert wär das schon interessant


----------



## apokryphus (11. Mrz 2010)

> > Muss ich die beiden Instanzen des Panels nicht getrennt bearbeiten?
> 
> ich hatte dir vorgeschlagen, überhaupt keine Panel oder GUIs zu verwenden,



Sorry, mein Fehler, das ging eigentlich an Verjigorm...

Also ja, ich denke, dass die Daten schnell genug ankommen. Könnte es sein, dass die G-Sensordaten und die der IR-Events die Bandbreite überlasten, bzw. das System träge machen? 
Ich bin allerdings auch eher ein Anfänger in den Dingen. 

Grundsätzlich wäre ein Testthread glaube ich nicht schwer, da einfach nur beliebige doubles zwischen -1 und 1 für die drei G-Sensoren sowie doubles zwischen 0,1 für die IR-Lights ankommen müssten.

Danke euch beiden!


----------

