Swing en Thread

Status
Niet open voor verdere reacties.

Chargeotto

Gebruiker
Lid geworden
22 aug 2007
Berichten
147
Daarnet was ik bezig met een Tetris spel in Java met swing, en nu lukt het mij een blokje te tekenen.
Nu wou ik het zo maken, dat een blokje iedere seconde 1 lager geplaatst wordt, en dat wou ik doen, maar sinds ik de Thread heb toegevoegd, wordt het Swing venster helemaal niet meer weergegeven? :confused:
 
Daarnet was ik bezig met een Tetris spel in Java met swing, en nu lukt het mij een blokje te tekenen.
Nu wou ik het zo maken, dat een blokje iedere seconde 1 lager geplaatst wordt, en dat wou ik doen, maar sinds ik de Thread heb toegevoegd, wordt het Swing venster helemaal niet meer weergegeven? :confused:

Het eenvoudigste kan dit doen door een Timer te gebruiken. (uit de javax.swing package, er zijn er meer Timers in java)

Code:
Timer timer = new Timer(1000,new ActionListener() {
	public void actionPerformed(ActionEvent e) {
		// hier je code.	
	}
});
timer.start();

Als je deze timer gebruikt de swing thread dus mag je graphics updaten. Als je Timer uit java.util package) gebruikt mag dit niet.
 
Het eenvoudigste kan dit doen door een Timer te gebruiken. (uit de javax.swing package, er zijn er meer Timers in java)

Code:
Timer timer = new Timer(1000,new ActionListener() {
	public void actionPerformed(ActionEvent e) {
		// hier je code.	
	}
});
timer.start();

Als je deze timer gebruikt de swing thread dus mag je graphics updaten. Als je Timer uit java.util package) gebruikt mag dit niet.

thanks :thumb:, nu werkt het wel, alleen hij heeft nu last van iets anders. Het blokje valt met de timer iedere seconde 1 vakje omlaag. En hij valt ook 1 blokje omlaag als je op de knop "omlaag" drukt.
Alleen nu met de timer, laat hij iedere keer het oude blokje staan met tekenen, en als je dan met de hand op de knop omlaag drukt, doet hij het weer wel goed.

Misschien is het een beetje onduidelijk,als ik het zo vertel. Hieronder staat de link, naar mijn spel... ik hoop dat iemand een idee heeft wat er fout kan zijn.
Vreemd vind ik dat zowel de Timer als de actie die gebeurt na het klikken op de knop "omlaag" precies hetzelfde is :confused:

www.hitmol.nl/Tetris2.jar
 
Het zou praktisch zijn moest je source code er ook bij zitten;) maar ik neem aan dat de timer en de knop toch niet helemaal hetzelfde doen.
 
setDefaultCloseOperation(EXIT_ON_CLOSE); Please!
 
In dit geval moet je feitelijk in layers denken

Als je je class UI repaint() ga je je Graphics g (die wordt aangemaakt tijdens setVisible()) opnieuw tekenen maar als je je Grid repaint ga je je grid opnieuw tekenen en toevoegen aan Graphics g alsof je er een layer op kleeft. Dus elke keer teken je een nieuwe layer bovenop de reeds bestaande layers.

Oplossing 1: Grid heeft als parent UI dus als je zegt grid.getParent().repaint() (en grid.getParent().validate() om dat ook onmiddelijk uit te voeren) is je probleem onmiddelijk opgelost. Maar nu wordt er een 2de probleem gecreëerd... Waarom zou je alles willen herschilderen (ook bv. je achtergrond, buttons of tekeningen om de boel te verfraaien opnieuw inladen) als je enkel je grid wilt veranderen

Oplossing 2: Je veranderd de achtergrondkleur van je grid, nu heb je geen achtergrondkleur, elke keer als je nu je grid opnieuw tekent zal je de vorige achtergrond overlappen, dus weg met de doorzichtige layer
Code:
public void tekenGrid(Graphics g)
	{
		for (int i=0; i<10; i++)
		{
			for (int j=0; j<20; j++)
			{
				g.setColor(Color.lightGray);
				g.fillRect((i*25)+20, (j*25)+20, 25, 25);
				g.setColor(Color.gray);
				g.drawRect((i*25)+20, (j*25)+20, 25,25);
			}
		}
	}

oplossing 3: bij de vorige oplossing moet je nog steeds de complete grid hertekenen, in dit geval gaat het nog maar bij heel trage pc's of uitgebreidere games wil je enkel het stukje hertekenen dat veranderd, of misschien wil je wel dat de grid doorzichtig is dus ga je onthouden van welke positie de blok kwam en daarop g.clearRect() uitvoeren om dan te tekenen wat er oorspronkelijk stond
 
In dit geval moet je feitelijk in layers denken

Als je je class UI repaint() ga je je Graphics g (die wordt aangemaakt tijdens setVisible()) opnieuw tekenen maar als je je Grid repaint ga je je grid opnieuw tekenen en toevoegen aan Graphics g alsof je er een layer op kleeft. Dus elke keer teken je een nieuwe layer bovenop de reeds bestaande layers.

Oplossing 1: Grid heeft als parent UI dus als je zegt grid.getParent().repaint() (en grid.getParent().validate() om dat ook onmiddelijk uit te voeren) is je probleem onmiddelijk opgelost. Maar nu wordt er een 2de probleem gecreëerd... Waarom zou je alles willen herschilderen (ook bv. je achtergrond, buttons of tekeningen om de boel te verfraaien opnieuw inladen) als je enkel je grid wilt veranderen

Oplossing 2: Je veranderd de achtergrondkleur van je grid, nu heb je geen achtergrondkleur, elke keer als je nu je grid opnieuw tekent zal je de vorige achtergrond overlappen, dus weg met de doorzichtige layer
Code:
public void tekenGrid(Graphics g)
	{
		for (int i=0; i<10; i++)
		{
			for (int j=0; j<20; j++)
			{
				g.setColor(Color.lightGray);
				g.fillRect((i*25)+20, (j*25)+20, 25, 25);
				g.setColor(Color.gray);
				g.drawRect((i*25)+20, (j*25)+20, 25,25);
			}
		}
	}

oplossing 3: bij de vorige oplossing moet je nog steeds de complete grid hertekenen, in dit geval gaat het nog maar bij heel trage pc's of uitgebreidere games wil je enkel het stukje hertekenen dat veranderd, of misschien wil je wel dat de grid doorzichtig is dus ga je onthouden van welke positie de blok kwam en daarop g.clearRect() uitvoeren om dan te tekenen wat er oorspronkelijk stond

Heel erg bedankt, het werkt nu wel goed :D :thumb:
Heb nu oplossing 1 gebruikt, en ga het nog proberen te verbeteren naar oplossing 3
 
Ik ben nu al een stuk verder, maar ontdekte nu dat ik een memory-leak heb. Volgens taakbeheer komt er iedere seconde telkens een beetje geheugen bij de hele tijd.
En nu heb ik ontdekt dat als ik

grid.getParent().repaint();
grid.getParent().validate();

weglaat, en dus alleen de logica wordt uitgevoerd zonder het te tekenen. Het memory leak weg is. Iemand enig idee waarom mijn repaint voor een steeds groter geheugenbereik zorgt?
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan