🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.java
5 messages
5 total messages Started by Borneq Thu, 23 Jul 2015 11:23
Jak nie reagować na kliknięcie buttona w Swingu?
#154230
Author: Borneq
Date: Thu, 23 Jul 2015 11:23
18 lines
1556 bytes
Ma przycisk, którego naciśnięcie powoduje uruchomienie dość długiej 
procedury, tak z 5 sekund. Gdy kliknę na niego kilka razy szybko, 
procedura zostaje uruchamiana wielokrotnie od początku. Próbowałem 
setEnabled(false):
         buttonBench.addActionListener( new ActionListener()
	{
		public void actionPerformed(ActionEvent e)
		{
		    	buttonBench.setEnabled(false);
		    	if (originalName!=null)
		    		printBenchmarks(originalName);
		    	buttonBench.setEnabled(true);
		}
	});

ale coś się dzieje - gromadzi kliknięcia na zablokowanym przycisku i 
nadal jest źle. Może da się napisać klasę buttona dziedziczącą z JButton 
gdzie to było by poprawione?
Re: Jak nie reagować na kliknięcie buttona w Swingu?
#154231
Author: Piotr Rezmer
Date: Thu, 23 Jul 2015 12:02
16 lines
1507 bytes
W dniu 2015-07-23 o 13:23, Borneq pisze:
> Ma przycisk, którego naciśnięcie powoduje uruchomienie dość długiej
> procedury, tak z 5 sekund. Gdy kliknę na niego kilka razy szybko,
> procedura zostaje uruchamiana wielokrotnie od początku. Próbowałem
> setEnabled(false):

Jeśl deaktywowanie buttona nie działa tak jak oczekujesz, to przychodzą 
mi do głowy dwa rozwiązania:
A) użycie flagi którą sprawdzasz i ustawiasz wewnątrz ActionPerformed
B) przeniesienie długotrwałej operacji do oddzielnego wątku.


-- 
pozdrawiam
Piotr
XLR250&bmw_f650_dakar
Re: Jak nie reagować na kliknięcie buttona w Swingu?
#154232
Author: Borneq
Date: Thu, 23 Jul 2015 13:12
25 lines
2052 bytes
W dniu 2015-07-23 o 14:02, Piotr Rezmer pisze:
> Jeśl deaktywowanie buttona nie działa tak jak oczekujesz, to przychodzą
> mi do głowy dwa rozwiązania:
> A) użycie flagi którą sprawdzasz i ustawiasz wewnątrz ActionPerformed
> B) przeniesienie długotrwałej operacji do oddzielnego wątku.

To chyba co innego i chyba dlatego button nie działa tak jak powinien:
zrobiłem:
		public void actionPerformed(ActionEvent e) {
			if (duringOperation == false) {
				duringOperation = true;
				buttonBench.setEnabled(false);
				if (originalName != null)
					printBenchmarks(originalName);
				buttonBench.setEnabled(true);
				duringOperation = false;
			}
			}

to zabezpieczyło by przed zdarzeniami, które przyszły by podczas 
wielokrotnego wołania procedury roboczej. A tutaj jest jakieś 
kolejkowanie, nie wiem, jak bym tu zrobił runnable, to czy nie 
potworzyło by wielu wątków. Potrzebne jest coś w rodzaju globalnego 
czyszczenia zdarzeń kliku myszy. Ale to nie jest takie wazne, to tylko 
procedura porównująca algorytmy, najważniejsze siedzi w algorytmach.
Re: Jak nie reagować na kliknięcie buttona w Swingu?
#154234
Author: Pit
Date: Thu, 23 Jul 2015 13:14
35 lines
2219 bytes
Dnia 23.07.2015 Borneq <borneq@antyspam.hidden.pl> napisał/a:
> Ma przycisk, którego naciśnięcie powoduje uruchomienie dość długiej 
> procedury, tak z 5 sekund. Gdy kliknę na niego kilka razy szybko, 
> procedura zostaje uruchamiana wielokrotnie od początku. Próbowałem 
> setEnabled(false):
>          buttonBench.addActionListener( new ActionListener()
> 	{
> 		public void actionPerformed(ActionEvent e)
> 		{
> 		    	buttonBench.setEnabled(false);
> 		    	if (originalName!=null)
> 		    		printBenchmarks(originalName);
> 		    	buttonBench.setEnabled(true);
> 		}
> 	});
>
> ale coś się dzieje - gromadzi kliknięcia na zablokowanym przycisku i 
> nadal jest źle. Może da się napisać klasę buttona dziedziczącą z JButton 
> gdzie to było by poprawione?

Jeśli poczytasz API dla javax.swing.JComponent.setEnabled (boolean) , to
znajdziesz tam:
Note: Disabling a lightweight component does not prevent it from receiving
MouseEvents.
Wszyskie komponenty Swing są "lightweights" więc będą odbierać myszkę nawet
jeśli są wyłączone (z wszelkimi tego konsekwencjami), dlatego jeśli już
miałbym do tego podejść na Twój sposób, to bym to zrobił na zasadzie:

public void actionPerformed(ActionEvent e) {
  if(buttonBench.isEnabled()) {
    buttonBench.setEnabled(false);
    tu_akcja();
    buttonBench.setEnabled(true);
  }
}
Re: Jak nie reagować na kliknięcie buttona w Swingu?
#154233
Author: Borneq
Date: Thu, 23 Jul 2015 13:30
40 lines
2006 bytes
W dniu 2015-07-23 o 15:12, Borneq pisze:
> kolejkowanie, nie wiem, jak bym tu zrobił runnable, to czy nie
> potworzyło by wielu wątków. Potrzebne jest coś w rodzaju globalnego

Tak, w wątkach, ale przy sprawdzaniu terminated:
field:
BenchWorker worker

class BenchWorker extends SwingWorker<Integer, Integer> {
		String originalName;
		protected boolean terminated;

		BenchWorker(String name) {
			originalName = name;
			terminated = false;
		}

		@Override
		protected Integer doInBackground() throws Exception {
			if (originalName != null)
				printBenchmarks(originalName);
			terminated = true;
			return null;
		}
	}


   -------------------
	  buttonBench.addActionListener(new ActionListener() {
	      public void actionPerformed(ActionEvent e) {
		buttonBench.setEnabled(false);
		if (worker == null || worker.terminated == true) {
				worker = new BenchWorker(originalName);
					worker.execute();
				}
				buttonBench.setEnabled(true);
			}
		});

Działa!
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads