Wstrzymanie procesu JavaFX

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.

@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;
            }
        };
    }
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 :).

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 :

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())?

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.

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?

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:

    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;

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.

0
Platform.runLater(new Runnable() {
    @Override
    public void run() {
        DOITytul.setText(tytul); //tutaj wyrzuca błąd
    }
});
0

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

0

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

0

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

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ść.

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ć. :)

 
    @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.

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