10. Tworzenie graficznego łącza z użytkownikiem
10.1. Elementy biblioteki AWT i ich układacze
Graficzne łącze do współpracy z użytkownikiem programu (GUI - Graphical User's Interface) można łatwo zbudować za pomocą zestawu Abstrakcyjnych Narzędzi Okienkowych (AWT - Abstract Windowing Toolkit).
Elementy AWT (pakiet java.awt) tworzą hierarchię klas pokazaną na następnej stronie:
Składnik (Component) może być etykietą (Label), polem tekstowym (TextField), przyciskiem (Button) itp.;
Pojemnik (Container) jest składnikiem AWT, w którym mogą być umieszczane inne składniki;
Panel (Panel) jest pojemnikiem, którego zawartość można wyświetlić na ekranie (aplet jest szczególnym przypadkiem panelu);
Płótno (Canvas) jest miejscem na umieszczanie rysunków (na panelach też można rysować);
Okno (Window) może zawierać ramki, paski przewijania itp.;
Ramka (Frame) jest podstawowym składnikiem niezależnego okna.
Aby składnik AWT pojawił się na ekranie musimy najpierw stworzyć odpowiedni obiekt, a następnie dodać go do aktualnego pojemnika za pomocą metody add ( ). Na przykład, aby na aplecie pojawił się przycisk z napisem „Koniec”, inicjujemy aplet w taki sposób:
public void init ( ) {
Button b = new Button(”Koniec”);
add ( b );
Dodanie składnika AWT nie przesądza o jego pozycji względem pojemnika. Decyduje o tym aktualny układacz elementów (layout manager):
FlowLayout ( )
GridLayout ( )
BorderLayout ( )
CardLayout ( )
GridBagLayout ( )
Wyboru układacza dokonujemy za pomocą instrukcji
setLayout( new <nazwaUkładacza>
( <opcjonalne argumenty> ) );
Domyślnie stosowany jest układacz FlowLayout ( ), który układa składniki według kolejności dodawania centrując je w wierszach. Jako argumenty można podać inne sposoby wyrównania oraz odstępy poziome i pionowe, np.
setLayout ( new FlowLayout ( FlowLayout.LEFT, 30, 10 ) );
Układacz GridLayout pozwala określić wymiary tabeli, w której klatkach będą umieszczane kolejne składniki AWT:
setLayout ( new GridLayout ( 3, 2 ) );
Podając 2 dodatkowe argumenty możemy określić poziome i pionowe odstępy pomiędzy składnikami:
setLayout ( new GridLayout ( 3, 2, 10, 30 ) );
Układacz BorderLayout umieszcza 4 składniki na obrzeżu panelu, rezerwując dla każdego z nich jak najmniej miejsca. Piąty składnik zajmuje cały środkowy obszar panelu. Wybieramy ten rodzaj układacza przez zlecenie
setLayout ( new BorderLayout ( ) );
lub
setLayout ( new BorderLayout ( 10, 30 ) );
gdy chcemy ustalić odstępy. Natomiast w metodzie add ( ) musimy podać położenie każdego z dodawanych składników. Służą do tego napisy ”North”, ”East”, ”South”, ”West”, ”Center”, np.
add ( ”North”, new Button ( ”Jeden” ) );
Poniższy przykład ilustruje stosowanie prostych układaczy elementów.
Przykład
import java.awt.*;
public class Uklady extends java.applet.Applet {
public void init ( ) {
setBackground ( Color.blue );
// domyślny układacz FlowLayout
Panel p1 = new Panel ( );
p1.setBackground ( Color.green );
p1.add ( new Button ( "P11" ) );
p1.add ( new Button ( "P12" ) );
p1.add ( new Button ( "P13" ) );
p1.add ( new Button( "P14" ) );
add ( p1 );
// układacz GridLayout
Panel p2 = new Panel ( );
p2.setBackground ( Color.red );
p2.setLayout ( new GridLayout ( 2, 2, 10, 10) );
p2.add ( new Button ( "P21" ) );
p2.add ( new Button ( "P22" ) );
p2.add ( new Button ( "P23" ) );
p2.add ( new Button ( "P24" ) );
add ( p2 );
// układacz BorderLayout
Panel p3 = new Panel ( );
p3.setBackground ( Color.white );
p3.setLayout ( new BorderLayout ( 10, 10) );
p3.add ( "North", new Button ( "P31" ) );
p3.add ( "East", new Button ( "P32" ) );
p3.add ( "South", new Button ( "P33" ) );
p3.add ( "West", new Button ( "P34" ) );
p3.add ( "Center", new Button ( "P35" ) );
add ( p3 );
}
}
Układacz GridBagLayout ( ) daje największe możliwości, ale jest trudniejszy w użyciu. Elementy układamy za pomocą tego układacza na siatce prostokątnej, lecz w odróżnieniu od układacza GridLayout ( ) mogą one zajmować kilka klatek. Dodatkowo możemy wpływać na proporcje elementów.
Parametry sterujące umieszczeniem kolejnego elementu powinny być przekazane do następujących zmiennych instancyjnych obiektu klasy GridBagConstraints:
gridx, |
współrzędne elementu na siatce (klatka zajmowana przez lewy górny róg) |
gridwidth, |
liczba kolumn i wierszy zajmowanych przez element |
weightx, |
wagi wymiarów elementu |
Kolejność postępowania jest taka:
1) zgłaszamy ukladacz
GridBagLayout gbl = new GridBagLayout ( );
2) tworzymy obiekt pomocniczy
GridBagConstraints gbc = new GridBagConstraints ( );
I przekazujemy mu parametry elementu el.
3) kojarzymy ten obiekt z układaczem i elementem za pomocą metody
gbl.setConstraints ( el, gbc );
Przykład
Utworzymy łącze do komunikacji z użytkownikiem, które będzie zawierało 3 panele:
panel grafiki;
panel komunikatów;
panel przycisków.
Niech panele te mają być rozłożone w następujacy sposób:
h
import java.awt.*;
public class Przycisk1 extends java.applet.Applet {
Panel grafika;
Panel komunikaty;
Panel przyciski;
GridBagLayout gbl;
GridBagConstraints gbc;
static final int D = 10; // margines wewnętrzny
void buildConstraints ( GridBagConstraints gbc,
int gx, int gy, int gw, int gh,
int wx, int wy ) {
gbc.gridx = gx;
gbc.gridy = gy;
gbc.gridwidth = gw;
gbc.gridheight = gh;
gbc.weightx = wx;
gbc.weighty = wy;
}
public Insets getInsets ( ) {
return new Insets ( D, D, D, D );
}
public void init ( ) {
setBackground ( Color.lightGray );
gbl = new GridBagLayout ( );
gbc = new GridBagConstraints ( );
setLayout ( gbl );
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.CENTER;
buildConstraints ( gbc, 0, 0, 1, 1, 80, 80, D, D );
grafika = new Panel ( );
grafika.setBackground ( Color.yellow );
gbl.setConstraints ( grafika, gbc );
add ( grafika );
buildConstraints ( gbc, 0, 1, 2, 1, 100, 20, D, D );
komunikaty = new Panel ( );
komunikaty.setBackground ( Color.green );
gbl.setConstraints ( komunikaty, gbc );
add ( komunikaty );
buildConstraints ( gbc, 1, 0, 1, 1, 20, 80, D, D );
przyciski = new Panel ( );
przyciski.setBackground ( Color.blue );
gbl.setConstraints ( przyciski, gbc );
add ( przyciski );
przyciski.setLayout ( new GridLayout ( 3, 1, D, D ));
przyciski.add ( new Button ( "Open" ));
przyciski.add ( new Button ( "Close" ));
przyciski.add ( new Button ( "Exit" ));
}
}
10.2. Metody klasy Component
Wszystkie elementy biblioteki graficznej AWT są pochodnymi bazowej klasy Component. Można zatem stosować dla nich następujące metody tej klasy:
Metoda |
Działanie |
Color getBackground ( ) |
zwraca kolor tła |
void setBackground ( Color c ) |
wybiera kolor tła |
Color getForeground ( ) |
zwraca kolor pierwszego planu |
void setForeground ( Color c ) |
wybiera kolor pierwszego planu |
Font getFont ( ) |
zwraca czcionkę |
void setFont ( Font f ) |
wybiera czcionkę |
Dimension getSize ( ) |
zwraca wymiary |
void setSize ( Dimension d ) |
ustala wymiary |
Rectangle getBounds ( ) |
zwraca prostokąt okalający składnik |
void setBounds ( Rectangle r ) |
ustala prostokąt okalający składnik |
Point getLocation ( ) |
zwraca współrzędne składnika |
void setLocation ( Point p ) |
ustala współrzędne składnika |
int getX ( ) |
zwraca współrzędną x |
int getY ( ) |
zwraca współrzędną y |
boolean contains ( Point p ) |
sprawdza, czy dany punkt leży w obrębie składnika |
boolean isVisible ( ) |
sprawdza, czy składnik jest widoczny, gdy widoczny jest jego składnik nadrzędny |
boolean isShowing ( ) |
sprawdza, czy składnik jest widoczny |
void setVisible ( boolean b ) |
steruje widocznością składnika |
Graphics getGraphics ( ) |
zwraca graficzny kontekst składnika |
void paint ( Graphics g ) |
rysuje składnik |
void repaint ( ) |
wywołuje metodę update |
void update ( Graphics g ) |
wymazuje powierzchnię składnika i rysuje go na nowo metodą paint |
10.3. Dodatkowe elementy AWT
Etykieta (Label) jest napisem stosowanym do opisu innych elementów AWT. Napisy takie można tworzyć również metodą drawString, lecz musimy wówczas sami dbać o pozycjonowanie. Ustawianiem etykiet na ekranie zajmuje się układacz (LayoutManager).
Do tworzenia etykiet służą konstruktory:
Label ( ) |
tworzy pustą etykietę |
Label ( String s ) |
tworzy etykietę zawierającą napis s dosunięty w lewo |
Label ( String s, int align ) |
parametr align steruje ustawieniem napisu s |
Zamiast liczbowych wartości align lepiej stosować stałe:
Label.LEFT |
Label.RIGHT |
Label.CENTER |
Klasa Label udostępnia m.in. metody:
Metoda |
Działanie |
String getText ( ) |
zwraca napis na etykiecie |
void setText ( String s ) |
określa napis na etykiecie |
Dodatkowo dostępne sa wszystkie metody klasy bazowej Component, m.in. metoda setFont.
Pole wyboru (Checkbox) może znajdować się w jednym z dwóch stanów: wybrane (prawda) lub niewybrane (fałsz). W odróżnieniu od przycisków nie powodują one wykonania jakiejś akcji, lecz sterują wykonaniem programu.
Pola wyboru można tworzyć za pomocą konstruktorów:
Checkbox ( ) |
tworzy pole wyboru bez etykiety |
Checkbox ( String label ) |
tworzy pole wyboru z etykietą label |
Checkbox ( String label, boolean state ) |
dodatkowy parametr state określa stan początkowy pola wyboru |
Checkbox ( String label, boolean state, CheckboxGroup group ) |
dodatkowy parametr group określa grupę, do której należy dane pole wyboru |
Pojęcie grupy pól wyboru pozwala ograniczyć wybór do jednej opcji.
Klasa Checkbox zawiera m.in. takie metody:
Metoda |
Działanie |
String getLabel ( ) |
zwraca etykietę |
void setLabel ( String label ) |
określa etykietę |
CheckboxGroup getCheckboxGroup ( ) |
zwraca grupę |
|
|
void setCheckboxGroup |
ustala grupę |
boolean getState ( ) |
zwraca stan |
void setState ( boolean state ) |
ustala stan |
Dodatkowo w klasie CheckboxGroup mamy metody:
Metoda |
Działanie |
Checkbox getSelectedCheckbox ( ) |
zwraca wybrane pole |
void setSelectedCheckbox (Checkbox box ) |
określa wybrane pole |
Lista rozwijana (Choice) określa szereg opcji, z których tylko jedna może być wybrana. Można takie listy tworzyć za pomocą konstruktora Choice ( ). Następnie dodajemy elementy i dodajemy całość do apletu:
Choice c = new Choice ( );
c.add ( "Zielony" );
c.add ( "Czerwony" );
c.add ( "Niebieski" );
add ( c );
Metody klasy Choice:
Metoda |
Działanie |
String getItem ( int pos ) |
zwraca element umieszczony na pozycji pos |
int getItemCount ( ) |
zwraca liczbę elementów |
void select ( String s ) |
wybiera element o podanej nazwie |
void select ( int pos ) |
wybiera element na pozycji pos |
String getSelectedItem ( ) |
zwraca wybrany element |
int getSelectedIndex ( ) |
zwraca pozycję wybranego elementu |
Pole tekstowe (TextField) pozwala wprowadzać i modyfikować pojedynczy wiersz tekstu. Pole takie można utworzyć za pomocą jednego z konstruktorów:
TextField ( ) |
tworzy puste pole |
TextField ( int n ) |
tworzy puste pole o długości n znaków |
TextField ( String s ) |
tworzy nowe pole i wypełnia je napisem s |
TextField ( String s, int n ) |
tworzy nowe pole o długości n znaków i wypełnia je napisem s |
Najczęściej stosowane metody klasy TextField zawiera tabela:
Metoda |
Działanie |
String getText ( ) |
zwraca napis umieszczony w polu |
void setText ( String s ) |
ustala napis umieszczony w polu |
int getColumns ( ) |
zwraca wymiar pola |
void select ( int pos1, int pos2 ) |
wybiera część napisu między pozycjami pos1 i pos2 |
void selectAll ( ) |
wybiera cały napis |
boolean isEditable ( ) |
zwraca true, jeżeli napis można zmieniać |
void setEditable ( boolean e ) |
steruje dostępem do napisu |
char getEchoChar ( ) |
zwraca znak wyświetlany przy wczytywaniu napisu |
void setEchoChar ( char ch ) |
określa znak wyświetlany przy wczytywaniu napisu |
Przykład
import java.awt.*;
public class PoleTekstowe extends java.applet.Applet {
public void init ( ) {
setFont ( new Font ( "Helvetica",
Font.BOLD, 14 ) );
setLayout ( new GridLayout ( 3, 2, 5, 15 ) );
add ( new Label ( "Podaj swoje imie: " ) );
TextField t1 = new TextField ( " nieznane ", 45 );
t1.setFont ( new Font ( "Helvetica",
Font.ITALIC, 14 ) );
add ( t1 );
add ( new Label ( " Podaj numer telefonu: " ) );
TextField t2 = new TextField ( );
t2.setFont ( new Font ( "Helvetica",
Font.ITALIC, 14 ) );
add ( t2 );
add ( new Label ( "Podaj haslo: " ) );
TextField t3 = new TextField ( );
t3.setEchoChar ( '*' );
add ( t3 ) ;
}
}
Obszar tekstowy (TextArea) można tworzyć za pomocą konstruktorów:
TextArea ( ) |
tworzy pusty obszar tekstowy, którego wielkość ustali układacz elementów |
TextArea ( String s ) |
tworzy obszar tekstowy zawierający podany napis. Wielkość obszaru ustali układacz elementów |
TextArea ( String s, int r, int c ) |
tworzy obszar tekstowy o podanej liczbie kolumn i wierszy zawierający podany napis |
TextArea ( String s, int r, int c, int scroll ) |
dodatkowy parametr scroll określa sposób wyświetlania pasków przewijania |
Zamiast liczbowych wartości scroll lepiej stosować stałe:
TextArea.SCROLLBARS_BOTH |
TextArea.SCROLLBARS_HORIZONTAL_ONLY |
TextArea.SCROLLBARS_VERTICAL_ONLY |
TextArea.SCROLLBARS_NONE |
Przykład
import java.awt.*;
public class Obszar extends java.applet.Applet {
public void init ( ) {
String s = "\n" +
"On stracil dla niej rozum - \n" +
"ona dla niego cnote ... \n" +
"Niestety - \n" +
"potem rozum \n" +
"zjawil sie z powrotem.\n";
TextArea t = new TextArea ( );
t.setText ( s );
add ( t );
}
}
Pola i obszary tekstowe są pochodnymi klasy TextComponent. Metody ustawiania treści oraz zaznaczania fragmentów tekstu są zatem wspólne. Dodatkowo klasa TextArea udostępnia metody:
Metoda |
Działanie |
int getColumns ( ) |
zwraca szerokość obszaru jako liczbę znaków lub kolumn |
int getRows ( ) |
zwraca liczbę widocznych wierszy |
void insert ( String s, int pos ) |
wstawia napis s na pozycji pos |
void replace ( String s, int pos1, int pos2 ) |
zastępuje tekst pomiędzy pos1 i pos2 podanym tekstem s |
Lista jest grupą elementów, które można dowolnie zaznaczać. W klasie List są zdefiniowane takie konstruktory:
List ( ) |
tworzy pustą listę, na której można zaznaczyć jeden element |
List ( int n ) |
tworzy listę, na której jednocześnie widoczne jest n elementów |
List (int n, boolean sel ) |
dodatkowy parametr sel określa, czy można jednocześnie wybierać kilka elementów |
Po utworzeniu listy dodajemy do niej elementy metodą add ( String s ). Następnie dodajemy całą listę do składnika AWT, w którym ma być wyświetlana.
Przykład
import java.awt.*;
public class Lista extends java.applet.Applet {
public void init ( ) {
List lista = new List ( 5, true );
lista.add ( "Białystok" );
lista.add ( "Bielsko-Biała" );
lista.add ( "Katowice" );
lista.add ( "Kraków" );
lista.add ( "Poznań" );
lista.add ( "Siedlce" );
lista.add ( "Warszawa" );
add ( lista );
}
}
Poniżej przytaczamy niektóre metody klasy List:
Metoda |
Działanie |
String getItem ( int pos ) |
zwraca element umieszczony na pozycji pos |
String [ ] getItems ( ) |
zwraca wszystkie elementy w postaci tablicy |
int getItemCount ( ) |
zwraca liczbę elementów |
void select ( int pos ) |
wybiera element na pozycji pos |
void deselect ( int pos ) |
kasuje wybór tego elementu |
String getSelectedItem ( ) |
zwraca wybrany element |
String [ ] getSelectedItems ( ) |
zwraca wybrane elementy w postaci tablicy |
int getSelectedIndex ( ) |
zwraca pozycję wybranego elementu |
int [ ] getSelectedIndexes ( ) |
zwraca pozycje wybranych elementów w postaci tablicy |
Przewijany panel (ScrollPane) jest wygodnym sposobem na oszczędzanie miejsca na ekranie. Tworzymy go za pomocą jednego z dwóch konstruktorów:
ScrollPane ( ) |
tworzy nowy panel, do którego zostaną automatycznie dodane paski przewijania (w razie potrzeby) |
ScrollPane ( int scroll ) |
parametr scroll steruje sposobem prezentacji pasków przewijania |
Zamiast liczbowych wartości scroll lepiej stosować stałe:
ScrollPane.SCROLLBARS_ALWAYS |
ScrollPane.SCROLLBARS_AS_NEEDED |
ScrollPane.SCROLLBARS_NEVER |
Po utworzeniu przewijanego panelu dodajemy do niego jakiś składnik, np. zwykły panel. Następnie całość dodajemy do apletu:
ScrollPane pp = new ScrollPane ( );
Panel p = new Panel ( );
pp.add ( p );
add ( pp );
Adam Borkowski Język programowania „Java” 10−1
Adam Borkowski Język programowania „Java” 10−22
Applet
Textfield
Label
Frame
Panel
Window
Checkbox
Canvas
Button
Container
Component
Label
TextField
Panel
Applet
Label
TextField
Panel
Frame
EXIT
CLOSE
OPEN