Zatrzymanie pętli

Odpowiedz Nowy wątek
2010-10-09 16:23

Rejestracja: 9 lat temu

Ostatnio: 6 lat temu

0

Witam,
po wcisnieciu buttona, zaczyna sie rysowac punkty az do ostatniego, chcialbym jednak by po wcisnieciu drugiego buttona petla zakonczyla swoje dzialanie.

kod w buttonie "Stop":

stop = false;

fragment kodu z buttonem "Start":


int iloscElementow = ODane.length;
        stop = true;

        while(j<iloscElementow || stop ==true ) {

            RysujPunkt(j);
            j++;

        }

Niestety po wcisnieciu przycisku Start petla sie wykonuje, rysuje ladne punkty jak nalezy, tylko nie da sie wcisnac przycisku Stop ani nic innego.
Prosze o pomoc.</cpp>

Pozostało 580 znaków

::.
2010-10-09 16:42
::.
0

Poczytaj o warkach i klasie SwingWorker.
W skrocie: za GUI odpowiedzialny jest watek o nazwie EDT (Event Dispatch Thread) - caly kod w Twoich listenerach odbywa sie w tym watku, zatem Twoja niekonczaca sie petla rowniez. Skoro ona sie nie konczy, EDT jest nieustannie zajety, wiec nie pozwala wcisnac nic innego, ani odrysowac, ani nic. Rozwiazaniem jest wystartowanie osobnego watku rysujacego punkty - jednak to rozwiazanie ma takie wady, ze Swing jest jednowatkowy i nie wolno dotykac jego klas (ok, wiekszosci, niektore mozna) z innych watkow niz EDT. W tym miejscu mozesz zrobic maly task implementuja Runnable i zapodac go do EDT - no ale ponownie rysowanie bedzie sie odbywac w EDT, czyli powtorka z sytuacji 1, ktora masz teraz.
Rozwiazanie jest takie, aby wykonywac logike rysowania w osobnym watku, ale w jakis sposob odwolywanie sie do panelu / labelki po ktorej rysujesz w EDT - nie lada gratka dla laikow (jakim bez watpienia jestes, bez urazy - kazdy kiedys zaczynal). Rozwiazaniem jest wspomniany wyzej SwingWorker. Ta klasa zajmuje sie synchronizacja za Ciebie, ty musisz tylko zaimplementowac pare metod, i wszystko bedzie sterowane przez SwingWorkera. Notka: od Javy 1.4 przewinelo sie w internecie wiele wiele implementacji SwingWorkera, ale w Javie 6 zostala dolaczona standardowa klasa - poszukaj jej w API i poczytaj opis jej i jej metod.
Uprzedzajac kolejny post zanim go napiszesz jak juz zrobisz workera - zmiena boolean ktora decyduje czy petla ma rysowac czy przestac jest ruszana w (co najmniej) 2 watkach - EDT gdy startujesz / konczysz rysowanie, oraz w watku workera (w petli, jako warunek stopu). Takie zmienne musza byc volatile, aby JVM wiedziala ze nie moze ich ot tak sobie rzucac gdzie chce i cachowac.
Powodzenia.

Pozostało 580 znaków

2010-10-09 17:54

Rejestracja: 10 lat temu

Ostatnio: 6 lat temu

0
Wojtekss napisał(a)

Niestety po wcisnieciu przycisku Start petla sie wykonuje, rysuje ladne punkty jak nalezy

Myślę zatem, że błąd nie siedzi tam gdzie pisał ::., ale w kodzie, który podałeś.
Zauważ, że jeżeli piszesz:

int iloscElementow = ODane.length;
stop = true;
while(j<iloscElementow || stop ==true) { //swoją drogą, jeżeli stop jest boolean'em, nie musisz pisać stop==true, wystarczy same 'stop' (warunki przyjmują typy boolean)
    RysujPunkt(j);
    j++;
}

, gdy naciskasz przycisk STOP, i zmieniasz wartość zmiennej stop na false, pętla się wykonuje dalej, bo j<iloscElementow się zgadza, a operator || symbolizuje alternatywę (przynajmniej jedno zdanie musi być prawdziwe).

Jeżeli zamienisz || na && (alternatywę na koniunkcję), warunek będzie wymagał obydwu zdań poprawnych (skończy wykonywać pętle gdy j==iloscElementow LUB gdy stop!=true). Jednak czy o to Ci chodzi? Zauważmy, że program 'pójdzie dalej' i nie wróci już do tego while'a by zmiana stop na false (przyciskiem start) wznowiła rysowanie. Możesz to rozwiązać np. tak:

int iloscElementow = ODane.length;
stop = true;
while(j<iloscElementow) {
    if (stop) {
        RysujPunkt(j);
        j++;
    } else 
        try {Thread.sleep(10);} catch (Exception e){} //usypiasz watek na 10ms co każdego 'nieudanego if'a', jednocześnie program 'siedzi w while'u'.
}

pozdro

Pozostało 580 znaków

2010-10-09 18:16

Rejestracja: 14 lat temu

Ostatnio: 3 godziny temu

0

"Kropki" dobrze napisał - wykonywanie czegoś w EDT blokuje cały interfejs i nie da się niczego kliknąć. Swing nie jest wielowątkowy!!!

Billy:
Każde wystąpienie Thread.sleep() świadczy o źle napisanym kodzie. Do czekania na sygnał/ sprawdzania warunku można użyć np: java.util.concurrent.locks.Condition .


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.

Pozostało 580 znaków

::.
2010-10-09 18:25
::.
0

@Billy - nie dosc ze pizgasz kropki w petli w EDT, to jeszcze go usypiasz - swietny pomysl :-P
Co do tych warunkow stopu to tez masz pewnie racje, nie zglebialem.

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0