NetBeans. "Code too large..."

0

Witam, mam kolejny problem z programem pisanym w NetBeans.
Robię aplikację do bazy danych - jest tam masa różnych jTextField, jPanel, jLabel do wprowadzania danych wrzucanych później do bazy (Postgres).
Program w którymś momencie zgłosił błąd: "Code too large in initComponents()". Czyżby było za dużo użytych komponentów? To jest w ogóle możliwe? NetBeans przecież sam automatycznie wszystkie nowe komponenty deklaruje w initComponents() i chyba nie bardzo mam na to wpływ..?
Bardzo proszę o pomoc, totalnie nie wiem co teraz z tym zrobić... :(

0

To chyba nie NetBeans zgłaszał, a konkretnie kompilator. Pliki .class mają pewne ograniczenia, sporo indeksów czy liczników wewnątrz takich plików ma rozmiar 16-bit. Dokładnie nie pamiętam jaka jest budowa pliku .class, ale może właśnie przekroczyłeś jakiś limit 65k instrukcji (bajtkodowych) na metodę.

Zapewne stosujesz dużo kopiuj wkleja. Kontrolki możesz generować dynamicznie, tzn stwórz sobie np listę kontrolek i forem je generuj.

Napisz jak długi masz ten kod i ile kontrolek na formie.

1

Dokładnie to co pisze Wibowit. Wielkość pojedynczej metody jest ograniczona do 64kb bytecodu, przy czym statyczne inicjalizatory są traktowane "jako jedna metoda". Visual z NB wyprodukował ci za dużą metodę initComponents, bo jest dość "mało mądry" (jak każdy visual). Musisz podzielić tą metodę na mniejsze.

Moja rada. W NB wejdź w edycję źródła do metody initComopnents(). Zaznacz jakiś fragment dotyczący inicjalizacji konkretnego komponentu (lub grupy) i następnie z menu Refactor wybierz Introduce Method. Nazwij nową metodę tak byś wiedział co się dzieje np initMyComponent.
W ten sposób postąp z każdym z komponentów. Metoda initComponents będzie wtedy tylko wywoływać kolejne małe metody inicjujące i problem zniknie.

0

Jeju, dziękuję za odpowiedzi. Mam niestety problem z Introduce Method. Wchodzę normalnie na panel z "Source", zaznaczam dla sprawdzenia 1 linię kodu w initComponents() (np. jPanel1 = new javax.swing.JPanel();) bądź kilka linii z rzędu (nie potrafię zaznaczyć wybiórczo np. wszystkiego co dotyczy jButton3, nie wiem jak zaznaczać poszczególne linie, Ctlr tu nie działa) i w Refactor wybieram Introduce Method, podaję jakąś nazwę i nic. Totalnie nic się nie dzieje. Co robię źle..?

0

Kod zaznaczasz jak zwykły tekst. Chyba, że NB blokuje edycję tej metody... i dal tego lubię visuale.

0

A może da się podzielić formę na małe panele? Co ty tam w ogóle masz? 500 JLabeli pod rząd? Takie coś można wygenerować w pętli przecież.

0

Jest sporo tego wszystkiego (jTextField i JLabel głównie). Jak to generować w pętli? W NetBeans korzystam z Design i wrzucam komponenty w program wklejając je z Palette i program sam to tworzy w initComponents(). Nie potrafię odblokować tej metody żeby cokolwiek tam ręcznie zrobić.

0

Ale to initComponents to jest chyba wywoływane z innej metody. Dopisz sobie własną metodę generującą kontrolki w pętli i wywołaj ją tuż obok wywołania initComponents().

Wrzuć zrzut ekranu z designera. Może twoje kontrolki nadają się do tego, aby je wepchnąć do tabeli?

0

Hm, kombinowanie teraz z tabelą to tak średnio widzę, mam to porozmieszczane w jPanelach z odpowiednimi Layoutami (tak się już przyzwyczaiłam do robienia, chwilowo za mało czasu na zabawę z tabelami, z których btw jeszcze niespecjalnie korzystałam).

Czyli po prostu mam stworzyć np. jakieś init() w którym potworzę sobie np same jTextField, i kolejny init() z samymi jLabel, ustawię od razu wszystkie parametry tych kontrolek w tych initach i wrzucę do Form żeby wywoływało to jako nowe metody? :) =ręcznie trzeba sobie potworzyć potrzebne komponenty? :)

A co jeszcze w przypadku kiedy już utworzę sobie np. jakieś jLabel i je wyświetlę i będę chciała zmienić jakieś jego parametry, np. nazwę czy cokolwiek innego, z poziomu "Design" - to będzie się automatycznie zapisywało w init() zawierającym deklarację tego jLabela?

Ps. Takie szybkie i banalne pewno pytanie - czy w tabelach można ustawiać komórkom odpowiedni border i blokować tekst żeby się nie dało go edytować? Bo jeśli tak to to w sumie może być lepsze niż męczenie się z panelami i wciskaniem do nich pól tekstowych i labeli...

0

ZTCP w tabeli możesz mieć wszystko o ile podmienisz renderer. http://download.oracle.com/javase/tutorial/uiswing/components/table.html

Mimo wszystko czuję, że masz skopany design. Trzeba nawciskać naprawdę dużo kontrolek, żeby się w 64k bytecodu nie zmieścić. Stawiam, że masz ich tam rzędu tysiąca kontrolek.

