No to kilka błędów jakie robisz.
- Uruchamiasz setVisible jako pierwszą instrukcję. Nawet przed wywołaniem setLayout(), które powinno być jednym z pierwszych wywołań Swinga dla komponentu kontenerowego (takiego, który zawiera inne komponenty). SetVisible() zasadniczo powoduje tworzenie okna w systemie okien lub przeglądarki. Okno takie jest dość autonomiczne w stosunku do komponentów Swing, które nie są samymi oknami, a tylko ich logicznymi reprezentacjami w Javie/Swingu. Dużo trudniej jest manipulować już utworzonym obiektem systemu okien niż komponentem, który zostanie wyświetlony po tym jak wszystko zostanie w nim przygotowane.
2.setSize uruchamiasz po setVisible. Błąd podobny jak powyżej. Dodatkowo dla apletu setSize ma niewiele sensu ponieważ jego ułożenie i wielkość powinna być zasadniczo kontrolowana przez stronę html, a nie przez samego siebie - choć jest to możliwe, nie jest zbyt dobrą praktyką.
-
Tworzysz komponent przycisku i dodajesz go do komponentu rezystor - tyle, że to wcale nie oznacza, że dodajesz element graficzny przycisku do elementu graficznego apletu związanego z obiektem rezystor. Żeby tak się stało musiałbyś wykonać metodę revalidate(), albo invalidate() i validate() po sobie. Te wywołania aktualizują elementy graficzne związane z komponentami Swinga.
-
Podmieniając całą metodę paint() i wrzucając jako jedyne działanie tej procedury drukowanie obrazka likwidujesz możliwość odrysowania się elementów graficznych jakie są związane z komponentami dodanymi w tym aplecie - a to dlatego, że procedura ta domyślnie powoduje odrysowanie siebie, ramki i wszystkich zawartych w sobie komponentów*. Twoja wersja paint() tego nie robi. Dlatego widzisz tylko sam obrazek, a przycisk rysuje się z wielkim bólem dopiero jak wyślesz do niego komunikat najechania myszą (najeżdżając myszą:).
Powinieneś w celu zmiany tła przedefiniować procedurę paintComponent(), a nie paint().
*public void paint(Graphics g)
[...] This method actually delegates the work of painting to three protected methods: paintComponent, paintBorder, and paintChildren. They're called in the order listed to ensure that children appear on top of component itself.
- Wywołujesz metody Swing z wątku metody init() apletu, co nie oznacza wcale wątku Swing. Wszelkie wywołania metod komponentów Swing powinny byc zawarte w wywołaniu klasy implementującej interfejs Runnable() i przekazanej do wywołania metody invokeAndWait(). Normalnie dla Swing powinna to być invokeLater() - ale ponieważ wiele przeglądarek wysypuje się kiedy wątek procedury init() zakończy się przed pierwszym wywołaniem pętli zdarzeń Swing - dlatego nie wolno do tego dopuścić. Stąd wywołanie procedur inicjujących aplet musi być wywołaniem synchronicznym (powrócić ze sterowaniem do init() dopiero po wykonaniu żądanego do uruchomienia kodu).
Jest nawet gorzej niż wielu sądzi. Każda z 4 procedur: init, start, stop i destroy może być wywoływana w zupełnie innym wątku (choć nie musi) dlatego trzeba to uwzględniać. Aplet w naturalny sposób jest programem wielowątkowym. Aplet używający Swinga może mieć conajmniej 5 wątków. Aplikacja conajmniej 2 z czego jeżeli main() szybko się zakończy - staje się potencjalnie jednowątkowa.
Tak więc można powiedzieć, że niemal wszystko w tym krótkim kawałku kodu jest źle. Musiałbyś to poprawić. Możesz wyszukać na tym forum tematy ze słowem Swing i co nieco się dowiedzieć. Albo skorzystać z jakiegoś lepszego podręcznika do Javy (lub wreszcie go przeczytać:).