Kopiowanie panelu

0

Jak w javie mogę zawartość jednego panelu przekopiować do innego?

0

Co rozumiesz przez słowa "panel" i "zawartość panelu"?
Klasę dziedziczącą po JPanel i obiekt tej klasy?
Jeżeli tak, to taka klasa musiałaby również implementować interfejs Cloneable, aby móc stworzyć kopię istniejącego obiektu. Wtedy w kopii, czyli już innym obiekcie możesz modyfikować dane ustawione w obiekcie źródłowym. Tylko przy takim podejściu kopiowanie powinno być głębokie (czyli one również powinny implementować Cloneable lub być typami prostymi) dla elementów, które będą modyfikowane w kopii.
Problem w tym, że JPanel, ani żaden z jego przodków nie jest typu Cloneable, więc wszystkie standardowe cechy obiektu JPanel mogą być wspólne dla źródła i kopii. A to może skończyć się bardzo dziwnymi objawami lub błędami. W najlepszy razie zaraz po wykonaniu kopii powinno się ponownie ustawić w niej różne dane za pośrednictwem jej metod set[...]. Dlatego bezpieczniej jest tworzyć obiekty klas (dziedziczących po klasach Swinga) zawsze od początku (przez new), a specyficzne dla nich dane ustawiać przez własne metody set[...] lub za pomocą argumentów stworzonego w tym celu konstruktora.
Jeżeli nie o to Ci chodzi, to musisz doprecyzować pytanie.

0

W programie chcę zrobić przycisk reset. Zamiast zerować wszystkie wartości, chciałem zrobić coś takiego, żeby stworzyć nowy panel i zawartość tego nowego wstawić do aktualnie używanego.

0
lecter69 napisał(a)

stworzyć nowy panel i zawartość tego nowego wstawić do aktualnie używanego.

public void actionPerformed(ActionEvent e) //obsługa przycisku reset
{
	cp = getContentPane(); //pobiera panel "główny" okna
	cp.removeAll(); //usuwa wszystkie panele załadowane do contentPane (np. jeden:)
	aktualnyPanel = new MójPanel(aktualnyPanel); //nowy panel, przeklejenie do niego danych ze starego i od razu przypisanie referencji do roboczego panela
	cp.add(aktualnyPanel, BorderLayout.CENTER); //dodaje nowy nie śmigany panel
	//uwidocznienie zmiany
	cp.validate(); //uaktualnienie zmian w Swingu
	cp.repaint(); //jednokrotne odrysowanie po aktualizacji zmian w obiektach Swinga
}

Zakładając, że klasa MójPanel zawiera te dane, które chcesz zresetować i jest podstawowym panelem aplikacji, który zajmuje całość obszaru udostępnianego przez okienko JFrame. Jeżeli MójPanel ma konstruktor z parametrami, to musisz to uwzględnić i uzupełnić.
Nie wiem tylko po jakiego grzyba do nowego panelu kopiować dane ze starego, skoro chodzi o reset, czyli przywrócenie danych początkowych.

Po usunięciu referencji do poprzedniego egzemplarza obiektu MójPanel śmieciarka sama się nim zajmie i uprzątnie. Można też to ręcznie przyspieszyć, ale to kiedy indziej.
Można też zamieniać sam contentPane na nową wersję przez metodę setContentPane(). Będzie mniej bytów.

Jeżeli potrafisz sformułować co chcesz zrobić - to znaczy, że umiesz napisać program.

0

Dzięki bardzo. Nie chciałem kopiować starych danych, więc jedna linijka nie jest potrzebna. Swoją drogą, wczoraj jak to pisałem miałem coś podobnego, z tym że nie wiem czemu, ale tylko raz mogłem dokonać resetu.

0

Jednak pojawił się problem. Po wrzuceniu czystego panelu mogę na nim operować buttonami, ale nie mogę już na nim niczego robić korzystając z MenuBar. Jak mogę to poprawić (głównie chodzi o "Cofnij", a także "Zapisz" i "Otwórz")?

Kod: GraMain http://wklej.org/id/439991/
Kod: GraGUI http://wklej.org/id/439992/

Edit: static przy buttonach oraz przy klasie Panel rozwiązuje problem. A czy można to jeszcze jakoś inaczej zrobić?

0

W tym kodzie masz totalny chaos. To samo co robisz z pierwszym obiektem, którego referencję przypisujesz do zmiennej plansza powinieneś zrobić z obiektem, który przypisujesz tej samej zmiennej po resecie. Na przykład ustawienie setResizable(false) oraz co jeszcze ważniejsze - setVisible(true), a także ustalenie rozmiarów początkowych. To wszystko powinieneś zamknąć w osobnej metodzie prywatnej. To co Ci wcześniej podałem, to minimalny zestaw instrukcji potrzebny do przeresetowania obiektu, ale trzeba go uzupełnić o rzeczy, które sobie ustaliłeś przy tworzeniu nowej gry. Wiele rzeczy jest w Twoim kodzie zupełnie niepotrzebnych - takich jak np. "Container cp = new Container();". Może nie doczytałeś, ale zmienna taka jak Container cp jest prostym zazwyczaj 32-bitowym pojemnikiem na adres lub indeks obiektu. Nie różni się niczym od zmiennej wskaźnikowej. A to znaczy, że reprezentuje konkretny obiekt tylko od momentu przypisania obiektu, aż do zmiany wartości tej zmiennej. Nie można utożsamiać takiej zmiennej z obiektem. No chyba, że ma modyfikator final. Obiekty w javie nie mają nazw.

Co do innych rzeczy, to widzę, że w (action)Listenerach robisz rzeczy typowe dla gier i w swojej idei czasochłonne. Tak nie powinno się robić bo przez ten czas dosłownie zawieszasz działanie GUI. Klawisze się nie odrysowują, wciskanie w nie myszką nie daje żadnego efektu, jeżeli zostały wciśnięte, to nie są "wyciskane". Oprócz tego jeżeli coś ma jakiś czas trwać, to na ten czas wszelkie kontrolki należy wyłączać (dosłownie wygląda to jak wyszarzenie), aby użytkownik nie był w stanie na czymś operować (wysyłać kolejnych zdarzeń) w czasie gdy Twój program jest w trakcie obsługi poprzednich. Na razie jesteś początkujący, ale od tego jaki będziesz utrzymywał porządek w kodzie zależeć będzie jak będą działały Twoje programy. Tak samo powinieneś zapanować nad stylem kodu bo nawet tu jest pewien chaos. Nie wiadomo co należy do jakiej klasy, czyli co może zrobić obiekt takiej klasy. :)

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