Wstrzymanie procesu JavaFX

Wstrzymanie procesu JavaFX
M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Witam,
Chciałbym wstrzymać proces by wykonać inne zadanie w programie (aktualizację do bazy). Co zrobić by proces był kontynuowany po wykonaniu danej operacji? Poniżej przedstawiam fragment programu odpowiedzialnego za proces i wydobycie danych z pliku html. Przykładowo program pobiera dane z pliku, wstrzymuje proces pobierania, ładuje wydobyte dane do bazy i np po wciśnięciu przycisku z komunikatu o zaktualizowaniu danych proces pobierania jest kontynuowany.

Kopiuj
@FXML
    public void aktualizuj(){
        proces = aktualizujProces();
        proces.messageProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                System.out.println(newValue);
            }
        });
        new Thread(proces).start();        
    }
    public Task aktualizujProces(){ return new Task() {
            @Override
            protected Object call() throws Exception {
                    try { 
                        File dir = new File("Pliki");
                        Polaczenie lacz = new Polaczenie();
                        lista = lacz.LinkiDOI(imie, nazwisko);
                        int numer = 1;
                        try{
                           while(lista.next()){
                                ObservableList<String> row = FXCollections.observableArrayList();
                                for(int i = 1; i<=lista.getMetaData().getColumnCount();i++){
                                    row.add(lista.getString(i));
                                }
                                String ldoi = row.toString();
                                String doi = ldoi.substring(1, ldoi.length()-1);
                                if(dir.isDirectory()){
                                    String plik = "Pliki\\plik" + numer + imie + nazwisko + ".html";
                                    try{
                                        File daj_plik = new File(plik);
                                        Platform.runLater(new Runnable() {
                                            @Override
                                            public void run() {
                                            }
                                        });
                                            try{
                                                opis = null;
                                                Document doc = Jsoup.parse(daj_plik, "UTF-8", doi);
                                                Elements links = doc.select("meta");
                                                for (Element link : links) {
                                                    String description = link.attr("property");                      
                                                    if(linkHref.equals("description") || linkHref.equals("twitter:description") || description.equals("og:description"))
                                                        opis = linkText;
                                                }
                                                System.out.println("Opis: "+opis);
                                            }finally{
                                                daj_plik.deleteOnExit();
                                            }
                                    }catch(Exception e){
                                        System.out.println("Dane nie zostały znalezione");
                                    }
                                    numer++;
                                    updateProgress(numer-1, liczbaDOI);
                                    dir.deleteOnExit();
                                }else{System.out.println("Blad");}
                            }
                        }catch(Exception e){
                            System.out.println("Anulowano");
                        }
                    } catch (Exception e) { 
                        e.printStackTrace();
                    }
                System.out.println("Skończone.");
                proces.cancel(true);
                return true;
            }
        };
    }
edytowany 1x, ostatnio: matteo0092
azalut
offtop: szukam tego obrazka z dragonball'a a propos wcięć w kodzie, ale nie moge znaleźć :P poubieraj kod np. w krótkie metody bo ciężko się czyta
krzysiek050
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 4 lata
  • Postów:1272
0

Tak to się nie da. Nie można wstrzymać samemu ot tak procesu. Co gdyby zatrzymał się w chwili kiedy posiada jakąś blokadę, a do odblokowania potrzebna jest właśnie ta blokada? Deadlock murowany.

Jeżeli chcesz robić takie akcje to musisz posiadać obiekt który posiada stan tego co robisz i wie czy ma zostać przerwanym. Jeżeli chcesz zatrzymać task to ustawiasz flage na tym obiekcie setCancelled(true). Co każdą atomową (wg. ciebie) operację którą zrobisz, sprawdzasz czy flaga jest ustawiona i jeżeli tak to przerywasz pracę wątku i zachowujesz stan obiektu. W przypadku kontynuowania wątku resteujesz flagę cancelled na false i startujesz nowy task z stanem poprzedniego obiektu.

Ale często da się to obejść łatwiej. Skoro ładujesz tylko 1 plik i potem po załadowaniu do bazy danych od razu rzucasz komunikat, to równie dobrze dla każdego nowego ściąganego pliku tworzysz nowy task który to właśnie robi.

PS. Przychylam się do komentarza azaluta odnośnie refaktoru kodu. Jeżeli piszesz w eclipsie to polecam skrót ctrl+shift+m :).

M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

No rozumiem :) Gdy mam jeden plik to raczej to łatwo jest tylko problem pojawia się przy większych ilościach. Chodzi mi teraz o pobieranie danych, wszystko zależy od ilości rekordów w bazie jeśli jest jeden to super a jeśli jest kilka to pętla while tu w kodzie to :

