JComponent oraz prosty Overlay

0

Witam!

Chciałbym zrobić rodzaj takiego overlaya na którym wyświetlałbym np pasek postępu jakiejś operacji. Miałoby to wyglądać w ten sposób, prze mam swoje kontrolki na JPanelu i przy wystartowaniu jakiejś operacji, cały JPanel "jakby" przygasał i wyświetla się progress.

Najprostszym (z pozodu) sposobem na to będzie rozszerzenie JPanel i przepisanie na nowo paint lub paintComponent w którym to najpierw wywołuje odpowiednią metodę z klasy bazowej (super.paint() lub super.paintComponent()) a nastepnie rysuje sobie wielki szary prostokąt w rozmiarach JPanelu z jakąś tam alfą. Ładnie to wygląda, faktycznie jest wrażenie cienia, jednak wszystkie kontrolki "pod spodem" odrysowują się przez co np, jeżeli klikam lub przejeżdżam nad JButtonem, wówczas następuje efekt mrugania na tej kontrolce(czyli raz się rysuje button raz "cień"). Jest to zdecydowanie niepożądane zjawisko. Jak moża by było je wyeliminować (blokada odrysowania kontrolek kiedy "cień" jest rysowany - prosta zmienna isRunning jeżeli tak to nie odrysowuj childów). Macie może inny pomysł na to?

Drugim sposobem, który właśnie zaimplementowałem, jest stworzenie przezroczystego okna dialogowego które dostosowuje się do rozmiarów i pozycji swojego "ownera". Nie jest już źle, widać tylko jak to się rozjeżdża podczas przesuwania okna, ale to można bardzo łatwo zlikwidować blokując przesuwanie w trybie "live" (czyli ze będzie widoczny tylko kontur okna a samo przesunięcie odbędzie się po puszczeniu przycisku). Pozostaje tylko kwestia powrotu do aplikacji oraz zmiany stanu z iconified itd. alwaysOnTop odpada, jako że, dialog jest widoczny nad innymi oknami. W tej chwili korzystam z toFront() jednak przekazuje to focus na dialog. Owszem, mogę go oddać głównemu oknie, jednak tworzy to brzydkie mrugania i wrażenie jakby coś nie działało jak powinno. Jakiś pomysł na bringToFront bez straty focusa? (to by generalnie stanowiło rozwiązanie mojego problemu)

Ostatnim sposobem który działa tak jak chcę, jednak jego obsługa jest dosyć skomplikowana (a przynajmniej tak mi dziwnie to to wyszło), że do każdego komponentu dopinam sterownik z osobnnym JPanelem, który to jest w odpowiednich momentach(i te odpowiednie momenty komplikują sprawę - chodzi tutaj o chowanie cienia kiedy np zmienimy karte w interface itd itp) podpinany jako GlassPane głównego okna. To już wygląda całkiem całkiem fajnie, jednak angażuje tysiące listenerów i komplikuje kod.

Any ideas ?

0

Najprostsze rozwiązania są dwa. Kontrolki "pod spodem" załatwiamy przez setEnable(false), dzięki czemu stają się wyszarzone i nie reagują na zdarzenia, a user również wie, że są w tym stanie niedostępne. A jeżeli efektu dodatkowego wyszarzenia/wyłączenia nie chcesz, to tuż przed wyświetleniem progresu "robisz zdjęcie" swojego panela za pomocą Robota, następnie wyłączasz wszystkie kontrolki, a dla painta podkładasz właśnie zrobione zdjęcie. Kontrolki wyglądają jak nówki nie śmigane, a jednocześnie na nic nie reagują.

Tej samej techniki używają loadery gier, które najpierw zrzucają do zdjęcia obraz całego ekranu i wyświetlają go przez czas ładowania kodu w fullscreenie, dzięki czemu żadne klikania czy inne dziwne działania usera nie dają efektu, a pulpit zachowuje się jakby był zamrożony.

0

Bardzo ciekawy pomysł z podstawianiem fotki.
Generalnie chciałbym "zautomatyzować" obsługę preloadera. Przygotowałem klase rozszerzającą panel, która posiada "wbudowany" komponent. Zadaniem takiego zestawu będzie wykrycie czy obecny panel się pokazał/ukrył i odpowiednio będzie pokazywał(setVisible) lub ukrywał komponent, a dodatkowo ustawiał owy komponent jako GlassPane głównej ramki. Korzystam do tego celu z ComponentListenera (implementuje ten interdejs w klasie rozszerzającej panel) i ustawiam na nim samego siebie (this.setComponentListener(this));
Czy wg Ciebie takie rozwiązanie będzie się trzymało kupy?
Programista jedynie będzie obsługiwał 2 metody start() stop() (preloadera) a z panelem będzie pracował jak z normalnym JPanel (komponent sam oragnizuje się tak, a by "cień" pokrywał tylko swój owner - w tym przypadku klase pochodną od JPanel'u)
Zadanie screenshot'a i podstawieni zlece do komponentu w glassPane(będzie rysował foto, a na nim rect i animacje).

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