JProgressBar- odświeżanie

0

Robiąc projekt z grafiki, nie mogłem poradzić sobie z odświeżaniem JProgressBar. Gdy wgrywam obrazek, a następnie uruchamiam dowolny filtr macierzowy (np. Blur), to postęp pracy algorytmu nie jest przedstawiany za pomocą niego(ProgressBar). A tworzę nowy wątek w metodzie algorytmu(381. linijka). Sam wątek pokazuje, że pracuje(484.), jednak setValue(int), repaint() nie działają. Co zrobić, aby działało?

src:

0

Nie wnikając w całą strukturę, JProgressBar jest komponentem swingowym, dlatego też operacje wykonywane na nim powinienec wykonywać w wątku swingowym. A Ty towrzysz zwykły wątek, w nim zmieniasz wartość progressa, natomiast Swing nie updatuje go ponieważ jest zapchany czasochłonnymi operacjami które masz w listenerach (czyli Twoje filtry) :)

Schemat rozwiązania powinien być inny, operacje filtrowania powinny lecieć w osobnych wątkach (nie Swingowych) aby nie zapychać GUI dla użytkownika, a update porgressBara powinien być w Swingowym (czyli SwingUtilities.invokeLater(new Runnable(..)); )

0

Niestety LukaStrz nie masz racji.

Metody setValue i repaint można uruchamiać w innych wątkach niż swingowe.
Metoda repaint jedynie zleca przerysowanie, a nie wykonuje je od razu. Rysowaniem zajmuje się wątek AWT.

Aby się o tym przekonać najłatwiej dopisać wypisywanie wątku:

progressBar=new JProgressBar(){
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		System.out.println("JProgressBar paint() thread=" + Thread.currentThread());
	}	
};
System.out.println("Invoking repaint thread=" + Thread.currentThread());
progressBar.repaint();

Rezultat:

Invoking repaint thread=Thread[Thread-3,6,main]
JProgressBar paint() thread=Thread[AWT-EventQueue-0,6,main]
Invoking repaint thread=Thread[Thread-3,6,main]
JProgressBar paint() thread=Thread[AWT-EventQueue-0,6,main]

Błąd natomiast jest gdzie indziej - metoda actionPerformed jest wykonywana przez wątek AWT i jeżeli będzie się ona długo wykonywać (tak, jak w tym przypadku), to trzeba wprowadzić dodatkowy wątek:

class MatrixFilterMenuItem extends JMenuItem{
	private static final long serialVersionUID = 1L;
	
	MatrixFilterMenuItem(String filterName,final int[][] matrix){
		super(filterName);
		addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				//wykonywane przez wątek AWT
				new Thread(){
					public void run() {
						matrixFilter(matrix);
					}}.start();
			}
		});
	}
}
0

Dodanie wątku rozwiązało problem. Wielkie dzięki!

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