Kopiuj
while(lista.next()) 

pobiera ostatni rekor z resultseta. krzysiek050 mówisz, że mogę zacząć nowy task do każdego pliku. Jak to zrobić by zachować kolejność wydobywania rekordów z bazy (lista.next())?

edytowany 1x, ostatnio: matteo0092
krzysiek050
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 4 lata
  • Postów:1272
0

Pobierasz listę wcześniej. Dostajesz listę plików a jako że 1 plik chcesz robić osobno to jest to niejako lista zadań. Sprawdzasz czy lista nie jest pusta i jeżeli nie, startujesz nowe zadanie.

M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Hmm a tą pobraną listę przypisuję do jakiejś zmiennej czy jak bo nie bardzo widzę jak to zrobić. Mógłbyś podać przykład?

M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Wczoraj siadłem jeszcze raz do tego problemu i mniej więcej działa. Ale teraz pojawił się kolejny problem przypisaniem zmiennej do labela. Wyrzuca mi NullPointerException. Gdy tytlko wymiszę na konsolę (System.out.println()) to działa bez problemu.

Oto kod:

Kopiuj
    public Task aktualizujRecznieProces(){ 
        return new Task() {
            @Override
            protected Object call() throws Exception {
                    try { 
                        File dir = new File("Pliki");
                        try{
                            while(doAktualizacji.next() && !done){
                                FutureTask<String> futureTask = new FutureTask(
                                        new Aktualizuj()
                                );
                                Platform.runLater(futureTask);
                                done = true;
                                ObservableList<String> row = FXCollections.observableArrayList();
                                for(int i = 1; i<=doAktualizacji.getMetaData().getColumnCount();i++){
                                    row.add(doAktualizacji.getString(i));
                                }
                                String doi = doAktualizacji.getString("ee_dblp");
                                System.out.println(doi + " " + numer);
                                if(dir.isDirectory()){
                                    String plik = "Pliki\\plik" + numer + imie + nazwisko + ".html";
                                    try{
                                        File daj_plik = new File(plik);
                                            try{
                                                tytul = null;
                                                Document doc = Jsoup.parse(daj_plik, "UTF-8", doi);
                                                Elements links = doc.select("meta");
                                                for (Element link : links) {
                                                    String str1,str2,cyfra;
                                                    String linkHref = link.attr("name");
                                                    String description = link.attr("property");
                                                    String linkText = link.attr("content");
                                                    if(linkHref.equals("citation_title"))
                                                        tytul = linkText; 
                                                }
                                                Platform.runLater(new Runnable() {
                                                    @Override
                                                    public void run() {
                                                        DOITytul.setText(tytul); //tutaj wyrzuca błąd
                                                    }
                                                });
                                            }finally{
                                                daj_plik.deleteOnExit();
                                            }
                                    }catch(Exception e){
                                        futureTask.cancel(true);
                                        System.out.println("Dane nie zostały znalezione");
                                    }
                                    numer++;
                                    updateProgress(numer-1, liczbaDOI);
                                    dir.deleteOnExit();
                                }else{System.out.println("Blad");}
                            }
                        }catch(Exception e){
                            System.out.println("Anulowano");
                        }
                    } catch (Exception e) { 
                        e.printStackTrace();
                    }
                System.out.println("Skończone.");
                proces.cancel(true);
                return true;
            }
        };
    }
    class Aktualizuj implements Callable {

        @Override
        public Object call() throws Exception {
            aktualizujDane.setOnAction(new EventHandler<ActionEvent>() {
                @Override 
                public void handle(ActionEvent t) {
                    try {
                        if(numer <= liczbaDOI+1){
                            okno();
                            System.out.println(numer+" "+ liczbaDOI);
                        }else{
                            okno1();
                            aktualizujDane.setVisible(false);
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(Dane.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
            return null;
        }
    }

Macie jakieś pomysły? Podkreślę, że błąd jest wyrzucany gdy while wykonuje się drugi raz tzn gdy wraca z klasy Aktualizuj;

krzysiek050
Napisz w której lini leci wyjątek. @Edit Postaraj się podzielić kod na mniejsze metody. Skrót w eclipse ctrl+shift+m.
M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at przegladarkalinkowdoi.Dane$10$1.run(Dane.java:845)

czyli coś jest nie tak z Runnable.

krzysiek050
A która to jest linia w tym kodzie?
M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0
Kopiuj
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        DOITytul.setText(tytul); //tutaj wyrzuca błąd
    }
});
krzysiek050
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 4 lata
  • Postów:1272
0

W takim razie nie w tym kodzie jest błąd.

M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Ale to dziwne bo tylko przy przypisaniu tekstu do labela tak jest bo gdy wypisuje na ekran to jest wszystko dobrze.

M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Ogólnie przy przipisywaniu do obiektów w oknie wyrzuca ten błąd

krzysiek050
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 4 lata
  • Postów:1272
0

DOITytul musi być polem klasy zewnętrznej i w momencie przypisania jest ustawiona na null.

Postaraj się dowiedzieć co się dzieje przy pomocy debuggera. Wtedy na żywo masz informacje jaka zmienna ma jaką wartość.

M0
  • Rejestracja:ponad 12 lat
  • Ostatnio:około 10 lat
  • Postów:24
0

Problem rozwiązałem w inny sposób. Przy użyciu przycisku, czyli nie w pełni automatycznie tak jak chciałem ale też może być. :)

Kopiuj
 
    @FXML
    public void aktualizujRecznie(){
        numer = 1;
        Polaczenie lacz = new Polaczenie();
        doAktualizacji = lacz.LinkiDOI(imie, nazwisko);
        proces = aktualizujRecznieProces();
        proces.messageProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                System.out.println(newValue);
            }
        });
        new Thread(proces).start();        
    }
    public Task aktualizujRecznieProces(){ 
        return new Task() {
            @Override
            protected Object call() throws Exception {
                    try { 
                        File dir = new File("Pliki");
                        try{
                            while(doAktualizacji.next() && !done){
                                done = true;
                                ObservableList<String> row = FXCollections.observableArrayList();
                                for(int i = 1; i<=doAktualizacji.getMetaData().getColumnCount();i++){
                                    row.add(doAktualizacji.getString(i));
                                }
                                String doi = doAktualizacji.getString("ee_dblp");
                                System.out.println(doi + " " + numer);
                                if(dir.isDirectory()){
                                    String plik = "Pliki\\plik" + numer + imie + nazwisko + ".html";
                                    try{
                                        File daj_plik = new File(plik);
                                            try{
                                                tytul = null;
                                                Document doc = Jsoup.parse(daj_plik, "UTF-8", doi);
                                                Elements links = doc.select("meta");
                                                for (Element link : links) {
                                                    String str1,str2,cyfra;
                                                    String linkHref = link.attr("name");
                                                    String description = link.attr("property");
                                                    String linkText = link.attr("content");
                                                    if(linkHref.equals("citation_title"))
                                                        tytul = linkText; 
                                                }

                                                Platform.runLater(new Runnable() {

                                                    @Override
                                                    public void run() {
                                                        try{
                                                        DOITytul.setText(tytulPOM);
                                                        }catch(Exception e){
                                                        }
                                                    }
                                                });
                                            }finally{
                                                daj_plik.deleteOnExit();
                                            }
                                    }catch(Exception e){
                                        System.out.println("Dane nie zostały znalezione");
                                    }
                                    numer++;
                                    tytulPOM = tytul;
                                    updateProgress(numer-1, liczbaDOI);
                                    dir.deleteOnExit();
                                }else{System.out.println("Blad");}
                            }
                        }catch(Exception e){
                            System.out.println("Anulowano");
                        }
                    } catch (Exception e) { 
                        e.printStackTrace();
                    }
                System.out.println("Skończone.");
                proces.cancel(true);
                return true;
            }
        };
    }
    @FXML
    public void Przypisz(){
        DOITytul.setText(tytulPOM);
    }
    @FXML
    public void Aktalizuj() {
        try {
            if(numer < liczbaDOI+1){
                okno();
                System.out.println(numer+" "+ liczbaDOI);
            }else{
                okno1();
            }
        } catch (IOException ex) {
            Logger.getLogger(Dane.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    @FXML
    public void AktualizacjaOK(ActionEvent event) throws SQLException{
        done = false;
        doAktualizacji.first();
        proces = aktualizujRecznieProces();
        proces.messageProperty().addListener(new ChangeListener<String>() {
            @Override
            public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
            }
        });
        new Thread(proces).start();    
        ((Node)event.getSource()).getScene().getWindow().hide();
    }

Stworzyłem przycisk, do którego przypisałem klasę Przypisz. Gdy go klikam labele się aktualizują i mogę kontynuować dalsze operacje.

edytowany 1x, ostatnio: matteo0092
M0
tytulPOM jest zmienna statyczną co pozwala nią operować między klasami
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)