|
[ sanja2010 @ 11.06.2009. 00:56 ] @
| Imam aplikaciju sa JButtonom gde klik na dugme treba da promeni njegov ImageIcon, da se program pauzira na sekund, pa da vrati ikonicu na staro. E sad, nikad nisam koristila timere, a izguglala sam da to preko njih treba da se radi.
Konkretno, pravim onu igricu memorija gde na tabli treba da pronadjete dva ista simbola. Znaci, otvorite prvo polje, ono stoji dokle god se ne klikne na drugo polje. Ako nisu ista, oba stoje otvorena recimo sekund, pa se zatvore. Napravila sam matricu JButtona. Klikom na neki pokrece se ActionPerformed ciji bitan deo koda izgleda ovako:
Code: public void actionPerformed(ActionEvent event) {
if
//nesto nebitno
}
else {
String koordinate = event.getActionCommand();
Point tacka = new Point();
tacka = nadjiKoordinate(koordinate); //ActionCommand mi kaze koje su koordinate dugmeta u matrici
timer = new Timer(700, new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPolja[igra.getOtvoreno(0).x][igra.getOtvoreno(0).y].setIcon(upitnik);
buttonPolja[igra.getOtvoreno(1).x][igra.getOtvoreno(1).y].setIcon(upitnik);
labelPokusaji.setText("Broj pokusaja: " + Integer.toString(igra.getBrojPokusaja()));
timer.stop();
}
});
if (igra.getStanje(tacka)==false) {
int pomocna = igra.proveri(tacka);
//ako je pomocna 0, kliknuto je na vec otvoreno polje,
//ako je 1, otvoreno je 1. polje, ako je 2, otvoreno je 2. polje
if (pomocna>0) {
buttonPolja[tacka.x][tacka.y].setIcon(igra.getSlike(igra.getTip(tacka)));
if (pomocna==2) {
timer.restart();
}
if (igra.getBrojPreostalihPolja()==0) {
krajIgre();
}
}
}
}
}
Ovo s tajmerom je radjeno potpuno naslepo, bukvalno sam nagadjala sta da radim. Kada igrica krene, to radi kako treba, kad se otvore 2 polja, program saceka sekundu, pa vrati na staro stanje itd. Posle izvesnog broja poteza tj. izvesnog vremena, ta sekunda se sve vise smanjuje i na kraju potpuno prestaje da menja ImageIcon-e. Ja stvarno ne kapiram o cemu se tu radi i pokusala sam da trazim na guglu, ali mi i dalje stvari nisu najjasnije. U sustini, ako mi tajmeri nisu potrebni i mogu da zaustavim program na odredjeni vremenski interval bez njih (a da to nije Thread.sleep() jer ne radi kako treba), otvorena sam za predloge :) |
[ bantu @ 11.06.2009. 07:55 ] @
Zašto Thread.sleep() ne radi kako treba? Možda si ga pogrešno koristila? Pravilno bi bilo da kreiraš novi thread prosljediš mu reference na dugmad za koja treba da vrati ikonice poslije određenog vremena i da ga onda "uspavaš", a da ti se glavni thread u kome se iscrtava GUI nastavi da radi nesmetano. Možda nešto ovako, naravno ti to sada prilagodi svojim potrebama. Nadasm se da će da ti pomogne.
Code:
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class IconReseter extends Thread {
private JButton button1;
private JButton button2;
private ImageIcon upitnik;
private int time;
public IconReseter(JButton button1, JButton button2, ImageIcon upitnik, int time) {
this.button1 = button1;
this.button2 = button2;
this.upitnik = upitnik;
this.time = time;
}
public IconReseter(JButton button1, JButton button2, ImageIcon upitnik) {
this(button1, button2, upitnik, 1000);
}
public void run() {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
button1.setIcon(upitnik);
button2.setIcon(upitnik);
}
}
[ bantu @ 11.06.2009. 08:05 ] @
Zaboravih ti reći kako da upotrebiš ovo, mislim nije komplikovano ali da ne lutaš puno.
Negdje u kodu kada prikažeš i drugu sličicu i odlučiš da poslije nekog vremena treba da resetuješ obe sličice uradi ovo ispod i trebalo bi da radi.
Code:
IconReseter ir = new IconReseter(...);
ir.start();
[ sanja2010 @ 11.06.2009. 08:59 ] @
Isprobavala sam i to... i cini mi se da sam nesto jako slicno kucala, pa nije radilo :( Na nekom linku sam naletela da nije dobro koristiti threadove u ove svrhe, ali posto sam isuvise vremena potrosila s ovim, resenje mi je sasvim zadovoljavajuce :) Jedini problem je sto se program bas ne zakljuca tj. ako neko klikce okolo dok su ova 2 polja otvorena, i ona ce da se otvore, ali to cu vec nekako da resim.
Hvala ti puno :) Trebalo je mnogo ranije da pitam...
Edit: ako nekog ne mrzi, moze li da mi kaze u cemu sam gresila s timer-om?
[ bantu @ 11.06.2009. 09:11 ] @
E pa palo mi je to na pamaet dok sam ti pisao odgovor. To bi možda mogla riješiti tako što bi za sva ostalo dugmad uradila button.disable(); a ovom threadu proslijedis listu dugmadi koje treba ponovo enableovati. pa samo prođeš kroz listu i uradiš button.enable();
[ sanja2010 @ 11.06.2009. 10:10 ] @
Resila sam i taj problem :) Verovatno je resenje malo trapavo, ali uspesno. U run pre sleep-a sacuvam ActionListener za dugmice u posebnoj promenljivoj, sklonim ga s dugmica, pa ga posle spavanja thread-a vratim. Pokusala sam sa setEnabled (enable i disabled nisu radili kako valja, a i eklipsa mi je davala neke warninge), ali nije to sasvim ono sto zelim. U svakom slucaju, ovo radi, tako da sam ja savrseno zadovoljna.
Hvala puno!
[ bantu @ 11.06.2009. 10:39 ] @
Jesi li razmižljala o nekom flag-u koji podigneš u ActionListeneru kada klikneš na drugo dugme a na kraju run metode ga ponovo vratiš? I dovoljnoto je samo da ubaciš jedan if u ActionListener dogmadi koji provjerava stanje flag-a i to ti je to.
[ sanja2010 @ 11.06.2009. 10:46 ] @
Kazem ja da je ono resenje verovatno trapavo... Trebalo je jos malo da porazmislim i odaberem nesto ociglednije :) Hvala jos jednom.
[ Dejan Lozanovic @ 11.06.2009. 20:03 ] @
Citat: bantu: Zašto Thread.sleep() ne radi kako treba? Možda si ga pogrešno koristila? Pravilno bi bilo da kreiraš novi thread prosljediš mu reference na dugmad za koja treba da vrati ikonice poslije određenog vremena i da ga onda "uspavaš", a da ti se glavni thread u kome se iscrtava GUI nastavi da radi nesmetano. Možda nešto ovako, naravno ti to sada prilagodi svojim potrebama. Nadasm se da će da ti pomogne.
Code:
import javax.swing.ImageIcon;
import javax.swing.JButton;
public class IconReseter extends Thread {
private JButton button1;
private JButton button2;
private ImageIcon upitnik;
private int time;
public IconReseter(JButton button1, JButton button2, ImageIcon upitnik, int time) {
this.button1 = button1;
this.button2 = button2;
this.upitnik = upitnik;
this.time = time;
}
public IconReseter(JButton button1, JButton button2, ImageIcon upitnik) {
this(button1, button2, upitnik, 1000);
}
public void run() {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
button1.setIcon(upitnik);
button2.setIcon(upitnik);
}
}
ARGH :) je samo sto mogu da kazem :) ovo ovako ne ni u ludilu, swing klase nisu thread safe, ovo sto si uradio generalno ni malo nije dobro, za bilo kakve mahinacije da vam sa swingom treba nesto da bude u vise threadova generalno treba koristiti swingworker( http://java.sun.com/javase/6/d...i/javax/swing/SwingWorker.html), ili ako zelis nesto u posebnom thereadu a treba da menjas state neke od komponenti onda imas SwingUtilities.invokeAndWait ili SwingUtilities.invokeLater, pa onda unutar tih run metoda promeni stanje koje ti treba.
Da sam asistent na fakultetu i da mu student donese ovo kao domaci/seminarski ja bi ga oborio :)
[ sanja2010 @ 11.06.2009. 20:14 ] @
Nismo mi bas duboko isli u swing, tako da necu pasti sigurno :) Vise zelim zbog sebe da naucim ove stvari, zato sam i pitala za tajmere. U svakom slucaju, pozabavicu se ovim sto si napisao. Hvala i tebi :)
[ Dejan Lozanovic @ 11.06.2009. 20:31 ] @
Generalno neka ti ideja vodilja da unutar listenera stvari moraju da se izvrsavaju veoma brzo, jer u tom threadu se odvijaju i sve ostale stvari, reagovanje na eventove i iscrtavanje kontrola. Pa primera radi ako unutar nekog eventa napravis jedan Thread.sleep(10000); narednih 10 minuta imaces osecaj kao da se progarm zaglavio i ne reaguje ni na sta, pa cak i ako u to vreme prevuces neki program preko tvog, videces da se nece ponovo iscrtati. Zbog takvih stvari generalno treba koristiti SwingWorkere.
Drugi savet koji bi mogao da ti dam, jeste da pises komentare i kod na engleskom jeziku :), veruj mi svi poslodavci to traze, to je neka vrsta dobre prakse , na koju bi mogla da pocnes da se teras.
[ sanja2010 @ 11.06.2009. 20:56 ] @
Za prvi savet, hvala :)
Za drugi savet, da, znam to, ali profesor insistira da sve bude na srpskom jeziku. Mnogo sam se nervirala dok sam kucala sve na srpskom, ne staj mi na muku :)
[ bantu @ 12.06.2009. 09:02 ] @
Da li bi prošao da sam uradio ovako nešto?
:)
Code:
SwingUtilities.invokeLater(new IconReseter(JButton button1, JButton button2, ImageIcon upitnik));
[ Dejan Lozanovic @ 12.06.2009. 16:55 ] @
Citat: bantu: Da li bi prošao da sam uradio ovako nešto?
:)
Code:
SwingUtilities.invokeLater(new IconReseter(JButton button1, JButton button2, ImageIcon upitnik));
ne bi :) opet bi pao :) zato sto taj IconReseter ima u sebi taj thread.sleep() a on u stvari ubije celu stvar i zbog njega zapravo hocemo da se sklonimo u drugi thread.
Code:
public class IconReseter extends Thread {
private JButton button1;
private JButton button2;
private ImageIcon upitnik;
private int time;
public IconReseter(JButton button1, JButton button2, ImageIcon upitnik, int time) {
this.button1 = button1;
this.button2 = button2;
this.upitnik = upitnik;
this.time = time;
}
public IconReseter(JButton button1, JButton button2, ImageIcon upitnik) {
this(button1, button2, upitnik, 1000);
}
public void run() {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
button1.setIcon(upitnik);
button2.setIcon(upitnik);
}
});
}
}
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|