0

No, z tysiąc może i nie będzie, ale widzę, że same ustawienia każdego z komponentów zajmują masę miejsca w initComponent(). Kwestia tego, że mam 8 dużych paneli (z CardLayout), w panelach po kilka dodatkowych paneli do rozdzielenia pól tekstowych i labeli (których jest sporo, bo jest dużo danych do wprowadzenia). Miała to być forma formularzy i wygląda dobrze. Ale nie spodziewałam się, że będzie problem z pamięcią:/

Próbowałam wprowadzić nowe komponenty za pomocą utworzenia nowego initu, ale kiedy wchodzę w "Design" to program tych pól nie widzi, mimo, iż przypisałam je do odpowiednich paneli. Pewno przez to, że NB zapisuje te utworzone przez siebie komponenty jako prywatne i pewno czegoś nie zmieniłam na public. Wygląda na to, że to będzie masakrycznie czasochłonna zabawa...

0

Nie widzi ponieważ zapisuje sobie layout w pliku *.form . Możesz zrobić osobne JPanele, zedytować je za pomocą Matisse (czyli Swing GUI Builder z NetBeansa) a potem wkleić do głównej formy, za pomocą chociażby przeciągnij i upuść.

0

Utworzyłam nowe jPanel Form w projekcie i wrzuciłam do niego cały wcześniejszy panel ze znajdującymi się w nim komponentami. Zrobiłam z tego nowe Palette i wstawiłam to po prostu jako osobny nowy komponent do głównego jPanel w programie. Dodatkowo trzeba pola tekstowe, z których mają być pobierane dane, pozmieniać z private na public. I to w sumie tyle zabawy jak na razie. Liczę na to, że nie sprawi takie kombinowanie większych problemów w trakcie dalszego pisania...
Faktycznie kodu była masa. Wydaje mi się, że chyba dostatecznie odciążyłam tym główny program (?). To samo teraz zrobię z kolejnymi panelami, które mam w programie. Mam nadzieję, że to dobry sposób.
Czyli rozumiem, że ogólnie jest tak, że metoda nie może mieć więcej niż 64kb?

0

Nie wydaje mi się, żebyś odciążyła bo przecież ilość rzeczy jest taka sama.

Limit jest chyba 2^16 instrukcji bajtkodowych na metodę, a jedna linijka kodu javowego to średnio powiedzmy kilka - kilkanaście instrukcji bajtkodowych (zależy jaki kod zresztą i jakie długie są te linie).

0

No racja, że tyle samo. Ale hmm, coś było i tak na rzeczy bo program już nie wyrzuca tego błędu:)
Jak na razie śmiga i mimo przybywającego kodu nic dziwnego się nie dzieje:)
Dziękuję za wszelką pomoc!:)

0

Witam, pozwolicie się że się podepnę pod ten wątek, ponieważ mam podobny problem.
Moja aplikacja w initComponents() ma ponad 5 tysięcy linijek i podczas kompilacji wyskakuje "code too large".
Zrobiłem zgodnie z wieloma poradami osobną klasę z JPanelem. Przy pomocy drag-and-drop przypiąłem go do jTabbedPane znajdującego się w głównej klasie i wszystko jest ok, wszystko się wyświetla... poza najważniejsza rzeczą: danych w iTextFiield'ach.
Otóż moja aplikacja czerpie dane poprzez masterTable z serwera mysql. Wszelkie pola w głównej klasie są bindowanie do masterTable.
Ponieważ jeszcze nie jestem biegły w tej dziedzinie, nie wiem jak mogę zrobić bindowanie do tej samej masterTable z inne klasy niż ona się znajduje. Proszę o podpowiedź.

0

Najszybszy fix to podzielenie metody na wiele metod. W Javie jest ograniczenie wielkości metody na 64 KiB po skompilowaniu. Możesz mieć jednak wiele dużych metod w klasie.

0

Mówisz o metodzie private void initComponents()?
Ta jest w NetBeans nie do ruszenia - generowana automatycznie poprzez dodanie elementu z palety.
Chyba że mam tworzyć każdy element poprzez ręczne kodowanie w osobnej metodzie - próbowałem i tak chodzi, tylko przy setkach elementów w panelu każdy musi być poprawiany ręcznie, a nie w ciągu paru sekund w graficznym interfejsie.

0

Zbudowałeś potworka, w którym masz setki komponentów. Podziel go na mniejsze komponenty.

0
Koziołek napisał(a):

.... Podziel go na mniejsze komponenty.

To już wiem - jak pisałem - problem jest: jak?
Jeżeli mówimy o podziale metody initComponent() na wiele to jest to pracochłonne zadanie niestety be możliwości używania edytora graficznego później dla nowo powstałych paneli - a tego chciałbym uniknąć.

Dlatego wiem że jest możliwość zrobienia nowych paneli w osobnych klasach - to już, jak pisałem, działa bez problemu.
Problem jest jak mam bindować elementy z nowej z masterTable która siedzi w klasie głównej.

0

Chociażby za pomocą wzorca obserwator, Guava Event Bus, czy czegoś w tym rodzaju. Problem ma swoje źródło w sztywnym połączeniu pomiędzy komponentami.

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