JProgressBar - brak płynnego przejścia

0

Witam, chcę dodać do GUI tworzonego w swingu - jProgressBara, który będzie płynnie pokazywał postęp wykonywania funkcji.

Kod po skróceniu (dla przejrzystości) wygląda tak:

public class GUI_DL extends JFrame implements ActionListener {

static JProgressBar pasek;

       	public GUI_DL()
	{
		pasek = new JProgressBar(1, 100);
		pasek.setBounds(623, 450, 280, 30);
		pasek.setVisible(true);
		add(pasek);
 	}

	public static void ustawPasek(int liczba2)
	{
		pasek.setValue(liczba2);
	}

	public void actionPerformed(ActionEvent e) {

	if(zrodlo==buttonLosuj)
		{
			  losowanie1.losuj();
		}

Druga klasa, której obiekt jest tworzony w tej pierwszej:

public class Losowanie {

  public void metoda1(int liczba)
        {
        	GUI_DL.ustawPasek(liczba);
        	
        }
        
        
        public void losuj()
        {
        		TRWA_LOSOWANIE=true;
								        do
								        {
								            licznik++;  
								            metoda1(licznik);

   //CIALO FUNKCJI

	}

A więc w skrócie - wywołuję metodę losuj() dla obiektu losowanie1, w której odbywa się ikrementacja licznika, który chcę przekazywać do JProgressBara jako parametr metodą setValue.
W tym celu w metodzie losuj() wywoływana jest przy każdym obiegu pętli metoda1(), która przekazuje licznik do metody ustawPasek() z klasy GUI_DL.

No i jest jeden problem, w trakcie trwania tej metody losuj() (trwa to kilkadziesiąt sekund) , JProgressBar nie uzupełnia się na bieżąco. Na starcie i w czasie trwania metody losuj() jest na 0, a po jej zakończeniu od razu na 100. Nie ma płynnego przejścia.
Całe te przekazywanie funkcjonuje chyba dobrze, bo gdy dam System.out.println(liczba2); w metodzie ustawPasek(liczba2) , to na bieżąco wyświetla aktualny licznik w konsoli.
Czyli wygląda to tak jakby problem był w: pasek.setValue(liczba2);

Co może być tego przyczyną? Z góry dziękuję za pomoc.

0

Zrobiłem testową wersję, w której wszystko odbywa się w jednej klasie, bez całego tego pokracznego przekazywania licznika, i dalej to samo.

Nie funkcjonuje coś takiego jak : długo wykonująca się pętla + korzystanie w jej środku z metody setValue();

Wykonywał ktoś kiedyś taki płynnie aktualizujący się pasek loading w javie, za pomocą JProgressBara?

1

Musisz obliczenia robić w osobnym wątku

new Thread( () -> {
obliczenia
}).start();

a ustawianie paska przez SwingUtilities.invokeLater( ()-> setValue(....)) );

0

Aha.
Nie wchodziłem jeszcze w ogóle w temat wielowątkowości, więc nie wiem za bardzo co do mnie mówisz :) Poczytam trochę o tej kwestii i spróbuję wykonać to co napisałeś.

Dzięki.

1

Swing ogólnie ma to do siebie, że powinien być używany w środowisku wielowątkowym - inaczej GUI będzie się blokować przy czasochłonnych operacjach.

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