Utworzenie formularza za pomocą języka opisowego, takiego jak HTML, jest o wiele prostsze niż osiągnięcie tego samego efektu w Javie. Mimo to nawet początkujący programista może sobie poradzić.
Utworzenie formularza za pomocą języka opisowego, takiego jak HTML, jest o wiele prostsze niż osiągnięcie tego samego efektu w Javie. Mimo to nawet początkujący programista może sobie poradzić.
Zanim przejdziemy do konkretów dotyczących implementacji aplikacji z interfejsem graficznym w postaci formularza, omówimy dziedziczenie, ponieważ zrozumienie tego zagadnienia ma podstawowe znaczenie podczas pisania programów w języku
Java. Dziedziczenie w Javie polega na udostępnieniu określonej klasie (tzw. klasie potomnej) wszystkich właściwości i metod innej klasy (jeśli nie ograniczają tego modyfikatory dostępu).
Załóżmy, że mamy dane dwie klasy: klasę Flora i klasę Drzewo. Klasa Drzewo dziedziczy z klasy Flora, a więc może korzystać z dostarczonych przez nią właściwości i metod. Jednak oprócz tego klasa Drzewo może mieć także swoje właściwości i metody, z których klasa Flora nie będzie korzystać, bo dziedziczenie działa tylko w jedną stronę. Można powiedzieć, że klasa Drzewo rozszerza klasę Flora, bo ma nie tylko właściwości i metody klasy Flora, ale również własne zmienne składowe i metody.
Gdyby była jeszcze jedna klasa, Brzoza, dziedzicząca z klasy Drzewo, mogłaby korzystać z właściwości i metod swoich, klasy Drzewo i również klasy Flora, bo Drzewo dziedziczy z klasy Flora (rys. 1).
Jeśli chcemy zaimplementować określoną klasę dziedziczącą z innej klasy, musimy zastosować kluczowe słowo extends, znaczące dosłownie "rozszerza". Pamiętajmy, że klasa może dziedziczyć tylko z jednej klasy. Nie ma więc wielodziedziczenia, dopuszczanego w niektórych językach programowania. W przypadku klas Flora i Drzewo dziedziczenie moglibyśmy zapisać w następujący sposób:
class Drzewo extends Flora {
// implementacja klasy Drzewo
}
Dziedziczenie pomoże nam w utworzeniu programu działającego w środowisku graficznym. Do obsługi nowego programu wykorzystamy nie okno konsoli, jak poprzednio, lecz graficzny interfejs użytkownika (GUI).
Aplikacja okienkowa

Rysunek 1. Dziedziczenie klas w Javie.Obecnie większość programów wykorzystuje właśnie GUI do komunikacji z użytkownikiem. W Javie są dwie biblioteki do tworzenia programów wykorzystujących GUI: AWT (zawierająca m.in. pakiety
java.awt i java.awt.event) oraz SWING (zawierająca pakiety javax.swing, javax.swing.border i inne). Początkowo w Javie dostępna była jedynie biblioteka AWT (Abstract Window Toolkit). Służyła do tworzenia okien i innych elementów GUI oraz obsługi zdarzeń. Nie spełniła jednak wszystkich oczekiwań programistów, w związku z czym utworzono kolejną, bardziej dopracowaną bibliotekę SWING. Udostępnia ona elementy GUI dające większe możliwości i nie powoduje tylu błędów podczas uruchamiania aplikacji na różnych platformach, co AWT. Dlatego zaprzestaje się obecnie używania AWT na rzecz biblioteki SWING. Oczywiście API Javy udostępnia obie biblioteki, a część klas SWING dziedziczy z klas AWT. W naszym programie wykorzystamy zatem nowszą biblioteką SWING.

