// This is supposed to show a modal dialog and then hide it again. In practice,
// this works about 75% of the time, and the other 25% of the time, the dialog
// stays visible.
// This is on Ubuntu 10.10, running:
// OpenJDK Runtime Environment (IcedTea6 1.9) (6b20-1.9-0ubuntu1)
// This always prints
// setVisible(true) about to happen
// setVisible(false) about to happen
// setVisible(false) has just happened
// even when the dialog stays visible.
package modalproblemdemo;
import java.awt.Frame;
import javax.swing.JDialog;
import javax.swing.SwingUtilities;
public class Main {
public static void main(String[] args) {
final Dialogs d = new Dialogs();
new Thread() {
@Override
public void run() {
d.show();
d.hide();
}
}.start();
}
static class Dialogs {
final JDialog dialog;
public Dialogs() {
dialog = new JDialog((Frame) null, "Hello World", /*modal*/ true);
dialog.setSize(400, 200);
}
public void show() {
SwingUtilities.invokeLater(new Runnable() { public void run() {
dialog.setLocationRelativeTo(null);
System.out.println("setVisible(true) about to happen");
dialog.setVisible(true);
}});
}
public void hide() {
SwingUtilities.invokeLater(new Runnable() { public void run() {
System.out.println("setVisible(false) about to happen");
dialog.setVisible(false);
System.out.println("setVisible(false) has just happened");
}});
}
}
}
Odpowiedz
Okazuje się, że to, co się dzieje, gdy pokazujemy()/setVisible (true) modalne okno dialogowe, że druga pętla ekspedycji zdarzeń jest uruchamiana w ramach wywołania show/setVisible. To ma sens, gdy tylko się o tym dowiesz. Mając to na uwadze, skończyło się z tym kodem:
public void runBlockingTask(final String taskName, final BlockingTask bt) {
SwingUtilities.invokeLater(new Runnable() { public void run() {
new Thread("Worker Thread: " + taskName) {
@Override
public void run() {
bt.run();
progressDialog.setVisible(false);
}
}.start();
}});
// NB This causes the event dispatch loop to be run inside this call,
// which is why we need to put everything after setVisible into an
// invokeLater.
progressDialog.setVisible(true);
}
+1 za udzielenie odpowiedzi na własne pytanie dwa lata później. Czy istnieje odznaka do poświęcenia? –
Jest to wyraźnie jakiś rodzaj wyścigu. Nie sądzę, żeby była tak prosta jak odpowiedź Ericka Robertsona. Dialogowy kod show()
jest dość skomplikowany, zawiera specjalną logikę do wywołania z wątku wysyłki zdarzeń, a także powoduje umieszczanie zdarzeń w kolejce zdarzeń. Być może kolejność, w której publikowane są zdarzenia, zależy od opóźnień wątków.
Być może potrzebne jest
Jak zauważyła Skip Head, funkcja invokeAndWait będzie blokować, dopóki okno dialogowe nie zostanie zamknięte.SwingUtilities.invokeAndWait()
, w ten sposób można zagwarantować, że
setVisible(true)
zakończyło wykonywanie przed wywołaniem
setVisible(false)
.
A dlaczego tak czy Ty potrzebujesz?
EDIT: To jest mój scenariusz tego, co się dzieje:
- zadzwonić d.show(), który księguje
setVisible(true)
wydarzenie - wątek jest umieścić więc spać przez scheduler i kopnięcia w EDT i rozpoczyna wykonywanie pierwsze wydarzenie
- EDT zostaje wyrzucony przed zakończeniem pierwszego zadania i opublikował faktyczne zdarzenie wyświetlające dialog, w którym wątek wykonuje d.hide(), która wysyła zdarzenie setVisible (false). Wątek jest zakończony i kopie EDT w
- EDT zakończyło pierwsze zadanie, umieszcza swoje zdarzenie pokazujące w kolejce zdarzeń
- Przechodzi do następnego zdarzenia, i, voila, jest to zdarzenie setVisible (false)!
- Przekazuje cały stan okna dialogowego i pozostaje widoczny i nie odpowiada.
EDIT2: Wygląda na to, że ProgressMonitor ma funkcjonalność, którą próbujesz zaimplementować.
InvokeAndWait w show() powoduje zablokowanie oczekiwania na zamknięcie modalnego okna dialogowego. Myślę, że właśnie tego Zarkonnen stara się unikać z wszystkimi dodatkowymi wątkami. –
@Skip Head: tak, masz rację. –
Potrzebuję go jako modalnego okna dialogowego "proszę czekać, przetwarzanie", aby poinformować użytkownika, że program jest zajęty. Musi to być modalne, aby powstrzymać użytkownika od kliknięcia przycisków, gdy program jest zajęty (ponieważ wtedy zarówno EDT, jak i wątek roboczy będą manipulować stanem). – Zarkonnen
Możesz spróbować otworzyć okno dialogowe zamiast ukryć je, ale wymagałoby to jego odbudowania, jeśli chcesz je ponownie wyświetlić.
Trochę czasu snu (100ms) między setVisible (prawdziwego) i setVisible (fałsz) rozwiązuje ten problem w niektórych przypadkach. zobacz także https://bugs.openjdk.java.net/browse/JDK-5109571 A gdy próbujesz użyć dispose zamiast setVisible (false), nie wydaje się, aby wystąpił warunek wyścigu
- 1. Okno dialogowe modulacji jQuery UI powinno zostać naprawione na przewijanie
- 2. Nie blokujące modalne okno dialogowe postępu Swing
- 3. okno dialogowe z systemem AndroidFragment "czasami" nie wyświetlający widoku sieciowego
- 4. Java Swing: okno dialogowe pozycjonujące na istniejącym oknie
- 5. Zamknij okno dialogowe kliknięcia (w dowolnym miejscu)
- 6. Android: Okno dialogowe/okno dialogowe operacji niespodziewanie znika
- 7. Animować niestandardowe okno dialogowe
- 8. Czasowe okno dialogowe niemodalne
- 9. Okno dialogowe potwierdzenia GWT
- 10. Typ/okno dialogowe WPF?
- 11. Okno dialogowe otwierania pliku
- 12. Okno dialogowe debugowania XCode
- 13. Pobierz okno dialogowe pliku
- 14. Okno dialogowe alertu WP7
- 15. okno dialogowe blendera wejściowego
- 16. Okno dialogowe Primefaces + commandButton
- 17. Wyszukaj okno dialogowe folderu
- 18. Android niestandardowe okno dialogowe
- 19. Okno dialogowe logowania PyQt
- 20. Okno dialogowe/wyskakujące okno z obrazem Androida
- 21. Okno wyskakujące w Java Swing
- 22. Okno dialogowe Android asyncTask Koło
- 23. Potwierdź okno dialogowe w angularjs
- 24. Okno dialogowe Bash nieznany tekst
- 25. jQuery Odroczone i okno dialogowe
- 26. C# Okno dialogowe komunikatu MessageBox
- 27. Niestandardowe okno dialogowe z RecyclerView
- 28. Okno dialogowe jqueryui do wyszarzenia
- 29. modalne okno dialogowe jquery onclick?
- 30. Niestandardowe okno dialogowe w C#?
Czy możesz uczynić dialog nie modalnym? Następnie możesz zamknąć go bez zakłócania wątków. –
Zobacz także: http://stackoverflow.com/questions/3886264/nonblocking-modal-swing-progress-dialog – Zarkonnen