Icons flimmern

Status
Nicht offen für weitere Antworten.

anfänger

Mitglied
Hallo,

ich habe ein Problem mit meinen Icons. Ich muss diverse Icons auf ein JPanel zeichnen. Da es aber nicht gerade wenig sind und die gleichzeitig mit dem Zeichnen vom Hintergrund geschehen kann, hab ich es mit Threads versucht. Die Icons werden zwar auch gezeichnet, aber bleiben nicht auf der Bildfäche, sonder verschwinden wieder und werden dann wieder gezeichnet. Wenn ich das ganze ohne Threads mache, hab ich dieses Problem aber nicht.
Vielleicht sieht sieht ja jemand meinen Fehler.

Danke.

Code:
public class IconThread extends JPanel implements Runnable{
	
	Graphics g;
	String sep;
	
	BufferedImage bimage =new BufferedImage(20,20,BufferedImage.TYPE_INT_ARGB);
	ImageIcon icon = new ImageIcon();
	
	
	final static Color farbe_rgb[]={new Color(210,20,0), new Color(60,60,200), new Color(250,120, 0),
			new Color(148,0,212), new Color(185,135,11), new Color(0,106,250),
			new Color(176,156,156), new Color(145,172,183)};
	
	IconThread(Graphics g, String sep)
	{
		this. g = g;
		this.sep = sep;
		new Thread(this).start();
	}

	public void run()
	{
		zeichneIcon(g);
	}
	
	public void zeichneIcon(Graphics g)
	{
		//System.out.println("len: "+Karte.zeichenDaten.length);
		MediaTracker mt = new MediaTracker(new JPanel());
		String tmp = "";
		String pfad = "";
		int index =0;
		
		Point view = Karte.scrollpane.getViewport().getViewPosition();
	     
	    int viewX = (int)(view.getX()/256);
	    int viewY = (int)(view.getY()/256);
	    
	 //   System.out.println("viewX: "+viewX+"  vviewY: "+viewY);
	     
	    boolean[][] gezeichnet = new boolean[500][500];
	    
		for(int i=0, l = Karte.zeichenDaten.length; i< l; i++)
		{		
			int x = Karte.zeichenDaten[i][9];
			int y = (Karte.canY- Karte.zeichenDaten[i][10]-6-6);
			
			if( x > viewX && x < viewX+500 && y > viewY && y < viewY+500 )
			{
			
				if( !gezeichnet[x][y] )
				{
					
					gezeichnet[x][y]=true;
					String pfad = blabla;							
			 						
					try{
						//System.out.println("pfad:  "+pfad);
						bimage = ImageIO.read(new File(pfad));
						
					}catch(Exception e){System.out.println("Grafik-Datei nicht gefunden");}
					
					
					int farbe = Karte.zeichenDaten[i][8];
					bimage = richtigeFarbe(bimage, farbe);
					bimage.flush();
					
					mt.addImage(bimage,i);
					try{
						mt.waitForID(i);
					}catch(InterruptedException ie)
					{
						bimage = null;
						return;
					}
					g.drawImage(bimage, x, y, 20, 20 , this);
				//	System.out.println("zeichne Bild");
			//		repaint();
				}
			}
		}
		
		
	}
	
	


	public synchronized BufferedImage richtigeFarbe(BufferedImage bimg, int farbe)
	{
		BufferedImage ret = bimg;		
				
		if(farbe>=0)
		{
			Color setting = farbe_rgb[farbe];	// Die Farbe setting ist die jenige, die gesetzt werden soll
			for(int i = 1, l = bimg.getWidth(); i<l; i++)
				for (int j = 1,m =bimg.getHeight() ; j < m; j++) 		
					if(bimg.getRGB(i,j)==Color.BLACK.getRGB())
						ret.setRGB(i,j,setting.getRGB());
		}
		else
			System.out.println("Partei-ID ist keine Farbe zugeordnet.");
					
		return ret;
	
	}
}
 
B

Beni

Gast
Öh? Threads + AWT = Schlechte Idee.