Rysunek 2. Pierwsza aplikacja okienkowa.Tworzenie aplikacji okienkowej rozpoczniemy od prostego przykładu programu, który wyświetla puste okno (rys. 2). Następnie uzupełnimy go o kontrolki graficzne (komponenty) i dodamy obsługę zdarzeń, żeby program mógł reagować na działania użytkownika. Początkowy kod naszego programu (Formularz.java) wygląda następująco:
import javax.swing.*;
public class Formularz {
public static void main(String[] args) {
Okno ok = new Okno();
ok.setDefaultCloseOperation(3);
ok.setVisible(true);
}
}
class Okno extends JFrame {
Okno() {
setSize(400,300);
}
}
Klasy reprezentujące komponenty zawarte w pakietach biblioteki SWING rozpoczynają się - w odróżnieniu od podobnych komponentów AWT - literą J. W naszym programie, korzystając z dziedziczenia, zaimplementowaliśmy klasę Okno, rozszerzającą klasę JFrame, która jest jedną z wielu wbudowanych klas Javy i znajduje się w pakiecie javax.swing (w AWT jej odpowiednikiem jest klasa Frame).
class Okno extends JFrame {... }
W poprzednim artykule wspomnieliśmy, że wszystkie wbudowane biblioteki Javy (a więc wszystkie klasy i interfejsy), z których korzystamy, implementując własne klasy, są niezbędne podczas kompilacji i uruchamiania programów. Klasy te uporządkowane są w strukturze podkatalogów zwanych pakietami (ang. package). Jednym z takich pakietów jest właśnie javax.swing, czyli katalog javax zawierający podkatalog swing, w którym z kolei umieszczona jest m.in. implementacja klasy JFrame. Aby móc w programie korzystać z właściwości i metod klasy JFrame, musimy dołączyć do niego odpowiedni pakiet. Służy do tego słowo kluczowe import, po którym wpisujemy nazwę pakietu (podkatalogi oddzielamy kropką, a dyrektywę kończymy średnikiem). Wszystkie importowane pakiety muszą być dołączone do programu przed implementacją klas. W naszym przykładzie zaimportowaliśmy całą zawartość pakietu javax.swing, o czym świadczą kropka i gwiazdka po jego nazwie. Daje to dostęp nie tylko do klasy JFrame, ale także do innych klas zawartych w tym pakiecie. Natomiast chcąc importować tylko określoną klasę, zamiast gwiazdki wpisujemy jej nazwę, np.:
import javax.swing.JFrame;
Jest również tzw. domyślny pakiet, importowany automatycznie, więc nie trzeba dołączać go do programu ręcznie. To pakiet java.lang, w którym znajduje się m.in. obsługa łańcuchów znaków, czyli klasa String. Bardzo dokładne informacje o wszystkich pakietach Javy znajdują się w dokumentacji Javy, która jest oddzielnym od SDK/JRE pakietem, dostępnym na stronie firmy Sun Microsystems.
Tworzenie okna

Rysunek 3: Program składa się z trzech podstawowych bloków.Program Formularz.java składa się z trzech zasadniczych części: importowania pakietów, implementacji klasy głównej oraz implementacji klasy Okno (rys. 3). Klasa główna w swojej metodzie main tworzy obiekt klasy Okno:
Okno ok = new Okno();
Klasa Okno, jako rozszerzenie klasy JFrame, może korzystać z jej właściwości i metod, dlatego dla utworzonego obiektu wywołujemy dwie metody pochodzące z klasy JFrame. Pierwsza, czyli setDefaultCloseOperation(), pobiera argument w postaci liczby całkowitej. Przekazanie jako parametru liczby 3 sprawi, że zamknięcie okna będzie powodować również zakończenie działania programu. Druga metoda - setVisible() - jest wywoływana z parametrem typu boolean, a więc jest wartością true lub false i ustawia widoczność okna. Musimy ją wywołać z parametrem true, ponieważ samo utworzenie okna wcale nie oznacza, że zostanie ono wyświetlone na ekranie. Metoda setVisible() pochodzi z klasy Component, z której pośrednio dziedziczy JFrame. Klasa Component pochodzi z kolei z bazowej klasy Object, od której pochodzą wszystkie klasy.
Podczas tworzenia okna ważne jest określenie jego rozmiaru. Służy do tego metoda setSize(), pobierająca dwie wartości typu całkowitego. Pierwsza określa szerokość, a druga wysokość okna w pikselach. Ustaliliśmy rozmiar okna na 400 pikseli szerokości i 300 pikseli wysokości - setSize(400,300).
Metody tej nie poprzedza zmienna referencyjna do obiektu, ponieważ jest wywoływana w konstruktorze klasy, której dotyczy. Gdybyśmy chcieli użyć tej metody w innej klasie w celu określenia rozmiaru innego, np. nowego okna, musielibyśmy utworzyć obiekt typu Okno i za jego pomocą wywołać omawianą metodę.
Okno inneokno = new Okno();
inneokno.setSize(400,300);