Du könntest auch ein Bild (z.B. BufferedImage) nehmen, und die 1000 Icons dort draufzeichnen (sogar in einem eigenen Thread). Dann kannst du in paint nur dieses Bild zeichnen (was ziemlich schnell geht).
Natürlich geht das nur, wenn du nicht andauernd neue Icons hinzufügst oder sowas...
 

anfänger

Mitglied
allso meine icons stellen eigentlich kleine figuren da, die über meinen Hintergrund wandern. und da beides ja unabhängig läuft, wollte ich diesen Teil parallelisieren.
 
B

Beni

Gast
Dann schreib irgendwo die Position dieser Figuren hin, und lies sie bei einem Aufruf von "paint" aus. Schlussendlich muss das sowieso irgendwo berechnet werden, d.h. es gibt keine grossen Performance-Unterschiede od du das jetzt in dem Thread, oder in paint machst.
 

anfänger

Mitglied
okay, vielen Dank. dann werd ich diesen Gedanken wohl verwerfen.
Kann mir aber jemand sagen warum ich, wenn ich meinen Hintergrund in einem Threrad zeichenen will ein OutOfMemory bekomme, aber wenn ich ihn ganz normal erstelle keine Probleme auftauchen, außer dass es eine gewisse Zeit dauert und so dass scrollen nicht gerade angenehm ist.
Mein Hintergrund setzt sich aus mehreren Bimaps zusammen. Da ich aber nicht den ganzen Hintergrund zeichnen kann, weil ich sonst ein OutOfMemory bekomme, wird nur der Viewport dargestellt. dieser setzt sich aus 5*6 solcher Bitmaps zusammen. Die Bitmaps bestehen aus 256*256 Bildpunkte.

Hier mal der Code, wenn ich es als Thread ablaufen lasse:

Code:
public class KartenThread extends JPanel implements Runnable{
	
	Graphics g;
	
	
	
	
	KartenThread(Graphics g)
	{
		this.g = g;
		new Thread(this).start();
	}
	
	public void run()
	{
		zeichneKarte(g);
		while(true)
		{
			repaint();
			try{
				Thread.sleep(1000);
			}catch(InterruptedException ie){}
		}
		
	}
	
	public synchronized void zeichneKarte(Graphics g)
	{
		int counter = 0;
		int count_bm = 0;
		int x = 0; 
		
		MediaTracker mt = new MediaTracker(this);
		
			
 		for(int z = Karte.viewPosX, l= Karte.viewPosX+Karte.BmX ; z<l;z++)
		  	for(int k = Karte.viewPosY, m = Karte.viewPosY+Karte.BmY; k<m; k++)
		  	{	
				count_bm++;
				int count_farbe = 0;
	
					Image img = Toolkit.getDefaultToolkit().createImage(
							new MemoryImageSource(256,256,Panel.image_data[x],0,256));
					
					mt.addImage(img,counter);
					try{
						mt.waitForID(counter);
					}catch(InterruptedException ie)
					{
						img = null;
						return;
					}
					g.drawImage(img,z*256,k*256,this);
					counter++;
						
				x++;	
			}
	}
}
 

jptc.org

Bekanntes Mitglied
Hallo, ich weiss zwar nicht, ob Du Dein Problem gelöst bekommen hast, aber nun doch nochmal ein schlauer spruch dazu:

Ich habe hier im Forum schon mehrfach gesehen, dass versucht wird in Swing mit Threads zu arbeiten und immer wieder werde ich nicht müde mitzuteilen, dass das nicht so trivial ist, da alle Operationen für die GUI nur vom EventDispatcherThread ausgeführt werden dürfen. D.h. es dürfen in eigenen Thread keine grafischen Aktionen durchgeführt werden.

Naja und weil das blöd ist, hat sun die SwingUtilities mit dem SwingWorker eingeführt. Über diese Klassen kann man eine Swingapplication multithreading fähig machen.

http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html

http://www.javaworld.com/javaworld/jw-06-2003/jw-0606-swingworker.html
 

anfänger

Mitglied
vielen dank für die Internetseiten. Ich hatte zwar schon rausbekommen, das swing nicht threadsicher ist, aber keine alternative. vielen danke jedenfalls. ich werd mal sehen, was ich damit anfangen kann.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben