JAVA 2: PROGRAMY Z GRAFICZNYM INTERFEJSEM UŻYTKOWNIKA 1. WSTĘP

Wielkość: px
Rozpocząć pokaz od strony:

Download "JAVA 2: PROGRAMY Z GRAFICZNYM INTERFEJSEM UŻYTKOWNIKA 1. WSTĘP"

Transkrypt

1 JAVA 2: PROGRAMY Z GRAFICZNYM INTERFEJSEM UŻYTKOWNIKA 1. WSTĘP Jest to wprowadzenie do pisania aplikacji GUI w języku Java przy użyciu interfejsu API Swing. Po przeczytaniu książki możesz pisać małe aplikacje z graficznym interfejsem użytkownika. Program z graficznym interfejsem użytkownika jest programem uruchamianym w oknie. Ponieważ w dużej mierze opiera się na zasadach programowania obiektowego. Kiedy jeszcze zdecydowałem się odnieść do tego tematu, to dlatego, że chcę móc pisać aplikacje, które są bardziej interesujące i lepiej pasują do programów spotykanych w życiu codziennym, niż to, co jest możliwe wyłącznie jako polecenia lub aplikacje konsolowe. Aby napisać program z graficznym interfejsem użytkownika, musisz pracować na podstawie szerokiego zakresu gotowych klas, na przykład klas, które tworzą i otwierają okno, klasy reprezentujące przycisk, klasy dla pola wejściowego itp. Jest to bardzo wiele klas i są montowane w API o nazwie Swing. W rzeczywistości klasy Swing oparte są na starszym API o nazwie AWT, więc istnieją dwa API, które musisz poznać, a każdy z nich ma kilka pakietów klas. Poniżej wezmę programy z graficznym interfejsem użytkownika dla programów GUI, w których GUI oznacza Graficzny Interfejs Użytkownika, i zacznę wyjaśniać, że nie można nauczyć się pisać aplikacji GUI, ucząc się wszystkich klas i ich metod. Zamiast tego musisz nauczyć się podstawowych zasad opracowywania tego rodzaju programów, a kiedy już się go nauczysz, nie będzie to takie trudne. Szybko zorientujesz się, co to jest, a pytanie brzmi, jak to się nazywa i co musisz napisać. Tutaj jednak istnieje tylko jeden sposób, a mianowicie pomoc, która na szczęście jest dostępna online, a także istnieje wiele innych źródeł w Internecie, które zawierają porady dotyczące rozwiązywania określonych problemów. Jest to bardzo odmienne od pisanie aplikacji konsolowych i natychmiast wydaje się, że musisz dużo pisać, ale szybko odkryjesz, że jest dużo powtórzeń i to samo musisz pisać za każdym razem. Dlatego, aby zredukować zadanie po napisaniu pierwszych programów i zmniejszyć pracę, możesz utworzyć własną bibliotekę klas z często używanymi metodami. Aplikacja GUI zazwyczaj składa się z kilku lub wielu klas, ale od początku możesz myśleć o każdym oknie jako klasie. Dodatkowo, dane, które program musi traktować, są zwykle również definiowane za pomocą klas, a być może będą również klasy które implementują logikę, która musi przetwarzać dane aplikacji. W związku z tym do pewnego stopnia zajmiemy się koncepcjami zorientowanymi obiektowo, ale odłożę wszystkie szczegóły na później. Nacisk kładziony jest na to, jak napisać aplikację GUI za pomocą Swinga, a przede wszystkim wykorzystam najbardziej podstawowe komponenty, a bardziej złożone komponenty zostaną opóźnione. Celem jest, aby po przeczytaniu tego tekstu i szczegółowej analizie powiązanych przykładów i rozwiązaniu powiązanych ćwiczeń i problemów powinieneś być w stanie napisać mniej programów GUI do praktycznego zastosowania 2 HELLO SWING Napiszę prosty program, ale tym razem program, który otwiera okno, w którym możesz wpisać nazwę. Po kliknięciu przycisku Dodaj wprowadzona nazwa zostanie dodana do pola listy i można wprowadzić nową nazwę. W dolnej części okna znajduje się również przycisk umożliwiający usunięcie zawartości pola listy.

2 Możesz przesunąć okno i możesz zmienić rozmiar okna. Kliknięcie prawym przyciskiem myszy na pasku tytułu powoduje wyświetlenie zwykłego menu i dwukrotne kliknięcie na pasku tytułu, okno maksymalizuje. Jeśli przez chwilę o tym pomyślisz, to naprawdę dużo może zrobić program. Dla napisania programu w NetBeans stworzyłem wspólny projekt, nazwałem projekt HelloSwing. Następnie dodałem do projektu klasę o nazwie MainWindow i jest to plik dla tej klasy, który zawiera cały kod: package helloswing; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MainWindow extends JFrame private JTextField txtname = new JTextField(); private JButton cmdadd = new JButton("Add"); private JButton cmdclr = new JButton("Clear"); private JList lstnames; private DefaultListModel model = new DefaultListModel(); public MainWindow() settitle("hello Swing"); setsize(500, 300); setdefaultcloseoperation(exit_on_close);

3 addlisteners(); createwindow(); setvisible(true); private void createwindow() add(createlabel(), BorderLayout.NORTH); add(createlabel(), BorderLayout.WEST); add(createlabel(), BorderLayout.EAST); add(createlabel(), BorderLayout.SOUTH); JPanel panel = new JPanel(new BorderLayout()); panel.add(createtop(), BorderLayout.NORTH); panel.add(createbottom(), BorderLayout.SOUTH); panel.add(createcenter()); add(panel); private JLabel createlabel() JLabel label = new JLabel(""); label.setpreferredsize(new Dimension(10, 10)); return label; private JPanel createtop() JPanel panel = new JPanel(new BorderLayout(10, 10)); JLabel label = new JLabel("Enter a name"); panel.add(label, BorderLayout.WEST); panel.add(cmdadd, BorderLayout.EAST); panel.add(txtname); return panel;

4 private JPanel createcenter() lstnames = new JList(model); JPanel panel = new JPanel(new BorderLayout()); panel.add(createlabel(), BorderLayout.NORTH); panel.add(createlabel(), BorderLayout.SOUTH); panel.add(new JScrollPane(lstNames)); return panel; private JPanel createbottom() JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); panel.add(cmdclr); return panel; private void addlisteners() cmdadd.addactionlistener(new AddAction()); cmdclr.addactionlistener(new ActionListener() public void actionperformed(actionevent e) model.clear(); ); class AddAction implements ActionListener public void actionperformed(actionevent e) String name = txtname.gettext().trim();

5 if (name.length() > 0) model.addelement(name); txtname.settext(""); txtname.requestfocus(); Wygląda niezaprzeczalnie jak wiele (jest 97 linii), a poniżej wyjaśnię, co to wszystko znaczy. Oczywiście nie można wiedzieć, że kod powinien zostać napisany w sposób pokazany powyżej, ale jeśli przejrzysz kod, możesz łatwo zrozumieć znaczenie większości. Istnieją trzy instrukcje importu, które importują trzy pakiety z klasami, dwa pakiety z interfejsu AWT API i jeden pakiet z interfejsu API Swing. Te instrukcje importu będą częścią dowolnego programu GUI i wszystkich klas, które definiują okna. Klasa nosi nazwę MainWindow i dziedziczy klasę JFrame. To jest klasa Swing, i jest to klasa, która definiuje wszystko, co jest konieczne do utworzenia okna i oferuje wszystkie usługi potrzebne do zdefiniowania zachowania okna. Okno to w zasadzie po prostu prostokątny obszar bez zawartości, ale może zawierać komponenty. Każdy komponent jest zdefiniowany przez klasę, w tym przypadku okno musi zawierać pole wejściowe, dwa przyciski i pole listy. Są one definiowane jako zmienne instancji na początku klasy. Pole wejściowe ma typ JTextField, przycisk typu JButton i pole listy typu JList. Wszystkie są klasami Swinga. Należy zauważyć, że pole listy nie jest tworzone, gdy zmienne są zdefiniowane, ale pozostałe trzy składniki są. Na koniec zdefiniowano zmienną ostatniej instancji typu DefaultListModel i wyjaśniono ją poniżej. Klasa ma konstruktor, który wykonuje następujące czynności: - definiuje tekst na pasku tytułu - określa rozmiar okna, który ma rozmiar okna po otwarciu - określa, że program powinien się zamknąć, gdy użytkownik kliknie krzyżyk na pasku tytułu - wywołuje metodę addlisteners (), która przypisuje funkcjonalność do przycisków okna - wywołuje metodę createwindow () umieszczającą komponenty w oknie - Zdefiniuj, że okno musi być wyświetlone na ekranie Klasa ma metodę o nazwie createlabel (), która tworzy pustą etykietę. Etykieta jest komponentem i ma typ JLabel i jest komponentem wyświetlającym tekst. W tym przypadku jest to pusty tekst, ale ważne jest to, że ma on rozmiar zdefiniowany za pomocą metody setpreferredsize (). Komponenty są umieszczane w oknie za pomocą menedżera układu, który jest obiektem, który określa rozmiar i położenie komponentu. Okno (to jest JFrame) ma domyślnie BorderLayout. Jest to menedżer układu, który dzieli okno na 5 obszarów i każdy obszar może zawierać składnik. Te pięć obszarów to 1. NORTH i ma zawsze taką samą szerokość jak okno, podczas gdy wysokość jest określona przez wysokość komponentu

6 2. SOUTH, i ma zawsze taką samą szerokość jak okno, podczas gdy wysokość jest określona przez wysokość elementu 3. WEST, wysokość jest wysokością okna, z wyjątkiem tego, co jest używane dla PÓŁNOC i POŁUDNIE, natomiast szerokość jest określona przez szerokość elementu 4. EAST, wysokość jest wysokością okna, z wyjątkiem tego, co jest używane dla PÓŁNOC i POŁUDNIE, a szerokość jest określona przez szerokość elementu 5. CENTER, czyli reszta okna Jeśli obszar jest pusty - nie ma w nim komponentu - nie ma on żadnego wpływu i jest zwinięty. Ważne jest, aby pamiętać, że BorderLayout może zawierać tylko 5 komponentów. Jeśli teraz przyjmiesz metodę createwindow (), zacznie ona używać metody createlabel (), aby umieścić komponent w każdym z czterech obszarów: PÓŁNOC, POŁUDNIE, ZACHÓD i WSCHÓD. Celem jest zdefiniowanie marginesu 10 odpowiadającego rozmiarowi komponentów, które są tworzone za pomocą metody createlabel (). Następnie metoda tworzy nowy komponent typu JPanel. Jest to komponent, który sam w sobie nie jest widoczny, ale ma menedżera układu (w tym przypadku BorderLayout) i może zawierać inne komponenty. Komponent nazywa się panelem, a ostatnia instrukcja w metodzie createwindow () umieszcza komponent CENTER w oknie. Przed wypełnieniem treści za pomocą trzech metod, wywoływanych odpowiednio createtop (), createcenter () i createbottom (). Jeśli zacznę od ostatniego, który tworzy JPanel z menedżerem FlowLayout. Jest to menedżer układu, w którym komponenty przepływają poziomo. W tym przypadku wskazałem, że komponenty muszą być wyrównane do prawej krawędzi. Po utworzeniu panelu dodaję jeden z dwóch przycisków (ten, który usuwa pole listy). W rezultacie uzyskujesz przycisk znajdujący się w prawym dolnym rogu okna, ale ze względu na dwie właściwości menedżerów układu, komponent będzie podążał za dolną i prawą krawędzią okna, gdy zmieni się rozmiar okna. Metoda createtop () tworzy komponent na górze, JPanel z etykietą po lewej, przycisk po prawej stronie i pole wprowadzania w środku. Trzy komponenty są umieszczane przez BorderLayout, gdzie pole wejściowe txtname jest umieszczone CENTER. Ponieważ obszar CENTRUM zawsze wypełnia to wszystko, jest wynikiem układu, że pole wejściowe zawsze wypełnia część panelu, która nie jest używana przez dwa pozostałe komponenty i tym samym dostosowuje się do szerokości okna. Należy pamiętać, że panel jest tworzony w następujący sposób: Panel JPanel = nowy JPanel (nowy BorderLayout (10, 10)); Tutaj określasz za pomocą parametrów konstruktora klasy BorderLayout, jaka powinna być wolna przestrzeń między komponentami. Metoda createcenter () tworzy pole listy. Gdy to zrobisz, przypiszesz pole listy do modelu danych - obiektu typu DefaultListModel - który musi zawierać dane, które powinny być wyświetlane w polu listy. Metoda tworzy JPanel z BorderLayout i przypisuje pustą etykietę NORTH i SOUTH, aby uzyskać trochę miejsca, odpowiednio na górze i na dole. Gdy pole listy znajduje się w panelu, jest ono uwięzione w JScrollPane, co pozwala na przewijanie zawartości. Wszystkie powyższe informacje dotyczą tylko sposobu tworzenia i projektowania okna. Należy zauważyć, że jest to stabilny projekt w tym sensie, że komponenty są zgodne z rozmiarem okna. Pozostaje tylko dołączyć funkcjonalność do dwóch przycisków. Gdy użytkownik kliknie przycisk, wywołuje zdarzenie. W szczególności oznacza to, że inne obiekty mogą zarejestrować się jako detektory dla tego zdarzenia, określając metodę z określonym sygnaturą. Ta metoda jest nazywana procedurą obsługi zdarzeń. Po kliknięciu przycisku sprawdzi, czy istnieją detektory, a jeśli tak, to je wywoła słuchacza. Spowoduje to wysłanie wiadomości do obiektów programu nasłuchującego, które powiedzą, że przycisk został kliknięty, a odbiorcy mogą coś zrobić. Powyżej znajduje się wewnętrzna zdefiniowana klasa, która jest po prostu klasą w obrębie innej klasy. Nazywa się AddAction i implementuje interfejs o nazwie ActionListener. Ten interfejs definiuje tylko jedną metodę o nazwie

7 actionperformed () i jest przykładem procedury obsługi zdarzeń. Powinien być połączony z przyciskiem Dodaj, tak jak to się dzieje w przypadku metody addactionlistener (). Procedura obsługi zdarzenia pobiera tekst z pola wejściowego, a jeśli tekst nie jest pusty, moduł obsługi aktualizuje model pola listy tekstem, a wynikiem jest, że wprowadzona nazwa pojawia się w polu listy. Następnie treść pola wejściowego jest usuwana, a na końcu pole jest ustawiane na ostrość, a pole wejściowe jest gotowe do wprowadzenia następnej nazwy. To, że klasa AddAction implementuje interfejs ActionListener, oznacza, że obiekt typu AddAction może być używany jako obiekt detektora dla przycisku. Zdarza się to w metodzie addlisteners () z następującą instrukcją: cmdadd.addactionlistener (new AddAction ()); cmdadd to nazwa przycisku, a klasa JButton (które są typu przycisku) mają metodę addactionlistener (), która może zarejestrować obiekt detektora. W rezultacie po kliknięciu przycisku Dodaj wykonywana jest metoda actionperformed () obiektu detektora. Należy zauważyć, że ta metoda może odnosić się do zmiennych instancji w klasie MainWindow. Jest to możliwe, ponieważ AddAction jest wewnętrzną klasą. Teraz musi być zrobione to samo dla drugiego przycisku, ale tym razem obsługa zdarzeń jest bardzo prosta, ponieważ sama musi usunąć zawartość modelu dla pola listy. Dlatego zamiast pisać nową klasę detektora dodałem obiekt detektora utworzony na podstawie anonimowej klasy: cmdclr.addactionlistener(new ActionListener() public void actionperformed(actionevent e) model.clear(); ); W tym momencie wystarczy zaakceptować składnię, ale cmdclear to nazwa przycisku, a ja używam jego metody addactionlistener () do powiązania obiektu detektora. To jest, jak wyjaśniono powyżej, obiekt implementujący interfejs ActionListener, a taki obiekt może być utworzony na podstawie anonimowej klasy o składni, jak pokazano powyżej. Można dyskutować o zaletach i wadach w odniesieniu do anonimowych klas, ponieważ mogą być trudne do zrozumienia i przeczytania, ale czy są to bardzo proste klasy - tak jak w tym przypadku - mogą być całkiem doskonałe. Teraz okno jest gotowe, ale nie jest to program sam w sobie. Musi zostać utworzony obiekt, którego typem jest MainWindow i powinien znajdować się w programie głównym: package helloswing; public class HelloSwing public static void main(string[] args) new MainWindow();

8 Następnie program jest gotowy i można go uruchomić. Jak już wspomniano, wiele się pisze, chociaż jest to bardzo prosty program, ale przykład przesadzony, częściowo dlatego, że tak samo dzieje się za każdym razem, a po drugie części kodu można zapisać prostszym. ĆWICZENIE 1 W tym ćwiczeniu należy wprowadzić pewne zmiany i ulepszenia do programu HelloSwing. Zacznij od utworzenia kopii i otwórz ją w NetBeans. W MainWindow znajduje się metoda o nazwie createlabel (), która służy do dodawania marginesów poza zawartością okna i do tworzenia odstępów między komponentami. Można to zrobić w inny sposób. Usuń tę metodę. Otrzymasz 6 instrukcji (które odnoszą się do tej metody), gdzie NetBeans zgłasza błąd. Usuń te 6 instrukcji. Jeśli następnie uruchomisz program, wynik będzie następujący: Aby zdefiniować marginesy, musisz dodać instrukcję importu: import javax.swing.border. *; Metodę createwindow () należy następnie zmienić na: private void createwindow() JPanel panel = new JPanel(new BorderLayout(0, 10)); panel.setborder(new EmptyBorder(10, 10, 10, 10)); panel.add(createtop(), BorderLayout.NORTH); panel.add(createbottom(), BorderLayout.SOUTH); panel.add(createcenter()); add(panel); Więc wszystko znowu będzie wyglądało dobrze. Następnie musisz dodać nowy przycisk na dole okna:

9 Robisz to w następujący sposób: 1. Utwórz nową instancję zmienną do przycisku, który możesz wywołać cmdcount 2. Dodaj przycisk (komponent) do okna w metodzie createbottom () Teraz okno powinno mieć inny przycisk. Dwa przyciski u dołu prawdopodobnie nie mają równych rozmiarów, ale ponieważ są one ułożone za pomocą FlowLayout, możesz zdefiniować ich rozmiar (w createbottom ()) w następujący sposób: cmdant.setpreferredsize (new Dimension (80, 27)); Przypisz przycisk Wyczyść o tym samym rozmiarze. Pozostaje tylko dołączyć akcję dla nowego przycisku. Po kliknięciu przycisku program musi otworzyć następujące okno komunikatu, które pokazuje, ile nazw zostało wprowadzonych: Zacznij od dodania kolejnej klasy wewnętrznej definiującej obiekt detektora: class CountAction implements ActionListener public void actionperformed(actionevent e) JOptionPane.showMessageDialog(MainWindow.this, "You have entered " + model.getsize() + " names", "Message", JOptionPane.INFORMATION_MESSAGE);

10 Oto showmessagedialog () to metoda statyczna w klasie JOptionPane, która otwiera okno komunikatu. Ma cztery parametry, w których wymagane są tylko pierwsze dwa. Pierwszy mówi, kto jest właścicielem skrzynki wiadomości, a następny - tekst do wyświetlenia. Trzeci to tekst na pasku tytułu, podczas gdy pozostałe wskazują ikonę, w której zostanie wyświetlone okno komunikatu. Po zdefiniowaniu tej klasy wystarczy tylko metoda addlisteners (), aby aplikacja była dostępna dla detektora zdarzeń za pomocą przycisku. Musisz dodać ostatnią zmianę do programu. Przycisk Wyczyść usuwa zawartość pola listy, ale bez ostrzeżenia, co w praktyce może być pechowe. Byłoby lepiej z ostrzeżeniem: Aby to dodać, należy zmienić procedurę obsługi zdarzenia dla przycisku Wyczyść, aby jego kod wyglądał następująco: if (JOptionPane.showConfirmDialog(MainWindow.this, "Are you sure you want to delete the list?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) model.clear(); ĆWICZENIE 2 Utwórz nowy projekt NetBeans, który możesz nazwać kalkulatorem. Powinieneś napisać program, który otwiera okno, jak pokazano poniżej: Okno ma dwa pola wprowadzania, w których należy wprowadzić liczby. Ponadto istnieją cztery przyciski - po jednym dla każdej z czterech operacji arytmetycznych. Po kliknięciu przycisku program powinien wstawić linię w polu listy, która pokazuje wyniki tego obliczenia. Jeśli wystąpi błąd, program po prostu wstawia komunikat o błędzie. Przycisk Wyczyść powinien działać w taki sam sposób, jak w pierwszym programie. Gdy rozmiar okna zostanie zmieniony, wszystkie przyciski muszą podążać za prawą krawędzią okna, podczas gdy dwa pola wejściowe będą wykorzystywały pozostałą przestrzeń

11 równomiernie. Jasne jest, że program jest podobny do HelloSwing, ale sugeruję, aby zacząć od zera i postępuj zgodnie z wytycznymi poniżej. Możesz oczywiście użyć HelloSwing, aby zobaczyć, jak powinny być napisane poszczególne instrukcje. 1) Dodaj nową klasę o nazwie MainWindow do projektu. Zacznij od wpisania następującego kodu: package calculator; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MainWindow extends JFrame public MainWindow() settitle("calculator"); setsize(500, 300); setdefaultcloseoperation(exit_on_close); setvisible(true); Następnie musisz edytować główną klasę, aby otworzyć okno: package calculator; public class RegneMaskine public static void main(string[] args) new MainWindow(); Przetestuj program. Powinno to otworzyć okno i jest to w pewnym sensie minimalny program GUI, ale mimo to program z oknem z paskiem tytułu, który można przesuwać na ekranie i zmieniać jego rozmiar. 2) Dodaj zmienne instancji do programu. Istnieje potrzeba 9 zmiennych: - dwa pola wejściowe, które powinieneś wywołać txtnum1 i txtnum2 - pięć przycisków o nazwach cmdadd, cmdsub, cmdmul, cmddiv i cmdclr - pole listy o nazwie lstres (nie możesz utworzyć obiektu, ale po prostu zdefiniuj zmienną) - model dla pola listy, a nazwa musi być modelem

12 Skompiluj program i uruchom go. Nie ma widocznych różnic, a to po to, aby upewnić się, że nie masz żadnych błędów składniowych. 3) Musisz następnie dodać metodę o nazwie createcenter (). Jest to zasadniczo ta sama metoda, co w ćwiczeniu 1, a zadaniem jest utworzenie listy i umieszczenie jej w JScollPane. Jedyna różnica polega na tym, że pole listy jest teraz nazywane czymś innym. Następnie dodaj metodę createwindow (), która tworzy komponenty okna: private void createwindow() JPanel panel = new JPanel(new BorderLayout(0, 10)); panel.setborder(new EmptyBorder(10, 10, 10, 10)); panel.add(createcenter()); add(panel); Należy pamiętać, że konieczne jest dodanie instrukcji importu import javax.swing.border. *; Powinieneś również wywołać metodę createwindow () z konstruktora. Uruchom program, wynikiem powinno być teraz otrzymanie okna z polem listy. 4) Dodaj metodę createbottom (). Musi to być ta sama metoda, co w programie HelloSwing, który dodaje przycisk Wyczyść do okna. Następnie należy dodać instrukcję do createwindow (), aby panel tworzący createbottom () tworzył na dole okna: private void createwindow() JPanel panel = new JPanel(new BorderLayout(0, 10)); panel.setborder(new EmptyBorder(10, 10, 10, 10)); panel.add(createbottom(), BorderLayout.SOUTH); panel.add(createcenter()); add(panel); Jeśli następnie uruchomisz program, wynik powinien wyglądać następująco:

13 5) Teraz musisz napisać kod na górnym panelu, co jest nieco trudniejsze. Zacznij od dodania następującej metody: private void initbutton(jbutton cmd) cmd.setpreferredsize(new Dimension(29, 29)); cmd.setfont(new Font("Liberation Sherif", Font.PLAIN, 16)); cmd.setmargin(new Insets(0, 0, 0, 0)); Posiada przycisk jako parametr i przypisuje przycisk o wielkości 29 29, definiuje czcionkę, przycisk powinien się stosować i usuwa margines wewnętrzny, ponieważ przycisk ma domyślnie. Następnie możesz dodać następującą metodę: private JPanel createright() JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0)); initbutton(cmdadd); initbutton(cmdsub); initbutton(cmdmul); initbutton(cmddiv); panel.add(cmdadd); panel.add(cmdsub); panel.add(cmdmul); panel.add(cmddiv); return panel;

14 Metoda wywołuje metodę initbutton () dla każdego z czterech przycisków obliczeniowych, a następnie umieszcza cztery przyciski w pliku JPanel za pomocą metody FlowLayout. W następnym kroku musisz utworzyć panel dla dwóch pól wejściowych: private JPanel createleft() JPanel panel = new JPanel(new GridLayout(1, 2, 10, 0)); panel.add(txtnum1); panel.add(txtnum2); return panel; Tutaj używam GridLayout. Jest to menedżer układu, który dzieli panel w kilku wierszach i kolumnach. Dzieli to panel w wielu komórkach, które mają ten sam rozmiar. W takim przypadku istnieje jeden rząd dwóch kolumn, w wyniku czego panel składa się z dwóch komórek, które zawsze będą tego samego rozmiaru. Dwa pola wejściowe zostaną dodane do panelu, a każde pole wypełni automatycznie komórka, w której się znajduje. Konstruktor obiektu GridLayout ma dwa dodatkowe parametry, które wskazują, ile miejsca powinno być między komórkami w poziomie i w pionie. Na koniec dodaj następującą metodę: private JPanel createtop() JPanel panel = new JPanel(new BorderLayout(10, 10)); panel.add(createright(), BorderLayout.EAST); panel.add(createleft()); return panel; Zwraca panel z BorderLayout. Do tego panelu dodawany jest panel z 4 przyciskami obliczeniowymi, więc znajduje się on po prawej stronie, a panel z dwoma polami wejściowymi, tak aby wykorzystał pozostałą przestrzeń. Jeśli następnie zastosujesz metodę createtop () w createwindow (), możesz dodać panel górny i projekt okna zostanie zakończony. 6) Pozostało tylko dołączenie programów obsługi zdarzeń do 5 przycisków. Zacznij od dodania następującej metody: private void calculate(char ch) try double tal1 = Double.parseDouble(txtTal1.getText()); double tal2 = Double.parseDouble(txtTal2.getText()); double res = 0; switch (ch)

15 case '+': res = tal1 + tal2; break; case '-': res = tal1 tal2; break; case '*': res = tal1 * tal2; break; case '/': res = tal1 / tal2; break; model.addelement(string.format("%f %s %f = %f", tal1, "" + ch, tal2, res)); catch (Exception ex) model.addelement(ex.tostring()); txttal1.settext(""); txttal2.settext(""); txttal1.requestfocus(); Ma parametr, który określa, jakie obliczenia należy wykonać. Metoda wykonuje obliczenia i wstawia linię do modelu dla pola listy. Ta metoda musi zostać wywołana z obsługi zdarzeń przycisków. Należy to zrobić w ten sam sposób, jak w programie HelloSwing, aby dodać metodę addlisteners (), która dodaje procedury obsługi zdarzeń dla przycisków, ale tym razem dla wszystkich 5 przycisków, z pomocą anonimowych klas. Pamiętaj, aby wywołać metody addlisteners () z konstruktora w MainWndow. Następnie program powinien zostać ukończony i może zostać przetestowany. 3 CZCIONKI I KOLORY Większość komponentów, które można wstawić do okna / panelu, wyświetla tekst i można zdefiniować czcionkę, której muszą używać. Podobnie możesz zdefiniować kolor tekstu, a na końcu możesz zdefiniować kolor tła. Program TextColor otwiera następujące okno: Jest to bardzo prosty program, który w rzeczywistości nic nie robi. Ma taką samą architekturę jak poprzednie programy, w których główna klasa otwiera okno, które w tym przypadku jest zdefiniowane następująco:

16 package textcolor; import java.awt.*; import javax.swing.*; public class MainWindow extends JFrame public MainWindow() settitle("font og farver"); setsize(500, 300); setdefaultcloseoperation(exit_on_close); setlocationrelativeto(null); createwindow(); setvisible(true); private void createwindow() add(createlabel("north", Color.blue, Color.white, new Font("Liberation Serif", Font.PLAIN, 24), 0, 30), BorderLayout.NORTH); add(createlabel("south", Color.green, Color.black, new Font("Liberation Serif", Font.BOLD, 36), 0, 50), BorderLayout.SOUTH); add(createlabel("west", Color.magenta, Color.black, new Font("Liberation Serif", Font.ITALIC, 18), 60, 0), BorderLayout.WEST); add(createlabel("east", Color.red, Color.white, new Font("Liberation Serif", Font.BOLD Font.ITALIC, 24), 60, 0), BorderLayout.EAST); add(createlabel("center", new Color(240, 240, 240), Color.pink, new Font("Liberation Serif", Font.BOLD, 96), 0, 0)); private JLabel createlabel(string text, Color bg, Color fg, Font font, int width, int height) JLabel label = new JLabel(text); label.setopaque(true); label.setbackground(bg); label.setforeground(fg); label.setfont(font); label.sethorizontalalignment(jlabel.center); label.setpreferredsize(new Dimension(width, height));

17 return label; Zacznę od metody createlabel (), która tworzy i zwraca komponent typu JLabel. Jest to komponent, który pokazuje tekst. Metoda ma 6 parametrów: - Pierwszy to tekst. - Następny jest kolor tła, który jest obiektem typu Kolor. - Trzeci to kolor pierwszego planu, a więc kolor tekstu. Jest to również obiekt typu Kolor. - Czwartym parametrem jest czcionka, która jest obiektem typu Font. - Ostatnie dwa parametry to odpowiednio szerokość i wysokość komponentu. Instrukcje metody są dość łatwe do wymyślenia, ale musisz ponownie zauważyć, jak zdefiniować rozmiar komponentu za pomocą metody setpreferredsize (). JLabel jest domyślnie wyświetlany z przezroczystym tłem i dlatego nie może mieć koloru tła, chyba że mówisz, że tło nie powinno być przezroczyste. Odbywa się to za pomocą setopaque (). Domyślnie okno ramek rodzi się z BorderLayout i można od razu dodać 5 komponentów, jak to ma miejsce w metodzie createwindow (). BorderLayout dzieli się tak, jak wspomniano o okno / panel w 5 obszarach, zwanych odpowiednio PÓŁNOCNYM, WSCHODNIM, POŁUDNIOWYM, ZACHODNIEM i CENTRUM, z tym ostatnim jako domyślnym. Każdy region może zawierać pojedynczy komponent, ale może również być pusty. Jeśli tak, obszar nie wypełnia niczego na ekranie. Jeśli obszar zawiera komponent, obowiązują następujące zasady dotyczące rozmiaru: - NORTH: Szerokość jest szerokością panelu, a wysokość jest określana na podstawie wysokości komponentu zdefiniowanej przez jego preferowany rozmiar. Szerokość składnika pod względem preferowanego rozmiaru jest ignorowana. - POŁUDNIE: szerokość jest szerokością panelu, a wysokość jest określana przez wysokość elementu zdefiniowaną przez jego preferowany rozmiar. Szerokość składnika pod względem preferowanego rozmiaru jest ignorowana. - ZACHÓD: Wysokość to wysokość panelu minus wysokość, która jest używana dla PÓŁNOC i POŁUDNIE, a szerokość jest określana przez szerokość elementu zdefiniowaną przez jego preferowany rozmiar. Wysokość składnika pod względem preferowanego rozmiaru jest ignorowana. - WSCHÓD: Wysokość to wysokość panelu minus wysokość, która jest używana dla PÓŁNOCNEGO i POŁUDNIOWEGO, a szerokość jest określana przez szerokość komponentu określoną przez jego preferowany rozmiar. Wysokość składnika pod względem preferowanego rozmiaru jest ignorowana. - CENTRUM: Szerokość to szerokość panelu minus szerokość używana przez ZACHÓD i WSCHÓD, a wysokość to wysokość panelu minus wysokość, która jest używana dla PÓŁNOC i POŁUDNIE. Preferowany rozmiar składnika jest ignorowany. W tym przypadku na panelu jest umieszczonych 5 komponentów JLabel, gdzie komponent jest tworzony za pomocą metody createlabel (). W tym miejscu należy zwrócić uwagę na to, jak zdefiniowany jest rozmiar, a wartości szerokości i wysokości, na których są ignorowane, są ustawione

18 na 0. Nie jest to konieczne i służy jedynie wyjaśnieniu, że wartości nie są używane. W przeciwnym razie zanotuj sposób definiowania kolorów i czcionek. Klasa Color ma wiele stałych dla często używanych kolorów, a większość kolorów w tym przykładzie jest oznaczona za pomocą tych kolorów. Kolory są definiowane za pomocą trzech intensywności koloru czerwonego, zielonego i niebieskiego, a także mówimy o tym kodowaniu kolorów jako kolorach RGB. Każda intensywność ma wartość od 0 do 255, a liczba możliwych kolorów to: = W tym miejscu należy zwrócić szczególną uwagę na ostatnie kodowanie, w którym ta sama wartość dla wszystkich intensywności zapewnia skalę szarości. W języku Java można zdefiniować kolor jako obiekt dla typu Kolor z intensywnością kolorów dla konstruktora. Jest używany w etykiecie, która znajduje się w środku okna, gdzie zdefiniowano następujący kolor: new Color(240, 240, 240) Oznacza to, że komponent będzie miał słabo szare tło. Zdefiniujesz czcionkę z nazwy czcionki, niezależnie od tego, czy powinna być normalna, pochyła, pogrubiona, czy może kombinacja dwóch ostatnich. Na koniec określasz rozmiar czcionki. Należy pamiętać, że tym razem program nie definiuje żadnej obsługi zdarzeń. Jest to oczywiście dlatego, że jest to prosty program demonstracyjny, a w praktyce programy GUI zawsze mają obsługę zdarzeń. Na koniec, w konstruktorze powinieneś zwrócić uwagę na stwierdzenie: setlocationrelativeto (null); Jest to instrukcja zapewniająca otwarcie okna na środku ekranu. ĆWICZENIE 3 Utwórz kopię programu TextColor. Powinieneś zmodyfikować 5 komponentów JLabel tak 1. Północ musi używać czcionki Liberation Sans, która jest pogrubiona i 16 punktów. 2. Południe musi mieć ciemnozielony kolor tekstu. 3. Zachód musi mieć szerokość na 100 i czcionkę na 48 punktów. 4. Wschód musi mieć standardowy żółty kolor tekstu. 5. Środek musi mieć jasnoszare tło i szary kolor tekstu 4 OKNA DIALOGOWE W powyższych przykładach za każdym razem jest to pojedyncze okno, ale w praktyce program GUI ma kilka lub wiele okien, aw tym rozdziale pokażę, jak z okna można otworzyć kolejne okno. Główne okno nazywa się oknem ramki i pochodzi z klasy JFrame. Innym oknem jest zwykle okno dialogowe, które jest klasą wywodzącą się z JDialog. Pokażę program, który ma trzy okna:

19 Oto MainView zwykłe okno ramki, które w tym przypadku musi mieć dwa przyciski, które służą do otwierania każdego z dwóch pozostałych okien: Okno po prawej jest przykładem okna dialogowego, w którym należy wpisać imię (imię i nazwisko): Musi to być okno dialogowe modalne, a to oznacza, że gdy okno dialogowe jest otwarte, inne okna aplikacji nie mają fokusu i nie można wchodzić w interakcje z innymi oknami przed zamknięciem tego okna dialogowego. Trzecie okno musi być również oknem dialogowym i musi pokazywać pole listy z wprowadzonymi nazwami (patrz poniżej), ale musi to być okno dialogowe bez modów, co oznacza, że inne okna mogą uzyskać fokus, gdy okno dialogowe jest otwarte. Okna dialogowe są zdefiniowane (prawie) w taki sam sposób jak okna ramek i jako takie nie ma nic nowego w programie, ale trzy okna muszą się komunikować, więc jeśli wpiszesz nazwę w oknie dialogowym powyżej, to okno dialogowe z pole listy musi zostać zaktualizowane o wprowadzoną nazwę.

20 Program powinien reprezentować nazwę jako obiekt, a do tego użyłem klasy Nazwa z programu Porównanie w książce Java 1. Klasa jest prosta i całkowicie niezmieniona, a zatem nie jest tu dalej omawiana. Zacznę od okna dialogowego do wpisania nazwy: package dialogs; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class EnterView extends JDialog private DefaultListModel model; private JTextField txtfirstname = new JTextField(); private JTextField txtlastname = new JTextField(); public EnterView(DefaultListModel model) super(null, "Enter a name", Dialog.ModalityType.APPLICATION_MODAL); this.model = model; setsize(400, 200); setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createview(); setvisible(true); private void createview() setlayout(new BorderLayout()); JPanel panel = new JPanel(new BorderLayout(0, 20)); panel.setborder(new EmptyBorder(20, 20, 20, 20)); panel.add(createtop(), BorderLayout.NORTH); panel.add(createbottom()); add(panel); private JPanel createtop() JPanel panel = new JPanel(new GridLayout(2, 1, 0,10)); panel.add(createline("first name", txtfirstname)); panel.add(createline("last name", txtlastname)); return panel;

21 private JPanel createbottom() JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); panel.add(createbutton("ok", 90, 25, this::ok)); panel.add(createspace()); panel.add(createbutton("close", 90, 25, this::close)); return panel; private JPanel createline(string text, JTextField field) JPanel panel = new JPanel(new BorderLayout()); JLabel label = new JLabel(text); label.setpreferredsize(new Dimension(90, 22)); panel.add(label, BorderLayout.WEST); panel.add(field); return panel; private JButton createbutton(string text, int width, int height, ActionListener listener) JButton cmd = new JButton(text); cmd.addactionlistener(listener); cmd.setpreferredsize(new Dimension(width, height)); return cmd; private JLabel createspace() JLabel label = new JLabel(); label.setpreferredsize(new Dimension(10, 20)); return label; private void clear() txtfirstname.settext(""); txtlastname.settext(""); txtfirstname.requestfocus(); private void ok(actionevent e)

22 String firstname = txtfirstname.gettext().trim(); String lastname = txtlastname.gettext().trim(); if (firstname.length() > 0 && lastname.length() > 0) model.addelement(new Name(firstname, lastname)); clear(); else JOptionPane.showMessageDialog(this, "You must enter both first name and last name", "Error", JOptionPane.WARNING_MESSAGE); private void close(actionevent e) dispose(); Klasa nazywa się EnterView, a pierwszą rzeczą do zapamiętania jest to, że klasa dziedziczy JDialog zamiast JFrame. Mówi się, że jest to okno dialogowe. Istnieją trzy zmienne instancji, dwa pola wejściowe i model pola listy. Może wydawać się to dziwne, ponieważ okno dialogowe nie zawiera pola listy, ale musi być używane do utrzymywania obiektów nazw, które mają być wyświetlane w drugim oknie dialogowym. Model jest wysyłany jako parametr w konstruktorze. Poza tym nie ma wiele nowych w konstruktorze, ale musisz zauważyć pierwszą linię, która jest miejscem, gdzie mówi się, że jest to modalne okno dialogowe, wysyłając parametr do konstruktora JDialog. Na koniec zanotuj instrukcję setdefaultcloseoperation (), która używa innego parametru, co oznacza, że po kliknięciu krzyżyka na pasku tytułu okno dialogowe musi zostać zamknięte, a program nie powinien się kończyć. Następnie istnieje metoda createview (), która inicjuje komponenty okna. Podobnie jak w innych przykładach, jest on rozproszony na kilka sposobów i jest z pewnością wystarczająco złożony, ale odwrotnie, nie ma wiele nowych w porównaniu do tego, co zostało wcześniej wspomniane. Należy jednak przeanalizować dane dotyczące sposobu definiowania interfejsu użytkownika, a w szczególności obserwować, co dzieje się z oknem po uruchomieniu programu i zmienić rozmiar okna. Istnieje jednak jedno miejsce, w którym dodano coś nowego. Okno dialogowe ma dwa przyciski i muszą mieć dołączone procedury obsługi zdarzeń. W poprzednich przykładach dołączyłem obsługę zdarzeń dla przycisków przy definiowaniu klas wewnętrznych lub przy definiowaniu klas anonimowych. Klasy wewnętrzne wymagają napisania dużo kodu, a anonimowe klasy skutkują kodem, który może być trudny do odczytania. Istnieją jednak alternatywy i w tym przykładzie użyłem prostego i czytelnego zapisu. Jeśli, na przykład, procedura obsługi zdarzenia dla przycisku Zamknij, nie będzie więcej instrukcji, które zamykają okno dialogowe. Robisz to za pomocą instrukcji dispose (), a ja dodałem następującą metodę: private void close(actionevent e)

23 dispose(); Tutaj należy zauważyć parametr, który jest tym, który mówi, że ta metoda może być używana jako procedura obsługi zdarzeń. Musi być dołączony do przycisku, który odbywa się w następujący sposób w metodzie createbottom (): this::close Łatwiej nie może być. Co dokładnie się dzieje, nie będę tutaj wyjaśniał, ale w zasadzie to, co się dzieje, to to, że kompilator automatycznie generuje kod, który zwykle piszę. Bardziej szczegółowe wyjaśnienie znajduje się w książce Java 4, ale notacja zwiększa czytelność tak bardzo, że zalecałbym rozpoczęcie przyjmowania go tak, jak jest i używanie go już. Istnieje podobny program obsługi zdarzeń dla drugiego przycisku. Jest to oczywiście szersze, ale wkrótce nastąpią następujące. Wprowadzone wartości są kopiowane do zmiennych z dwóch pól wejściowych. Jeśli zostanie wpisane coś dla imienia i nazwiska, zostanie utworzony obiekt Nazwa, a model zostanie zaktualizowany. Jeśli nie, okno komunikatu wyświetla komunikat o błędzie. Następnie jest inne okno dialogowe, pokazujące wprowadzone nazwy: package dialogs; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class ShowView extends JDialog private DefaultListModel model; private CloseListener listener; public ShowView(DefaultListModel model, CloseListener listener) super(null, "Names", Dialog.ModalityType.MODELESS); this.model = model; this.listener = listener; setsize(400, 500); setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); addwindowlistener(new ClosingHandler()); createview(); setvisible(true); private void createview() setlayout(new BorderLayout());

24 JPanel panel = new JPanel(new BorderLayout(0, 20)); panel.setborder(new EmptyBorder(20, 20, 20, 20)); panel.add(new JScrollPane(new JList(model))); panel.add(createbottom(), BorderLayout.SOUTH); add(panel); private JPanel createbottom() JPanel panel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); panel.add(createbutton("close", 90, 25, this::close)); return panel; private JButton createbutton(string text, int width, int height, ActionListener listener) JButton cmd = new JButton(text); cmd.addactionlistener(listener); cmd.setpreferredsize(new Dimension(width, height)); return cmd; private void close(actionevent e) listener.dialogclosed(); dispose(); class ClosingHandler extends WindowAdapter public void windowclosing(windowevent e) listener.dialogclosed(); Jest podobna klasa, która dziedziczy JDialog. Istnieją dwie zmienne instancji, z których pierwsza to model, a tym samym obiekty, które muszą być wyświetlane w polu listy, podczas gdy druga ma typ CloseListener. Wyjaśniam typ za chwilę, ale wartości dla obu zmiennych są wysyłane do konstruktora. W przeciwnym razie należy zwrócić uwagę tylko na to, że pierwsza linia określa, że jest to niemodalne okno dialogowe. Wygląd okna jest tym razem prosty, ponieważ wystarczy tylko umieścić pole listy i

25 przycisk. Przyciskowi przypisano obsługę zdarzeń o tej samej składni, jak wspomniano powyżej, ale powraca jedna komplikacja. Okno dialogowe otwiera się po kliknięciu przycisku w oknie głównym, a ponieważ jest to okno dialogowe, które nie jest niemodalne, można ponownie kliknąć przycisk i kilkakrotnie otworzyć okno dialogowe. Nie interesuje mnie to, ale odwrotnie, musi być możliwe ponowne otwarcie okna dialogowego, jeśli jest zamknięte. Dlatego konieczne jest wysłanie wiadomości z powrotem do głównego okna po zamknięciu okna dialogowego. Jak wspomniano, konstruktor ma parametr o nazwie detektor, który ma typ CloseListener. Jest to prosty interfejs zdefiniowany w tym samym pliku, co klasa MainView: interface CloseListener public void dialogclosed(); Interfejs nie ma nic poza zdefiniowaniem pojedynczej metody, ale gdy okno dialogowe konstruktora uzyskuje obiekt tego typu, okno dialogowe wie, że obiekt ma taką metodę, i może w ten sposób wysłać powiadomienie, gdy okno dialogowe zostanie zamknięte przez kliknięcie przycisk Zamknij: private void close(actionevent e) listener.dialogclosed(); dispose(); Teraz okno dialogowe można również zamknąć, klikając krzyżyk w tytule, aw tym przypadku wysyłając podobne powiadomienie. Konieczne jest zatem uchwycenie zdarzenia, które występuje po kliknięciu krzyżyka. Jest to WindowEvent i występuje w kilku kontekstach, ale powyżej pokazałem, jak go przechwycić klasą CloseHandler. Zwróć uwagę, że program obsługi musi być powiązany z oknem dialogowym, które dzieje się w konstruktorze: addwindowlistener (new ClosingHandler ()); Back to główne okno, w którym nie ma wiele do wyjaśnienia, ponieważ jest to zwykłe okno z dwoma przyciskami: package dialogs; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class MainView extends JFrame implements CloseListener private DefaultListModel model = new DefaultListModel(); private JButton cmdshow; public MainView()

26 settitle("dialogs"); setsize(200, 160); setresizable(false); setlocationrelativeto(null); setdefaultcloseoperation(exit_on_close); createwindow(); setvisible(true); private void createwindow() JPanel panel = new JPanel(new GridLayout(2, 1, 0, 20)); panel.setborder(new EmptyBorder(20, 20, 20, 20)); panel.add(createbutton("enter a name", this::openenter)); panel.add(cmdshow = createbutton("open list", this::openshow)); add(panel); private JButton createbutton(string text, ActionListener listener) JButton cmd = new JButton(text); cmd.addactionlistener(listener); return cmd; private void openenter(actionevent e) new EnterView(model); private void openshow(actionevent e) cmdshow.setenabled(false); new ShowView(model, this); public void dialogclosed() cmdshow.setenabled(true);

27 Istnieją dwie zmienne instancji, odpowiednio model pola listy i przycisk. Model jest wysyłany do obu okien dialogowych, a przycisk jest odnośnikiem do przycisku otwierającego okno dialogowe z listą. Należy zauważyć, że klasa implementuje interfejs CloseListener i dlatego musi zdefiniować metodę dialogowąclosed (). Po otwarciu okna dialogowego dla tej listy pojawiają się dwie rzeczy. Najpierw wyłącza przycisk, więc nie można ponownie otworzyć okna dialogowego, a następnie otwiera się okno dialogowe, wysyłając parametry jako model dla pola listy i odniesienie do samego okna, ale okno jest specjalnym obiektem zamykającym, dlatego może być używany jako aktualny parametr. W wyniku tego po zamknięciu okna dialogowego wywoływane jest okno dialogowe methodclosed (), które włącza przycisk, a okno dialogowe można ponownie otworzyć. Kiedy testujesz program, szczególnie zauważając, że jeśli utworzysz nazwę, to pole listy zostanie automatycznie zaktualizowane bez konieczności robienia czegokolwiek. Technika tego ukryta jest w klasie DefaultListModel. ĆWICZENIE 4 W tym ćwiczeniu należy wprowadzić pewne ulepszenia do powyższego programu. Rozpocznij od utworzenia kopii i otwórz kopię w NetBeans. Powinieneś zacząć dodawać kolejny przycisk do okna dialogowego ShowView, gdzie przycisk powinien usunąć zawartość pola listy. Ta zmiana nie powinna prowadzić do poważnych wyzwań. Następnie musi być taka, że jeśli klikniesz dwukrotnie nazwę w polu listy, wówczas okno dialogowe EnterView powinno zostać zainicjalizowane nazwą, która jest kliknięta, i powinieneś wtedy móc edytować nazwę. Jest to od razu nieco bardziej skomplikowane, ale możesz przejść następująco. Zmodyfikuj nazwę klasy, dlatego ustawiono metody dla obu zmiennych. Dodaj indeks parametrów do konstruktora w klasie EnterView: public EnterView(DefaultListModel model, int index) i zapisz wartość w zmiennej instancji. Jeśli wartość jest ujemna, oznacza to, że okno dialogowe jest używane do utworzenia nazwy, w przeciwnym razie indeks jest interpretowany jako indeks obiektu w edytowanym modelu. Zauważ, że zmiana oznacza, że konieczna jest zmiana klasy MainView, w której musisz dodać parametr (wartość -1), gdy otworzy się okno dialogowe EnterView. W klasie ShowView dodaj następującą klasę wewnętrzną: class MouseHandler extends MouseAdapter public void mouseclicked(mouseevent e) JList list = (JList)e.getSource(); if (e.getclickcount() == 2) int n = list.locationtoindex(e.getpoint()); JOptionPane.showMessageDialog(null, model.getelementat(n));

28 Definiuje procedurę obsługi zdarzeń dotyczącą kliknięć myszą i musi być połączona z polem listy, które można wykonać, zmieniając metodę createview (): JList list = new JList(model); list.addmouselistener(new MouseHandler()); panel.add(new JScrollPane(list)); Przed kontynuowaniem należy przetestować program. Utwórz kilka nazw i otwórz okno dialogowe z polem listy. Kliknij dwukrotnie nazwę i zobacz, czy pojawi się okno komunikatu z nazwą. Powoduje to, że wszystko zależy od dwukrotnego kliknięcia w miejscu. Powyższa procedura obsługi zdarzeń dla myszy powinna teraz zostać zmieniona, aby nie otwierać okna komunikatu, ale zamiast tego otwiera się EnterView, gdzie ostatnim parametrem jest teraz indeks dwukrotnego kliknięcia nazwy. EnterView powinien pokazać nazwę, a w tym celu zmienić metodę createtop (), aby zainicjowała pola wejściowe z podwójnie klikniętą nazwą. Pamiętaj, że indeks zmiennej jest indeksem obiektu Nazwa względem modelu. Po kliknięciu przycisku OK nie należy tworzyć nowego obiektu Nazwa, ale kliknięty obiekt musi zostać zaktualizowany. Konieczna jest zatem modyfikacja procedury obsługi zdarzenia OK (), tak aby (przy użyciu indeksu zmiennych) rozróżniała dwa przypadki: miejsce utworzenia nowego obiektu oraz miejsce edycji istniejącego obiektu. Po wprowadzeniu tych zmian okaże się, że pole listy nie wydaje się być aktualizowane, ale zamknij okno dialogowe ShowView i otwórz je ponownie, a zobaczysz, że zmiany są widoczne, więc model został zaktualizowany. Aby rozwiązać ten problem, musisz dodać następującą klasę do pliku z głównym oknem: class EnhancedListModel extends DefaultListModel public void update(int index) firecontentschanged(this, index, index); Jest to klasa, która rozszerza DefaultListModel o nową metodę. Musisz również zmienić definicję modelu w MainView: private DefaultListModel model = new EnhancedListModel(); Nowa metoda w modelu musi zostać wywołana w procedurze obsługi zdarzenia OK () w klasie EnterView po zaktualizowaniu obiektu: ((EnhancedListModel) model).update (indeks); Zwróć uwagę na typecast. Następnie pole listy zostanie poprawnie zaktualizowane. Musisz dodać jedno ostatnie ulepszenie. Okno dialogowe EnterView musi mieć dodatkowy przycisk do usunięcia edytowanego obiektu, ale przycisk musi być włączony tylko wtedy, gdy okno dialogowe służy do edycji Name 5 WIĘCEJ KOMPONENTÓW

29 W tej sekcji pokażę przykład, że w zasadzie jest podobny do pierwszych przykładów, gdzie program składa się z pojedynczego okna, ale jest to nieco bardziej złożony przykład: 1. Istnieje kilka komponentów zarówno pod względem liczby komponentów, jak i rodzaju komponentów 2. Jest to przykład złożonego układu 3. Istnieje kompleksowe zarządzanie wydarzeniami Jeśli uruchomisz program, otworzy się następujące okno: Okno powinno zilustrować znak z tekstem. Następnie możesz użyć innych składników okna, aby dostosować sposób wyświetlania znaku: - czcionka użyta do narysowania tekstu - w jaki sposób tekst jest wyrównany (w lewo, w prawo lub w środku) - kolor używany do narysowania tekstu - kolor tła do znaku W porównaniu do pierwszych przykładów, w tym przykładzie zastosowano więcej rodzajów komponentów: - JLabel, który jest komponentem pokazującym tekst i został użyty w poprzednich przykładach - JTextField, które jest polem wejściowym i jest również używane w poprzednich przykładach - JComboBox, który jest komponentem z listą obiektów, i możesz wybrać jeden z tych obiektów

30 - JCheckBox, który jest prostym komponentem, w którym można wybrać właściwość - JRadioButton, w którym kilka elementów jest zorganizowanych w grupę, więc możesz wybrać jedną z nich - JSlider, który jest komponentem, w którym za pomocą "pędów" można wybrać wartość w zakresie Jeśli na dodatek dodajesz komponenty JButton i JList, które są używane w poprzednich przykładach, ale nie są używane w tym przykładzie, faktycznie spotkałeś większość podstawowych komponentów Swing, a w praktyce osiągniesz daleko z tymi komponentami. Następnie jest kod programu, który jest obszerny z prawie 350 liniami. Zamiast pokazać razem kod, pokażę części w związku z opisem poszczególnych pojęć. Zaleca się otworzenie pełnego kodu podczas czytania poniższych instrukcji. Zacznę od układu, który tym razem jest dość złożony. Powinieneś uruchomić aplikację i zauważyć, jak niektóre składniki zmieniają swoje rozmiary wraz ze zmianami rozmiaru okna. Rozmiar i lokalizacja komponentów są określane przez używany menedżer układu i jest on przedmiotem następnego rozdziału, ale na razie wspomniałem o trzech menedżerach układów - BorderLayout - FlowLayout - GridLayout i wszystkie są używane w tym przykładzie. Używając zagnieżdżonych menedżerów layoutów, czyli posiadających panele w sobie nawzajem z własnymi menedżerami układów, można faktycznie za pomocą powyższych trzech menedżerów układu zaprojektować raczej skomplikowany układ. Punkt początkowy jest podobny do poprzednich przykładów i rozpoczyna się następującą metodą: private void createwindow() JPanel panel = new JPanel(new BorderLayout()); panel.setborder(new EmptyBorder(10, 10, 10, 10)); panel.add(createtop(), BorderLayout.NORTH); panel.add(createcenter()); add(panel); za pomocą BorderLayout z marginesem dzielącym okno na dwie części, gdzie na górze znajduje się panel z wszystkimi elementami regulacji, natomiast na dole ma znak, a on użyje części okna, która jest nie używane do górnego panelu. Zacznę od dolnego panelu, który jest najprostszy. Znak jest reprezentowany przez JLabel zdefiniowany jako zmienna instancji: private JLabel lbltext = new JLabel ("Det er teksten"); Dolny panel jest tworzony za pomocą następującej metody: private JPanel createcenter()

31 lbltext.setopaque(true); lbltext.setbackground(color.white); JPanel panel = new JPanel(new BorderLayout()); panel.setborder(new EmptyBorder(20, 0, 20, 0)); JPanel sign = new JPanel(new BorderLayout()); sign.setborder(new LineBorder(Color.black)); JPanel inner = new JPanel(new BorderLayout()); inner.setborder(new LineBorder(Color.white, 5)); inner.add(createdots(), BorderLayout.NORTH); inner.add(createdots(), BorderLayout.SOUTH); inner.add(createmargin(), BorderLayout.WEST); inner.add(createmargin(), BorderLayout.EAST); inner.add(lbltext); sign.add(inner); panel.add(sign); return panel; Pierwszą rzeczą, która się dzieje jest to, że tło panelu jest ustawione na białe. Panel ma BorderLayout z zagnieżdżonym BorderLayout z innym zagnieżdżonym BorderLayout. Celem tego wszystkiego jest zdefiniowanie niektórych marginesów. Zewnętrzny panel ma margines 20 na górze i na dole. Środkowy panel (zwany znakiem) ma na celu zdefiniowanie cienkiej czarnej ramki. Odbywa się to poprzez przypisanie LineBorder, który domyślnie jest linią 1 piksela. Następnie jest wewnętrzny panel zwany wewnętrznym. Ma biały margines 5 pikseli (aby stworzyć odległość do czarnej ramki, panel umieszcza w rogach kilka małych kwadratów (symbolizujących otwory na śruby), a na końcu umieszcza środek etykiety, aby go zbudować, wszystkie poniższe metody są stosowane : private JLabel createmargin() JLabel label = new JLabel(); label.setpreferredsize(new Dimension(5, 5)); label.setopaque(true); label.setbackground(color.white); return label; private JPanel createdots() JPanel panel = new JPanel(new BorderLayout());

32 panel.add(createdot(), BorderLayout.WEST); panel.add(createdot(), BorderLayout.EAST); panel.add(createmargin()); return panel; private JLabel createdot() JLabel label = new JLabel label.setpreferredsize(new Dimension(5, 5)); label.setopaque(true); label.setbackground(color.black); return label; Pierwszy jest używany do BorderLayout, aby zdefiniować białe tło. Dno tworzy czarny kwadrat (otwór na śrubę), natomiast środek tworzy panel z dwoma otworami na śruby i wypełniony białym tłem pomiędzy otworami. Następnie jest górny panel, który jest nieco bardziej złożony. W rzeczywistości składa się z czterech linii z narzędziami, które są ułożone z GridLayout: private JPanel createtop() JPanel panel = new JPanel(new GridLayout(4, 1)); panel.add(createfont()); panel.add(createfg()); panel.add(createbg()); panel.add(createtext()); return panel; Zacznę od dolnej linii, która definiuje pole wejściowe do tekstu znaku. Pole jest zdefiniowane jako zmienna instancji: private JTextField txttext = new JTextField(); a panel z polem wprowadzania jest tworzony w następujący sposób: private JPanel createtext() txttext.settext(lbltext.gettext()); JPanel panel = new JPanel(new BorderLayout(10, 0)); panel.setborder(new EmptyBorder(5, 0, 5, 0)); JLabel label = new JLabel("Tekst");

33 panel.add(new JLabel("Tekst"), BorderLayout.WEST); panel.add(txttext); return panel; Pole wejściowe jest inicjowane zawartością składnika etykiety na znak, ale poza tym jest to głównie BorderLayout z etykietą i polem wprowadzania, dodane centrum. W ten sposób uzyskuje się to, że pole podąża za rozmiarem okna. Następnie jest linia do koloru tła, który składa się z JLabel i trzech par składających się z JLabel i JSlider. Poniższa metoda tworzy takie kilka elementów: private JPanel createcolor(string text, int width, JSlider slider, int min, int max, int value) JPanel panel = new JPanel(new BorderLayout()); JLabel label = new JLabel(" " + text); label.setpreferredsize(new Dimension(width, 30)); panel.add(label, BorderLayout.WEST); slider.setminimum(min); slider.setmaximum(max); slider.setvalue(value); slider.setmajortickspacing(50); slider.setminortickspacing(10); slider.setpaintticks(true); panel.add(slider); return panel; Pierwszy parametr określa tekst składnika etykiety, a następnie szerokość składnika. Pozostałe cztery parametry dotyczą składnika suwaka i wartości, które musi on zainicjować. JSlider to komponent reprezentujący interwał liczb całkowitych zdefiniowany przez setminimum () i setmaximum (). Komponent ma zawsze wartość w tym zakresie i można go zdefiniować za pomocą metody setvalue (). Dwie metody setmajortickspacing () i setminortickspacing () są używane do definiowania wizualnej partycji komponentu. Metoda createcolor () zwraca JPanel z BorderLayout zawierający składnik etykiety i suwak. W rezultacie rozmiar suwaków będzie zgodny z szerokością panelu. Ta metoda służy do określenia trzech par etykiet i suwaków: private JPanel createcolors(jslider sldred, JSlider sldgreen, JSlider sldblue, int red, int green, int blue) JPanel panel = new JPanel(new GridLayout(1, 3));

34 panel.add(createcolor("rød", 40, sldred, 0, 255, red)); panel.add(createcolor("grøn", 50, sldgreen, 0, 255, green)); panel.add(createcolor("blå", 40, sldblue, 0, 255, blue)); return panel; Są one układane za pomocą GridLayout z 1 rzędem i 3 kolumnami, a każda para zawsze wypełnia to samo. Składniki JSlider są definiowane jako zmienne instancji: private JSlider sldrbg = new JSlider(JSlider.HORIZONTAL); private JSlider sldgbg = new JSlider(JSlider.HORIZONTAL); private JSlider sldbbg = new JSlider(JSlider.HORIZONTAL); Po tym następuje linia do dostosowania koloru tła zdefiniowanego w następujący sposób: private JPanel createbg() JPanel panel = new JPanel(new BorderLayout()); panel.setborder(new EmptyBorder(5, 0, 5, 0)); JLabel label = new JLabel("Baggrungsfarve"); label.setpreferredsize(new Dimension(120, 30)); panel.add(label, BorderLayout.WEST); panel.add(createcolors(sldrbg, sldgbg, sldbbg, 255, 255, 255)); return panel; Celem tego wszystkiego jest zapewnienie, aby elementy suwaka były zmieniane w linii na równi podczas zmiany rozmiaru okna. Linia definiująca kolor tekstu została zaprojektowana dokładnie w ten sam sposób i nie będę go tutaj pokazywał, ale trzy komponenty suwaka są definiowane jako zmienne instancji: private JSlider sldrfg = new JSlider(JSlider.HORIZONTAL); private JSlider sldgfg = new JSlider(JSlider.HORIZONTAL); private JSlider sldbfg = new JSlider(JSlider.HORIZONTAL); Następnie znajduje się górny pasek narzędzi, który jest najbardziej złożony. Używa następujących składników, z których wszystkie są zdefiniowane jako zmienne instancji: private JComboBox lstfont; private JTextField txtsize = new JTextField(); private JCheckBox chkbold = new JCheckBox("Bold");

35 private JCheckBox chkitalic = new JCheckBox("Italic"); private JRadioButton cmdleft = new JRadioButton("Left", true); private JRadioButton cmdcenter = new JRadioButton("Center"); private JRadioButton cmdright = new JRadioButton("Right"); Poniższa metoda tworzy JPanel z BorderLayout zawierającą JLabel i JComboBox, a celem jest, aby pole combo było zgodne z szerokością okna: private JPanel createfonts() JPanel panel = new JPanel(new BorderLayout(10, 0)); JLabel label = new JLabel("Fonte"); panel.add(new JLabel("Fonte"), BorderLayout.WEST); DefaultComboBoxModel model = new DefaultComboBoxModel(); String fonts[] = GraphicsEnvironment.getLocalGraphicsEnvironment(). getavailablefontfamilynames(); for (int i = 0; i < fonts.length; ++i) model.addelement(fonts[i]); lstfont = new JComboBox(model); Font df = label.getfont(); for (int n = 0; n < fonts.length; ++n) if (df.getfamily().equals(fonts[n])) lstfont.setselectedindex(n); break; panel.add(lstfont); chkbold.setselected(df.isbold()); chkitalic.setselected(df.isitalic()); txtsize.settext("" + (size = df.getsize())); return panel; Po dodaniu składnika etykiety metoda tworzy model danych dla pola kombi. Następnie tworzona jest tablica nazw wszystkich czcionek dostępnych na bieżącym komputerze, a ta tablica jest używana do zainicjowania modelu. Po utworzeniu pola kombi element etykiety służy do określenia bieżącej domyślnej czcionki dla JLabel i służy do określenia, który element w polu kombi, który powinien zostać wybrany. Na koniec domyślna czcionka służy do inicjalizacji dwóch pól wyboru i pola wprowadzania do rozmiaru czcionki. Po zastosowaniu tej metody pasek narzędzi do czcionek jest zdefiniowany w następujący sposób: private JPanel createfont()

36 JPanel panel = new JPanel(new BorderLayout(10, 0)); panel.setborder(new EmptyBorder(5, 0, 5, 0)); panel.add(createfonts()); JPanel east = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 0)); east.add(new JLabel("Størrelse")); txtsize.setpreferredsize(new Dimension(40, 25)); east.add(txtsize); east.add(chkbold); east.add(chkitalic); east.add(new JLabel(" Justering")); ButtonGroup group = new ButtonGroup(); group.add(cmdleft); group.add(cmdcenter); group.add(cmdright); east.add(cmdleft); east.add(cmdcenter); east.add(cmdright); panel.add(east, BorderLayout.EAST); return panel; Tutaj nie jest wiele nowych do wyjaśnienia, a metoda musi głównie wstawić panel z createfonts () i pozostałe komponenty w BorderLayout. Po zakończeniu projektu - po długiej drodze, ale mówimy również o bardzo złożonym projekcie, a poprzez testowanie należy zauważyć, że jest to stabilna konstrukcja, w której komponenty dopasowują się do rozmiaru okna. Back to obsługa zdarzeń i pomoc w ten sposób program zapewnia następujące metody: private Font createnewfont() boolean bold = chkbold.isselected(); boolean italic = chkitalic.isselected(); String name = (String)lstFont.getSelectedItem(); int size = Integer.parseInt(txtSize.getText()); if (bold && italic) return new Font(name, Font.BOLD Font.ITALIC, size); if (bold) return new Font(name, Font.BOLD, size); if (italic) return new Font(name, Font.ITALIC, size); return new Font(name, Font.PLAIN, size); private void aligntext() if (cmdleft.isselected()) lbltext.sethorizontalalignment(jlabel.left);

37 else if (cmdcenter.isselected()) lbltext. sethorizontalalignment(jlabel.center); else lbltext.sethorizontalalignment(jlabel.right); private void foreground() lbltext.setforeground( new Color(sldRfg.getValue(), sldgfg.getvalue(), sldbfg.getvalue())); private void background() lbltext.setbackground( new Color(sldRbg.getValue(), sldgbg.getvalue(), sldbbg.getvalue())); Pierwsza tworzy i zwraca czcionkę w oparciu o ustawienia wybrane na górnym pasku narzędzi. Następne ustawia wyrównanie w poziomie komponentu lbltext odpowiadające naciśniętemu przyciskowi radiowemu. Na koniec dwie ostatnie metody definiują kolor tekstu komponentu (znaku) i kolor tła z ustawień dla komponentów JSlider. Różne komponenty mogą wywoływać zdarzenie, gdy wystąpi akcja, a w poprzednich przykładach pokazałem i wykorzystałem, jak przycisk może wywołać ActionEvent po kliknięciu i jak to zdarzenie może zostać przechwycone i obsłużone przez ActionListener. W tym przykładzie użyję tego: - JTextField może wystrzelić FocusEvent, gdy uzyska fokus (gdy użytkownik wybierze pole za pomocą klawisza tabulatora lub myszy) oraz gdy straci fokus (gdy użytkownik opuści pole). Te zdarzenia mogą zostać przechwycone przez FocusListener. - JComboBox uruchamiający ActionEvent, gdy wybór zostanie zmieniony (gdy użytkownik wybierze inny element), który może zostać przechwycony przez ActionListener. - JCheckBox i JRadioButton uruchamiający ChangeEvent, gdy stan jest zmieniany i może zostać przechwycony przez ChangeListener. - JSlider odpala ChangeEvent, gdy wartość jest zmieniana, i może zostać przechwycony przez ChangeListener. Dzięki tej wiedzy można tworzyć programy obsługi zdarzeń. Są one wyjątkiem pojedynczego prostego i dlatego są zapisywane jako anonimowe klasy metody addlisteners (): private void addlisteners() txttext.addfocuslistener(new FocusListener() public void focuslost(focusevent e)

38 lbltext.settext(txttext.gettext()); public void focusgained(focusevent e) ); txtsize.addfocuslistener(new FocusListener() public void focuslost(focusevent e) try int t = Integer.parseInt(txtSize.getText()); if (t > 5) lbltext.setfont(createnewfont()); return; catch (Exception ex) txtsize.settext("" + size); public void focusgained(focusevent e) size = Integer.parseInt(txtSize.getText()); ); lstfont.addactionlistener(new ActionListener() public void actionperformed(actionevent e) lbltext.setfont(createnewfont()); );

39 chkbold.addchangelistener(new ChangeListener() public void statechanged(changeevent e) lbltext.setfont(createnewfont()); ); chkitalic.addchangelistener(new ChangeListener() public void statechanged(changeevent e) lbltext.setfont(createnewfont()); ); cmdleft.addchangelistener(new ChangeListener() public void statechanged(changeevent e) aligntext(); ); cmdcenter.addchangelistener(new ChangeListener() public void statechanged(changeevent e) aligntext(); ); cmdright.addchangelistener(new ChangeListener() public void statechanged(changeevent e) aligntext(); ); sldrfg.addchangelistener(new ChangeListener() public void statechanged(changeevent e) foreground(); ); sldgfg.addchangelistener(new ChangeListener() public void statechanged(changeevent e)

40 foreground(); ); sldbfg.addchangelistener(new ChangeListener() public void statechanged(changeevent e) foreground(); ); sldrbg.addchangelistener(new ChangeListener() public void statechanged(changeevent e) background(); ); sldgbg.addchangelistener(new ChangeListener() public void statechanged(changeevent e) background(); ); sldbbg.addchangelistener(new ChangeListener() public void statechanged(changeevent e) background(); ); Nie ma wiele do wyjaśnienia, ale należy pamiętać, że FocusListener definiuje dwie metody, które należy wdrożyć. Należy również zauważyć, że procedura obsługi zdarzeń w polu wprowadzania rozmiaru czcionki jest stosunkowo złożona, ponieważ musi uwzględniać fakt, że użytkownik może wprowadzić dowolne niedozwolone elementy. Zapraszam do przetestowania programu i szczegółowego przestudiowania kodu, ponieważ przykład zawiera wiele z tego, co jest konieczne w praktyce do napisania programu GUI. ĆWICZENIE 5

41 Utwórz kopię projektu CreateSign. Musisz rozwinąć układ za pomocą nowego paska narzędzi (patrz poniżej). Dwa pola kombinowane oraz powiązane etykiety i pole wyboru muszą mieć stały rozmiar i być umieszczone po lewej stronie, jak pokazano poniżej. Przycisk musi podążać za prawą krawędzią. Znaczenie nowych składników jest następujące. Pierwsze pole kombi powinno zawierać kolory zdefiniowane jako stałe w klasie Kolor - z wyjątkiem kolorów czarnego i ciemnoszarego. Drugie pole kombi powinno zawierać liczby od 3 do 20 włącznie. 4 czarne kwadraty (otwory na śruby) tworzą narożniki obramowania wokół znaku. Dwa pola kombinowane wskazują odpowiednio kolor i szerokość tej krawędzi, gdy szerokość musi również dotyczyć rozmiaru 4 kwadratów (muszą zawsze być czarne). Należy zaznaczyć to pole wyboru, aby określić, czy znak powinien mieć przezroczyste tło - tylko wnętrze znaku, a nie krawędź. Na koniec przycisk służy do przywracania wszystkich ustawień do domyślnych - czyli takich, jakie były w momencie uruchomienia programu. Twoim pierwszym zadaniem jest dodanie nowego paska narzędzi do programu, a tym samym rozszerzenie programu o niezbędny projekt. Możesz zacząć od utworzenia komponentów, a następnie umieścić je w panelu z BorderLayout, gdzie przycisk znajduje się na wschodzie, podczas gdy pozostałe komponenty znajdują się w FlowLayout, który następnie jest wstawiany WEST na pierwszym panelu. Dalej definiujesz zdarzenie procedury obsługi w addlisteners () - cztery w sumie. Procedura obsługi komponentu JCheckBox jest prosta, ale problem z aktualizacją komponentu podczas przechodzenia z nieprzejrzystego do przezroczystego tła jest niewielki: public void statechanged (ChangeEvent e) lbltext.setopaque (! chktrans.isselected ()); lbltext.repaint ();

42 Oto ostatnie oświadczenie, które jest wymagane, aby zmiany zaczęły obowiązywać. Aby zmienić kolor i szerokość ramki, konieczne jest odniesienie do komponentów składających się na ramkę: 4 czarne kwadraty i 4 krawędzie. Jest w sumie osiem i wszystkie komponenty JLabel. Zacznij od zdefiniowania 8 zmiennych instancji dla tych komponentów i zainicjuj je w odpowiednich komponentach podczas ich tworzenia. Wtedy łatwo jest napisać procedurę obsługi dla pierwszego pola kombi, aby zmienić kolor - tutaj tylko 4 z 8 komponentów musi zmienić kolor. Jeśli chodzi o ostateczne pole kombi, które służy do zmiany komponentów, preferowany rozmiar jest nieco trudniejszy. Poniższa metoda może być użyta do zmiany rozmiaru komponentu (czasów, w których JLabel): private void resize(jlabel label, int width) label.setpreferredsize(new Dimension(width, width)); label.dolayout(); label.revalidate(); Nareszcie jest przycisk po prawej. Po jej kliknięciu wszystkie ustawienia powinny zostać zwrócone podczas uruchamiania programu, a znak powinien być wyświetlany tak, jak przy uruchomieniu programu. 6 LAYOUT ORAZ ROZMIAR ELEMENTÓW Jak pokazano w powyższych przykładach, rozmiar i lokalizacja komponentu jest określana przez tak zwanych menedżerów układu, a wynik nie zawsze jest tak łatwy do wykrycia. W tej sekcji wyjaśnię częściowo, w jaki sposób obliczany jest rozmiar komponentu, a także gdzie jest on umieszczony w oknie. Kiedy jest dużo do opowiedzenia, jest to spowodowane tym, że okno i jego komponenty powinny zachowywać się rozsądnie, jeśli zmienia się rozmiar okna. Jeśli, na przykład, rozważysz powyższy program, kilka komponentów zmieni rozmiary po zmianie rozmiaru okna, podczas gdy inne komponenty będą podążać za prawą krawędzią okna. Jest kontrolowany przez menedżerów układu, który określa sposób umieszczania komponentów okna lub panelu. 6.1 ROZMIAR ELEMENTÓW Komponent ma rozmiar, który jest określony przez szerokość i wysokość, a do zdefiniowania i modyfikacji tych wartości komponent ma cztery metody - setsize () - setpreferredsize () - setminimumsize () - setmaximumsize () Wszystkie te metody mają parametr typu Wymiar, jednak pierwszy ma przeciążenie, gdzie parametry są dwiema wartościami int. Pierwszy działa tylko wtedy, gdy panel nie korzysta z menedżera układu. We wszystkich innych przypadkach jest to ignorowane. Dlatego można go użyć do zdefiniowania

43 rozmiaru okna, ponieważ okno ramki nie ma menedżera układu. W praktyce komponenty są prawie zawsze umieszczane w panelu za pomocą jednego lub kilku menedżerów układów, a tutaj są trzy ostatnie interesujące metody. Główną zasadą jest to, że menedżer układu będzie próbował dostosować rozmiar komponentu do jego preferowanego rozmiaru, ale menedżer nie zmniejszy rozmiaru komponentu poniżej jego minimalnego rozmiaru i nie zwiększy rozmiaru do więcej niż jego maksymalny rozmiar. Istnieją więc trzy rozmiary dołączone do komponentu, ale całość jest skomplikowana, ponieważ sposób wykorzystania tych ilości zależy od konkretnego menedżera układu. Jako początek pokazano poniżej kod okna z 6 przyciskami: package layoutpanels; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class MainView extends JFrame public MainView() settitle("components and there locations"); setsize(500, 300); setlocationrelativeto(null); setdefaultcloseoperation(exit_on_close); createwindow(); setvisible(true); private void createwindow() JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT, 30, 10)); panel.setborder(new EmptyBorder(20, 20, 20, 20)); panel.add(createbutton("borderlayout", 150, 30, null)); panel.add(createbutton("flowlayout", 120, 40, null)); panel.add(createbutton("gridlayout", 150, 30, null)); panel.add(createbutton("gridbaglayout", 200, 50, null)); panel.add(createbutton("boxlayout", 150, 30, null));

44 panel.add(createbutton("null layout", 250, 20, null)); add(panel); private JButton createbutton(string text, int width, int height, ActionListener listener) JButton cmd = new JButton(text); cmd.addactionlistener(listener); cmd.setpreferredsize(new Dimension(width, height)); return cmd; Należy zwrócić uwagę na metodę createbutton (), która tworzy przycisk o preferowanym rozmiarze. Ponadto procedura obsługi zdarzeń przycisku jest parametrem. Metoda jest używana w createview () do tworzenia przycisków, ale jak dotąd ostatni parametr jest zawsze pusty, co oznacza po prostu, że przycisk nie ma jeszcze obsługi zdarzeń, ale oznacza to, że po kliknięciu przycisku otwiera się kolejne okno ilustrujące działanie menedżera układu. Jeśli uruchomisz program, otrzymasz następujące okno: Metoda createwindow () tworzy panel z FlowLayout, który jest już używany kilka razy jako menedżer układu, który umieszcza komponenty w rzędzie od lewej do prawej. Nie ma wystarczającej ilości miejsca, komponenty są kontynuowane w następnym wierszu, a komponent rozmiar są określane przez ich preferowany rozmiar.

45 6.2 BORDERLAYOUT Jeśli klikniesz na górny przycisk, otworzy się okno, którego kod jest następujący: package layoutpanels; import java.awt.*; import javax.swing.*; public class BorderlayoutView extends JDialog public BorderlayoutView() super(null, "BorderLayout", Dialog.ModalityType.APPLICATION_MODAL); setsize(500, 300); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow()

46 setlayout(new BorderLayout(10, 20)); setbackground(color.lightgray); add(createlabel("north", 0, 30, Color.white, Color.blue), BorderLayout.NORTH); add(createlabel("south", 0, 40, Color.white, Color.red), BorderLayout.SOUTH); add(createlabel("west", 80, 0, Color.black, Color.green), BorderLayout.WEST); add(createlabel("east", 100, 0, Color.white, Color.magenta), BorderLayout.EAST); add(createlabel("center", 0, 0, Color.black, Color.yellow)); private JLabel createlabel(string text, int width, int height, Color color1, Color color2) JLabel label = new JLabel(text); label.sethorizontalalignment(jlabel.center); label.setopaque(true); label.setbackground(color2); label.setforeground(color1); label.setpreferredsize(new Dimension(width, height)); return label; Tym razem nie jest to okno JFrame, ale okno dialogowe - klasa dziedziczy JDialog. Okno dialogowe ma BorderLayout z pięcioma komponentami JLabel

47 Powyżej wyjaśniłem, jak działa BorderLayout, a ja nie będę komentował tego menedżera układu. Aby otworzyć okno dialogowe, MainView musi mieć procedurę obsługi zdarzeń dla pierwszego przycisku i nie ma nic nowego w porównaniu do tego, co zostało wcześniej powiedziane: private void border(actionevent e) new BorderlayoutView(); panel.add(createbutton("borderlayout", 150, 30, this::border)); 6.3 FLOWLAYOUT Kliknięcie drugiego górnego przycisku (w MainView) powoduje wyświetlenie okna pokazanego poniżej, ilustrującego użycie menedżera FlowLayout: package layoutpaneler; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FlowlayoutView extends JDialog public FlowlayoutView() super(null, "FlowLayout", Dialog.ModalityType.APPLICATION_MODAL); setsize(500, 300); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow() setlayout(new FlowLayout(FlowLayout.LEFT, 5, 5)); for (char c = 'A'; c <= 'Z'; ++c) add(createbutton("" + c, 50, 30));

48 private JButton createbutton(string text, int width, int height) JButton cmd = new JButton(text); cmd.setpreferredsize(new Dimension(width, height)); cmd.addactionlistener(new ActionListener() public void actionperformed(actionevent e) JOptionPane.showMessageDialog(FlowlayoutView.this, "You have clicked " + text); ); return cmd; Okno jest ponownie modalnym oknem dialogowym, ale tym razem z FlowLayout. Jest 27 przycisków, a jedyną rzeczą do obejrzenia jest to, co dzieje się po uruchomieniu programu i zmianie rozmiaru okna. Możesz również zauważyć, jak dołączyć anonimowy moduł obsługi zdarzeń dla przycisków. Nie jest to szczególnie czytelne, ale jest to krótki sposób pisania. 6.4 GRIDLAYOUT GridLayout to menedżer układu, który dzieli panel na kilka wierszy i liczbę kolumn. Jeśli panel ma na przykład 10 rzędów i 20 kolumn, zawiera 200 komórek, wszystkie mają ten sam rozmiar. Każda komórka może zawierać komponent, a składnik zawsze wypełnia całą komórkę, a GridLayout ignoruje wszystko, co dotyczy preferowanego rozmiaru komponentów. Poniżej znajduje się okno z 200 komponentami umieszczonymi w panelu za pomocą GridLayout. Składnikami są wszystkie komponenty JLabel, które są wyświetlane z losowym kolorem tła:

49 Kod jest następujący: package layoutpaneler; import java.util.*; import java.awt.*; import javax.swing.*; public class GridlayoutView extends JDialog private static Random rand = new Random(); public GridlayoutView() super(null, "GridLayout", Dialog.ModalityType.MODELESS); setsize(500, 300); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow() setlayout(new GridLayout(10, 20)); for (int r = 0; r < 10; ++r) for (int c = 0; c < 20; ++c) add(createlabel());

50 private JLabel createlabel() JLabel label = new JLabel(); label.setopaque(true); label.setbackground(new Color(rand.nextInt(256), rand.nextint(256), rand.nextint(256))); return label; Powinieneś zauważyć, jak w createwindow () tworzony jest GridLayout. Parametrami są odpowiednio liczba rzędów i liczba kolumn. Możesz także określić, jaka powinna być przerwa między poszczególnymi komórkami - zarówno poziomo, jak i pionowo. ĆWICZENIE 6 Napisz program, który możesz wywołać MiniCalc. Program musi otworzyć okno, jak pokazano poniżej. Okno ma pole wprowadzania i 20 przycisków. Program powinien symulować prosty kalkulator i powinien być obsługiwany tylko za pomocą myszy. Pole wejściowe jest tylko do odczytu (użyj metody seteditable ()), a tekst jest wyrównany do prawej. 10 górnych przycisków powinno być zrozumiałych. Przyciski w trzecim rzędzie od lewej: 1. Usuń ostatni znak na wyświetlaczu 2. Ekspansja 3. Podział 4. Odejmowanie 5. Kropka dziesiętna Przyciski w dolnym rzędzie od lewej:

51 1. Wyczyść wyświetlacz 2. Przesuń znak na zawartość na wyświetlaczu 3. Mnożenie 4. Dodatek 5. Enter, który oblicza wartość wyrażenia na wyświetlaczu i aktualizuje wyświetlacz za pomocą wartości Program musi potwierdzić, że na wyświetlaczu pojawiają się wyłącznie znaki prawne (znak prowadzący do prawidłowego wyrażenia). Jeśli spróbujesz wykonać nielegalne obliczenia, klikając OK, powinieneś otrzymać komunikat o błędzie, jak pokazano poniżej: Jest to oczywiście bardzo uproszczony kalkulator i można pracować tylko z bardzo prostymi wyrażeniami, szczególnie dlatego, że nie można wprowadzić nawiasów. 6.5 GRIDBAGLAYOUT Następny menedżer układu jest bardzo elastycznym menedżerem, ale jest również bardzo skomplikowany w obsłudze. Jak sama nazwa wskazuje, jest to siatka, która dzieli panel w wierszu i kolumnach, ale takie, że wszystkie wiersze nie muszą mieć tej samej wysokości, a wszystkie kolumny nie muszą mieć tej samej szerokości. Wynik jest taki sam jak w GridLayout, że panel jest podzielony na kilka komórek, ale komponent może tym razem obejmować wiele komórek. Oprócz tego, jaki jest dokładny rozmiar poszczególnych komórek, określa się ich preferowany rozmiar. To, ile składników się zapełnia i jak zachowują się one po zmianie rozmiaru okna, zależy od struktury danych zwanej GridBagConstraints, a obiekt tego typu jest powiązany z poszczególnymi komponentami. Ta struktura danych ma następujące pola: 1. gridx i gridy wskazujące kolumnę składnika i indeks wiersza w panelu w lewym górnym rogu (0, 0). Możesz również określić wartość jako GridBagConstraints. WZGLĘDNA dla kolumny i wiersza, co oznacza względem ostatniego komponentu, umieszczonego w panelu. Wartością domyślną dla kolumn i wierszy są GridBagConstraints. KREWNY. 2. szerokość sieci i wysokość siatki wskazujące odpowiednio liczbę kolumn i liczbę rzędów, które powinien objąć ten komponent. Domyślna wartość obu wartości wynosi 1. Dla obu wartości możliwe jest określenie GridBagConstraints.REMAINDER, co oznacza, że komponent będzie obejmował pozostałą część wiersza lub pozostałą część kolumny. 3. wypełnienie, które wskazuje, w jaki sposób komponent powinien wypełnić komórkę, jeśli jej preferowany rozmiar jest mniejszy niż rozmiar komórki. Można określić GridBagConstraints.NONE, (co oznacza, że używany jest preferowany rozmiar) GridBagConstraints.HORIZONTAL, GridBagConstraints. VERTICAL i GridBagConstraints.BOTH, gdzie pierwszy jest domyślny.

52 4. ipadx i ipady, które wskazują, ile odstępu musi znajdować się na zewnątrz elementu. Wartość domyślna to 0. Możesz myśleć o tej wartości jako o krawędzi komponentu, ale o wewnętrznej krawędzi, która jest częścią obszaru używanego dla komponentu. 5. wypustki, które wskazują margines zewnętrzny, a zatem ile miejsca, musi być wokół komponentu. Wartością jest obiekt Insets, a wartością domyślną jest brak marginesu. 6. Waga i wagi wskazujące, w jaki sposób przestrzeń zostanie rozdzielona odpowiednio na kolumny i rzędy. Wpływ tych wartości jest nieco trudny do zinterpretowania, ale mają one wartość od 0 do 1, gdzie wartość domyślna to 0. Oznacza to, że szerokość kolumn i wysokość rzędów to maksymalna preferowana szerokość i maksymalna preferowana szerokość. wysokość komponentów w kolumnie lub rzędzie. Jeśli, dla elementu wskazującego wagę, oznacza to, że dowolna wolna przestrzeń w panelu powinna być rozłożona zgodnie z tymi wagami. Wagi mają zatem kluczowe znaczenie dla zachowania komponentów podczas zmiany rozmiaru okna. 7. kotwica jak w przypadku, gdy preferowany rozmiar elementu jest mniejszy niż komórka wskazuje miejsce, w którym składnik ma być umieszczony w komórce. Opcje są pokazane na poniższym rysunku, gdzie wszystkie nazwy odnoszą się do stałych w GridBagConstraints: Powyższe dźwięki są skomplikowane i tak też jest, i trzeba trochę eksperymentów, aby GridBagLayout zachowywał się zgodnie z oczekiwaniami. Punktem wyjścia jest rozpoczęcie od szkicu, który może zilustrować okno, które chcesz zaprojektować. W tym przypadku zaprojektowałbym okno, w którym można wpisać liczbę jednostek i cenę jednostkową przedmiotu. Trzeba mieć również możliwość sprawdzenia, czy cena jednostkowa została wprowadzona z podatkiem VAT lub bez niego. Po kliknięciu przycisku program musi obliczyć sumę i VAT, a po kliknięciu innego przycisku element zamówienia zostanie wstawiony w polu listy. Projekt powinien wyglądać tak, jak pokazano poniżej:

53 Trzy pola pod polem listy muszą zawierać sumy dla linii produktów. Pole listy i trzy pola do sum powinny być zgodne z rozmiarem okna, a przyciski powinny być umieszczone względem dołu. W rzeczywistości jest to dość złożony projekt i jest przykładem projektu, który można rozwiązać za pomocą GridBagLayout. Kod jest pokazany poniżej i wypełnia wiele: package layoutpanels; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class GridbaglayoutView extends JDialog private DefaultListModel model = new DefaultListModel(); private ButtonGroup group = new ButtonGroup(); private JTextField txtunits; private JTextField txtprice; private JTextField txtexcl; private JTextField txtvat; private JTextField txtincl; private JRadioButton cmdexcl; private JRadioButton cmdincl; private JTextField txtexclsum; private JTextField txtvatsum; private JTextField txtinclsum; private double units; private double price; private double excl; private double vat; private double incl; private double exclsum; private double vatsum; private double inclsum; public GridbaglayoutView() super(null, "GridBagLayout", Dialog.ModalityType.APPLICATION_MODAL);

54 setsize(800, 500); this.setminimumsize(new Dimension(800, 450)); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow() setlayout(new BorderLayout()); JPanel panel = new JPanel(new GridBagLayout()); panel.setborder(new EmptyBorder(20, 20, 30, 20)); addcomponent(panel, createlabel("number of units", 120, 20), 0, 0, 2, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, txtunits = createfield(120, 20, true), 2, 0, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 20, 20)); addcomponent(panel, createlabel("unit price", 120, 20), 0, 1, 2, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, txtprice = createfield(120, 20, true), 2, 1, 1, 1, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0, 0, 20, 20)); addcomponent(panel, cmdexcl = createradio("unit price excl. VAT", 200, 20, true, group), 0, 2, 3, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 10, 0)); addcomponent(panel, cmdincl = createradio("unit price incl. VAT", 200, 20, false, group), 0, 3, 3, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 20, 0)); addcomponent(panel, createlabel("amount", 100, 20), 0, 4, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, txtexcl = createfield(150, 20, false), 1, 4, 2, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_END, new Insets(0, 0, 20, 20)); addcomponent(panel, createlabel("vat", 100, 20), 0, 5, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START,

55 new Insets(0, 0, 0, 0)); addcomponent(panel, txtvat = createfield(150, 20, false), 1, 5, 2, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_END, new Insets(0, 0, 20, 20)); addcomponent(panel, createlist(), 3, 0, 3, 7, 1, 1, GridBagConstraints.BOTH, GridBagConstraints.LINE_START, new Insets(0, 0, 10, 0)); addcomponent(panel, createlabel("total", 100, 20), 0, 6, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, txtincl = createfield(150, 20, false), 1, 6, 2, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.FIRST_LINE_END, new Insets(0, 0, 20, 20)); addcomponent(panel, createlabel("amount", 80, 20), 3, 7, 1, 1, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, createlabel("vat", 80, 20), 4, 7, 1, 1, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, createlabel("total", 80, 20), 5, 7, 1, 1, 1, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, createbutton("ok", 90, 23, this::ok), 0, 9, 1, 1, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(20, 0, 0, 10)); addcomponent(panel, createbutton("clear", 90, 23, this::clear), 1, 9, 1, 1, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(20, 0, 0, 10)); addcomponent(panel, createbutton("calculate", 90, 23, this::calc), 2, 9, 1, 1, 0, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(20, 0, 0, 40)); addcomponent(panel, txtexclsum = createfield(100, 20, false), 3, 8, 1, 1, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 10));

56 addcomponent(panel, txtvatsum = createfield(100, 20, false), 4, 8, 1, 1, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 10)); addcomponent(panel, txtinclsum = createfield(100, 20, false), 5, 8, 1, 1, 1, 0, GridBagConstraints.HORIZONTAL, GridBagConstraints.LINE_START, new Insets(0, 0, 0, 0)); addcomponent(panel, createbutton("delete", 90, 23, this::delete), 5, 9, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_END, new Insets(20, 0, 0, 0)); add(panel); private JScrollPane createlist() JList list = new JList(model); list.setenabled(false); JScrollPane scroll = new JScrollPane(list); scroll.setpreferredsize(new Dimension(400, 200)); return scroll; private JRadioButton createradio(string text, int width, int height, boolean checked, ButtonGroup group) JRadioButton cmd = new JRadioButton(text); cmd.setpreferredsize(new Dimension(width, height)); cmd.setselected(checked); group.add(cmd); return cmd; private JLabel createlabel(string text, int width, int height) JLabel label = new JLabel(text); label.setpreferredsize(new Dimension(width, height)); return label; private JButton createbutton(string text, int width, int height, ActionListener listener)

57 JButton cmd = new JButton(text); cmd.setpreferredsize(new Dimension(width, height)); cmd.addactionlistener(listener); return cmd; private JTextField createfield(int width, int height, boolean editable) JTextField field = new JTextField(); field.setpreferredsize(new Dimension(width, height)); field.seteditable(editable); field.sethorizontalalignment(jtextfield.right); return field; public static void addcomponent(container container, Component component, int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int fill, int anchor, Insets insets) GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = gridx; constraints.gridy = gridy; constraints.gridwidth = gridwidth; constraints.gridheight = gridheight; constraints.weightx = weightx; constraints.weighty = weighty; constraints.fill = fill; constraints.anchor = anchor; constraints.insets = insets; container.add(component, constraints); private void calc(actionevent e) try units = Double.parseDouble(txtUnits.getText().trim()); price = Double.parseDouble(txtPrice.getText().trim()); if (units > 0 && price > 0) if (cmdincl.isselected()) price *= 0.8; excl = price * units; vat = excl * 0.25; incl = excl + vat;

58 txtexcl.settext(string.format("%1.2f", excl)); txtvat.settext(string.format("%1.2f", vat)); txtincl.settext(string.format("%1.2f", incl)); return; catch (Exception ex) JOptionPane.showMessageDialog(this, "Illegal value for the number of units or unit price", "Error message", JOptionPane.ERROR_MESSAGE); private void ok(actionevent e) if (incl > 0) model.addelement(string.format( "%1.1f units á kr. %1.2f, amount = %1.2f, VAT = %1.2f, total = %1.2f", units, price, excl, vat, incl)); exclsum += excl; vatsum += vat; inclsum += incl; txtexclsum.settext(string.format("%1.2f", exclsum)); txtvatsum.settext(string.format("%1.2f", vatsum)); txtinclsum.settext(string.format("%1.2f", inclsum)); clear(e); private void clear(actionevent e) units = price = excl = incl = vat = 0; txtunits.settext(""); txtprice.settext(""); txtexcl.settext(""); txtvat.settext(""); txtincl.settext(""); txtunits.requestfocus(); private void delete(actionevent e) model.clear(); clear(e);

59 Okno zawiera tym razem wiele komponentów: - 8 składników etykiety, które są obiektami typu JLabel - 8 pól wejściowych, które są obiektami typu JTextField - 2 przyciski radiowe będące obiektami typu JRadioButton - 1 pole listy, które jest obiektem typu JList - 4 przyciski będące obiektami typu JButton Jeśli zaczniesz od góry, istnieje model dla pola listy i ButtonGroup. Ostatni obiekt powinien zostać użyty do przycisków radiowych dołączone do ButtonGroup. Dzięki temu można nacisnąć tylko jeden przycisk radiowy. Następnie zdefiniowane są komponenty, do których można się odwoływać w procedurach obsługi zdarzeń. Są to pola wprowadzania i dwa przyciski opcji (w rzeczywistości tylko jeden z nich). Końcowe są zdefiniowane zmienne do wartości pól wejściowych. Klasa ma kilka pomocniczych metod: - createlabel () to prosta metoda, która tworzy etykietę o preferowanym rozmiarze. - createfield () tworzy w ten sam sposób pole wejściowe. Ma parametr określający, gdzie można edytować zawartość. To jest, gdzie pole powinno być używane do wprowadzania danych lub powinno być używane tylko do pokazania wartości. Należy pamiętać, że zawartość jest wyrównana do prawej. - createradio () to metoda, która tworzy przycisk radiowy. Ma parametr, który mówi, czy przycisk powinien być sprawdzony, a także grupa jest parametrem. Grupa jest wymagana, ponieważ okno może mieć więcej grup przycisków opcji. - createbutton () to metoda, która tworzy przycisk i są parametry dla tekstu, rozmiaru i obsługi zdarzenia. - createlist () tworzy pole listy i hermetyzuje pole listy w JScrollPane, dzięki czemu będziesz mógł przewijać zawartość. Ponadto zdefiniowano cztery procedury obsługi zdarzeń dla czterech przycisków: 1. calc () jest procedurą obsługi zdarzenia do przycisku Oblicz. Po naciśnięciu pobiera zawartość pól wejściowych odpowiednio liczbę jednostek i cenę jednostkową i konwertuje wartości i przechowywane je w odpowiednich zmiennych. Jeśli podane wartości prawne, w razie potrzeby VAT usunięto z ceny jednostkowej, w przeciwnym razie kwoty produktów i VAT są obliczane, a odpowiednie pola są aktualizowane. Czy wartości z tego czy innego powodu są nielegalne, pojawia się komunikat o błędzie. 2. clear () to program obsługi zdarzeń do przycisku Wyczyść, który usuwa pola wejściowe i pola do wyniku i ustawia zmienne używane do obliczeń na zero.

60 3. ok () to obsługa zdarzeń dla przycisku OK. Jeśli istnieje obliczenie, metoda dodaje linię do pola listy dla bieżącego elementu i aktualizuje pola dla sum. Metoda wywołuje również funkcję handler clear () i czyści pola obliczeń. 4. delete () to program obsługi zdarzeń do przycisku Usuń i czyści pole listy. Teraz istnieje metoda createwindow (), i właśnie wtedy wszystko się dzieje. Aby dodać składnik, metoda używa metody o nazwie addcomponent (). Ta metoda tworzy obiekt GridBagConstraints i inicjuje go za pomocą parametrów. Ten obiekt jest dołączony do komponentu, który jest następnie dodawany do panelu. createwindow () tworzy JPanel z GridBagLayout. Aby uzyskać margines, panelowi przypisano granicę, ale poza tym praca polega na umieszczeniu 23 elementów w panelu. Nie przejdę przez wszystkie 23 komponenty, ale przyjrzę się dwóm, ponieważ zasada jest taka sama dla wszystkich komponentów. Zacznę od drugiego komponentu, który jest polem wejściowym do liczby jednostek: addcomponent (panel, txtunits = createfield (120, 20, true), 2, 0, 1, 1, 0, 0, GridBagConstraints.NONE, GridBagConstraints.LINE_START, nowe wypustki (0, 0, 20, 20)); Pole wejściowe jest tworzone z odpowiednim preferowanym rozmiarem. Ma to wpływ na rozmiar komórki zawierającej ten składnik. Następnie określa się, że komórka powinna być kolumną 2, wiersz 0. Kiedy jest umieszczona w kolumnie 2, dzieje się tak, ponieważ element etykiety z przodu i obejmuje dwie kolumny. Następne dwa parametry wskazują, że ten komponent nie musi obejmować komórek innych niż komórka, w której jest umieszczony. Kolejne dwa parametry to wagi, które wskazują przy następnym parametrze wypełnienia, rozmiar tego komponentu musi zawsze być jego preferowanym rozmiarem. Drugi ostatni parametr mówi, że komponent musi zostać ustawiony po lewej stronie komórki, a na końcu ostatni parametr wskazuje, że musi być margines 20 po prawej stronie i poniżej komponentu. Poniżej znajduje się kod dodający pole listy: addcomponent (panel, createlist (), 3, 0, 3, 7, 1, 1, GridBagConstraints.BOTH, GridBagConstraints.LINE_START, new Insets (0, 0, 10, 0)); Jest on umieszczony w kolumnie 3, wiersz 0, ale powinien obejmować 3 kolumny i 7 wierszy. Następnie wagi są ustawione na 1 i mówi się, że komponent musi wykorzystywać całą dostępną przestrzeń zarówno w poziomie, jak iw pionie. Jednocześnie mówiąc o następnym parametrze, komponent powinien wypełnić całą komórkę zarówno w poziomie, jak iw pionie, a wynik jest taki, że rozmiar komponentu jest zgodny z rozmiarem okna. Jego preferowany rozmiar jest ignorowany. Dwa ostatnie parametry informują, że komponent ma zostać skorygowany do lewej krawędzi komórki (zignorowany w tym przypadku, ale metoda addcomponent () wymaga wartości) i musi być margines 10 poniżej komponentu. Jako ostatnia uwaga do okna dialogowego zwróć uwagę, że okno w konstruktorze ma przypisany minimalny rozmiar. Powodem tego nie jest zmniejszanie okna, a następnie menedżer układu nie może wyświetlać komponentów. Jeśli otworzysz okno dialogowe i wprowadzisz wartości dla kilku elementów, wynik może wyglądać tak, jak pokazano poniżej:

61 ĆWICZENIE 7 Napisz program, który możesz wywołać Positiion otwierające okno, jak pokazano poniżej Użytkownik musi wprowadzić nazwisko i stanowisko osoby, a po kliknięciu przycisku OK program musi wstawić wiersz w polu listy. Celem ćwiczenia jest zaprojektowanie okna za pomocą GridBagLayout.

62 Górne pola wejściowe muszą mieć stały rozmiar, ale pole listy i przycisk dolny powinny być zgodne z rozmiarem okna. Najpierw powinieneś stworzyć prostą klasę, która reprezentuje osobę: package positions; public class Person private String firstname; private String lastname; private String position; public Person(String firstname, String lastname, String position) this.firstname = firstname; this.lastname = lastname; this.position = position; public String tostring() return firstname + " " + lastname + ", " + position; Aby utworzyć okno ManView, możesz skopiować metodę addcomponent () z powyższego przykładu, a może dobrze jest skopiować metody createlabel (), createfield () i createbutton (). Następnie okno może być zaprojektowane w taki sam sposób jak w powyższym przykładzie. Mogę wspomnieć, że mój GridBagLayout ma pięć wierszy i cztery kolumny. 6.6 BOXLAYOUT Następny menedżer układu jest w zasadzie bardzo prostym menedżerem układu, ale jest również skomplikowany, ponieważ istnieje wiele opcji i może być trudno dowiedzieć się, jak różne ustawienia wpływają na układ. Zasadniczo jest to menedżer układu, który organizuje swoje komponenty w rzędzie, poziomo lub pionowo. Natychmiast wygląda na FlowLayout, ale jest jeszcze kilka rzeczy, o których warto pamiętać. Kiedy BoxLayout organizuje komponenty, ich położenie i rozmiar zostaną określone przez - preferowany rozmiar komponentu - minimalna wielkość elementu - maksymalny rozmiar elementu - wyrównanie komponentu Najlepiej jest to zilustrować przykładami, a jeśli klikniesz przycisk BoxLayout w programie demonstracyjnym, pojawi się okno, w którym możesz otworzyć 11 przykładów (patrz niżej). Oto pierwsze 10 przykładów wirtualnych takich samych, podczas gdy drugie jest trochę inne. Przyciski okna są również układane za pomocą BoxLayout. Zachęcamy do uruchomienia programu i sprawdzenia, co

63 dzieje się z przyciskami podczas zmiany rozmiaru okna. Tutaj szczególnie powinieneś zauważyć trzy rzeczy: 1. Przyciski znajdują się w środku okna. Podczas korzystania z BoxLayout wszystkie komponenty kontenera mają zazwyczaj takie samo działanie, ponieważ różne wyrównania często prowadzą do nieoczekiwanych rezultatów. 2. Rozmiary komponentu nie są zmieniane, ale określa się ich preferowany rozmiar. Dzieje się tak, ponieważ mają one ten sam minimalny, maksymalny i preferowany rozmiar, który następnie określa rozmiar komponentu. Aby upewnić się, że BoxLayout daje oczekiwany wynik, należy zawsze określić wszystkie trzy rozmiary komponentu. 3. Część okna, która nie jest zajęta przez komponenty, jest pusta, a pusta przestrzeń (komponenty są ułożone w kolumnie) jest zawsze poniżej komponentów. Kod okna jest następujący, gdzie nie pokazałem procedur obsługi zdarzeń: package layoutpanels; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class BoxlayoutView extends JDialog public BoxlayoutView() super(null, "BoxLayout", Dialog.ModalityType.APPLICATION_MODAL); setsize(300, 330); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow()

64 setlayout(new BorderLayout()); JPanel panel = new JPanel(); panel.setlayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.add(createbutton("example 1", 150, 25, this::box01)); panel.add(createbutton("example 2", 150, 25, this::box02)); panel.add(createbutton("example 3", 150, 25, this::box03)); panel.add(createbutton("example 4", 150, 25, this::box04)); panel.add(createbutton("example 5", 150, 25, this::box05)); panel.add(createbutton("example 6", 150, 25, this::box06)); panel.add(createbutton("example 7", 150, 25, this::box07)); panel.add(createbutton("example 8", 150, 25, this::box08)); panel.add(createbutton("example 9", 150, 25, this::box09)); panel.add(createbutton("example 10", 150, 25, this::box10)); panel.add(createbutton("example 11", 150, 25, this::box11)); add(panel); private JButton createbutton(string text, int width, int height, ActionListener listener) JButton cmd = new JButton(text); cmd.setpreferredsize(new Dimension(width, height)); cmd.setminimumsize(new Dimension(width, height)); cmd.setmaximumsize(new Dimension(width, height)); cmd.setalignmentx(component.center_alignment); cmd.addactionlistener(listener); return cmd; Należy przede wszystkim zauważyć, jak metoda createwindow () definiuje BoxLayout i jak to BoxLayout.Y_AXIS wskazuje, że elementy muszą być rozmieszczone w kolumnie. Zauważ też, że BoxLayout jest zdefiniowany nieco inaczej niż inne menedżery układu. Ponadto zauważ, że metoda createbutton () definiuje wyrównanie poszczególnych komponentów: cmd.setalignmentx (Component.CENTER_ALIGNMENT); oznacza to wyrównanie w poziomie. Parametr jest stałą typu float i ma wartość z zakresu od 0 do 1. Wartość wskazuje stopień, w jakim komponent musi być wyrównany od lewej do prawej, i zdefiniowane są następujące stałe: 0 = Component.LEFT_ALIGNMENT 0,5 = Component.CENTER_ALIGNMENT

65 1 = Component.RIGHT_ALIGNMENT Jeśli otworzysz przykład 1, otrzymasz okno pokazane poniżej. Okno pokazuje trzy komponenty JLabel, które są ułożone w kolumnie przez BoxLayout. Podczas testowania tego przykładu należy obserwować, co dzieje się z komponentami podczas zmiany rozmiaru okna. Składniki zmieniają się na maksymalny rozmiar i są kompresowane do minimalnego rozmiaru, a na końcu należy pamiętać, że są one regulowane lewą krawędzią. Kod jest następujący, co nie wymaga dalszych wyjaśnień: package layoutpanels; import java.awt.*; import javax.swing.*; import javax.swing.border.*; public class Box01View extends JDialog public Box01View() super(null, "BoxLayout", Dialog.ModalityType.MODELESS); setsize(400, 400); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true);

66 private void createwindow() setlayout(new BorderLayout()); JPanel panel = new JPanel(); panel.setlayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); panel.setborder(new EmptyBorder(10, 10, 10, 10)); panel.add(createlabel(100, 50, Color.red)); panel.add(createlabel(150, 75, Color.green)); panel.add(createlabel(200, 100, Color.blue)); add(panel); private JLabel createlabel(int width, int height, Color color) JLabel label = new JLabel(); label.setalignmentx(component.left_alignment); label.setopaque(true); label.setbackground(color); label.setpreferredsize(new Dimension(width, height)); label.setminimumsize(new Dimension(width / 2, height / 2)); label.setmaximumsize(new Dimension(width * 2, height * 2)); return label; Poniższe 9 przykładów jest zasadniczo identycznych do powyższych i pokazuje te same trzy składniki. Różnica polega na tym, w jaki sposób komponenty są regulowane i czy są układane w pionie lub w poziomie. Nie będę tu pokazywał tych przykładów, ale powinieneś otworzyć okna dialogowe, aby zobaczyć, co się dzieje. Zasadniczo BoxLayout nie wstawia odstępów między komponentami, ale nie można dodawać żadnych komponentów wizualnych, a ja jako przykład wyjaśniam przykład 10. Jeśli otworzysz okno dialogowe, pojawi się następujące okno:

67 tam, gdzie komponenty tym razem układa się poziomo. Między pierwszymi dwoma komponentami dodano niewidoczny komponent o szerokości 10, podczas gdy między dwoma ostatnimi komponentami wstawiona jest szczelina wypełniająca część panelu, która nie jest używana. Wysokość komponentów jest jak poprzednio ograniczona ich maksymalną wysokością, a szerokość jest ich preferowaną szerokością. Kod jest następujący: package layoutpaneler; import java.awt.*; import javax.swing.*; import javax.swing.border.*; public class Box10View extends JDialog public Box10View() super(null, "BoxLayout", Dialog.ModalityType.MODELESS); setsize(600, 200); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow() setlayout(new BorderLayout()); JPanel panel = new JPanel(); panel.setlayout(new BoxLayout(panel, BoxLayout.X_AXIS)); panel.setborder(new EmptyBorder(10, 10, 10, 10)); panel.add(createlabel(100, 50, Color.red)); panel.add(box.createrigidarea(new Dimension(10, 0))); panel.add(createlabel(150, 75, Color.green)); panel.add(box.createhorizontalglue()); panel.add(createlabel(200, 100, Color.blue)); add(panel); private JLabel createlabel(int width, int height, Color color) JLabel label = new JLabel(); label.setalignmenty(component.top_alignment); label.setopaque(true); label.setbackground(color);

68 label.setpreferredsize(new Dimension(width, height)); label.setminimumsize(new Dimension(width / 2, height / 2)); label.setmaximumsize(new Dimension(width * 2, height * 2)); return label; który jest prawie identyczny z poprzednim przykładem, ale powinieneś zauważyć, jak createwindow () wstawia spacje między komponentami. Ważną rzeczą w tym przykładzie jest to, że niebieska etykieta podąża za prawą krawędzią okna. Na koniec ostatni przykład (Przykład 11), który otwiera następujące okno dialogowe: Okno umieszcza trzy komponenty za pomocą BoxLayout: 1. a JLabel 2. JScrollPane z polem listy 3. a JPanel z dwoma przyciskami Powinieneś przestudiować kod i zobaczyć, co się stanie, gdy okno zmieni się. ĆWICZENIE 8 Musisz napisać program, który możesz wywołać Boxes. Program powinien otworzyć okno, jak pokazano poniżej, pokazujące 12 komponentów JLabel w różnych kolorach. Program nie wykonuje żadnych czynności i nie powinno być obsługi zdarzeń. Projekt jest panelem z BoxLayout, który zawiera dwa inne panele z BoxLayout (lewy i prawy). Ponadto zastosuj następujące - Komponenty muszą mieć stały rozmiar. - Pionowo pomiędzy komponentami musi być przerwa 5. - Po zmianie rozmiaru okna 6 komponentów po prawej stronie musi podążać za prawą krawędzią okna, natomiast 6 dolnych elementów musi podążać za dolną krawędzią okna.

69 6.7 NULL LAYOUT Powyżej wspomniałem o najważniejszych menedżerach layoutu Javy, ale faktycznie można umieszczać komponenty w oknie bez użycia menedżera układu. Jeśli w programie demonstracyjnym klikniesz przycisk Układ NULL, pojawi się następujące okno dialogowe, które ma sześć komponentów (przyciski nie mają żadnej funkcji) package layoutpanels; import java.awt.*; import javax.swing.*; public class NulllayoutView extends JDialog public NulllayoutView() super(null, "Null Layout", Dialog.ModalityType.MODELESS); setsize(340, 200); setresizable(false); this.setlocationrelativeto(null); setdefaultcloseoperation(dispose_on_close); createwindow(); setvisible(true); private void createwindow()

70 setlayout(null); addcomponent(this, new JLabel("Zip code"), 20, 20, 100, 20); addcomponent(this, new JLabel("Town"), 20, 60, 100, 20); addcomponent(this, new JTextField(), 100, 20, 50, 20); addcomponent(this, new JTextField(), 100, 60, 220, 20); addcomponent(this, new JButton("Cancel"), 230, 110, 90, 24); addcomponent(this, new JButton("OK"), 120, 110, 90, 24); private void addcomponent(container container, Component component, int left, int top, int width, int height) component.setbounds(left, top, width, height); container.add(component); Pierwsza instrukcja w createwindow () ustawia menedżera układu na wartość null, co oznacza, że okno nie ma menedżera układu. Następnie metoda dodaje komponenty za pomocą metody addcomponent (). Określa rozmiar i położenie komponentów za pomocą metody setbounds (), gdzie dwa pierwsze parametry to lewy górny róg lokalizacji komponentu w panelu, a dwa ostatnie parametry to szerokość i wysokość. Oznacza to, że składnikowi przypisuje się bezwzględną pozycję i rozmiar. Wartości te można również przypisać za pomocą setlocation () i setsize (). Generalnie zaleca się użycie menedżera układu, ponieważ rozmiary tego komponentu mogą obejmować na przykład obecną czcionkę. Jeśli używasz określonej czcionki i rozmiar okna się nie zmienia (zauważ, że nie jest to możliwe w powyższym przykładzie), użycie komponentów na ustalonych pozycjach jest jednak możliwe. PROBLEM 1 Musisz napisać program, który jest programem obliczania pożyczki, a więc program, w którym użytkownik może wprowadzić kwotę pożyczki, stopę procentową i liczbę peridos. Program powinien następnie obliczyć płatność, gdy pożyczka jest dożywotnia. Należy wspomnieć, że istnieje wiele takich programów w Internecie, z którymi można porównać wynik. Renta roczna to pożyczka, która jest amortyzowana stałą opłatą w każdym okresie. Płatność składa się z odsetek i spłaty, a na początku

71 stanowi dużą część odsetek płatniczych, a mniejsza część to spłata. Sytuacja ta zmienia się w sposób ciągły, dlatego pod koniec okresu kredytowania, największą część płatności stanowi spłata. Jeśli - G = pożyczka - y = płatność - n = liczba kropek - r = stopa procentowa zależność między pożyczką a płatnością wynika z następującej formuły: Ta formuła zakłada, że stopa oprocentowania jest stała przez cały okres pożyczki, a pierwsza płatność musi nastąpić 1 okres po otrzymaniu pożyczki i należy założyć, że te założenia mają zastosowanie. Poniższa formuła określa zaległy dług natychmiast po zapłaceniu kaucji: Program musi otworzyć okno, w którym należy wpisać: - koszt tworzenia pożyczki - wielkość pożyczki - stopa procentowa w procentach pro ano - okres spłaty w latach - liczba okresów w roku Korzystając z tych informacji, program musi obliczyć płatność. Ponadto powinno być możliwe otwarcie okna, które pokazuje amortyzację, a tym samym przegląd pożyczki, która dla każdego okresu pokazuje płatność, odsetki, spłatę i zadłużenie po tym terminie. 6.8 MVC Kiedy zapoznasz się z moim rozwiązaniem powyższego problemu, koncentruję się przede wszystkim na architekturze programu i używanych klasach. Program można napisać inaczej - i prostsze - ale wybrana architektura jest krokiem w kierunku wzorca projektowego dla programu GUI, który jest wywoływany dla MVC dla kontrolera widoku modelu. W książce Java 7 powrócę do tego wzorca i chociaż wzorzec jest najpierw traktowany w tej książce, już zacznę go używać. Wzór jest bardzo prosty i oznacza opracowanie programu GUI z trójwarstwową architekturą

72 gdzie model składa się z klas, które definiują dane i stan programu, podczas gdy warstwa kontrolera ma klasy, które głównie wykonują kontrolę wpisów itp. i opcjonalnie ma również podstawowe funkcje obliczeniowe (logika biznesowa). Wreszcie, warstwa widoku ma wszystkie klasy dla interfejsu użytkownika, a tym samym dla okien i okien dialogowych. Celem tego wzoru jest oddzielenie kodu tak, aby kod dotyczący danych programu został umieszczony w klasach w modelu, a kod używany do kontroli danych i operacje logiczne są umieszczane w warstwie kontrolnej, podczas gdy sama warstwa widoku musi zawierać kod co ma związek z reprezentacją wizualną i interakcją użytkownika. Dopasowuje się do wzorca otrzymujesz kod, który może być nieco większy, ale w zamian jest o wiele łatwiejszy do odczytania i zrozumienia. Będę w następnych książkach, kiedy nieco większe programy zaczną używać wzorca, i jak dotąd jest to tylko kwestia podziału klas programu na warstwy logiczne, i chociaż nie brzmi to zbyt mocno, to wzór okazał się bardzo odpowiednie jako architektura dla programu GUI. Dlatego też w niewielkim stopniu zacznę używać wzorca tylko jako drogi do rozsądnego podziału kodu. Jest dużo więcej do powiedzenia na temat MVC, włączając w to sposób, w jaki każda warstwa powinna komunikować się z innymi, i może być też kilka warstw, ale szczegóły odłożę na książkę Java 7. 7 PAEDIT W tej sekcji pokażę program, który jest prostym edytorem tekstu, a więc programem, w którym użytkownik może wprowadzać tekst i zapisywać tekst w pliku. Program jest stosunkowo prosty i ma tylko jedno okno. Układ jest rozwiązany za pomocą jednego BorderLayout, a w odniesieniu do programów GUI program pokazuje głównie: - jak tworzyć i używać menu - jak utworzyć i użyć paska narzędzi - jak używać komponentu JTextArea - jak korzystać z gotowych okien dialogowych z interfejsu API Swing - jak korzystać ze schowka Odnosząc się do punktu 4 wcześniej pokazałem użycie JOptionPane.showMessageDialog (), ale klasa JOptionPane ma inne okna dialogowe, których użyję. Ponadto pokazuję użycie klasy JFileChooser, która implementuje okno dialogowe do przeglądania systemu plików. Program wymaga odczytywania i zapisywania pliku tekstowego, aw książce Java 1 wyjaśniłem, jak to zrobić. W rzeczywistości program nie zajmuje się zbytnio algorytmami, a co za tym idzie rozwiązywaniem problemów, więc większość programu zajmuje się pisaniem tekstu do pliku i odczytaniem tekstu z pliku, a to jest coś, co trzeba wziąć pod uwagę, ale z tyłu to wszystko, istnieje wiele szczegółów, które najpierw mogę wyjaśnić w późniejszym czasie. Podobnie jak to zostało powiedziane powyżej, program ma bardzo prostą architekturę, składającą się z widoku i modelu, a zdecydowanie większość kodu programu znajduje się w widoku. Program ma dwupoziomową architekturę. 7.1 MODEL Model składa się tylko z jednej klasy o nazwie Document, która zawiera plik tekstowy, a tym samym reprezentuje dokument, który program musi mieć możliwość edycji. Klasa jest napisana w następujący sposób: package paedit; import java.io.*; public class Document

73 private String text; // the documents text private File file; // object that represents the document's file public Document() text = ""; file = null; public Document(File file) throws Exception BufferedReader reader = null; try StringBuilder builder = new StringBuilder(); reader = new BufferedReader(new FileReader(file)); for (String line = reader.readline(); line!= null; line = reader.readline()) builder.append(line); builder.append("\n"); text = builder.tostring(); this.file = file; catch (Exception ex) text = ""; this.file = null; throw new Exception("The content of the file could not be read"); finally if (reader!= null) reader.close(); public String gettext()

74 return text; public void settext(string text) this.text = text; public boolean save() if (file == null) return false; else return save(file); public boolean save(file file) BufferedWriter writer = null; try writer = new BufferedWriter(new FileWriter(file)); writer.write(text); this.file = file; return true; catch (Exception ex) return false; finally if (writer!= null) try writer.close(); catch (Exception ex)

75 Istnieją dwie zmienne, z których pierwsza dotyczy tekstu, a druga reprezentuje plik i jest obiektem File, który reprezentuje ścieżkę do pliku. Domyślny konstruktor tworzy pusty dokument, jeszcze nie zapisany i powiązany z plikiem. Inny konstruktor ma parametr, który jest obiektem File, a konstruktor próbuje odczytać zawartość tego pliku jako tekst. Większość metod dotyczących plików może powodować wyjątki, ponieważ może być wiele przyczyn, dla których nie można poprawnie wykonać określonej operacji na plikach. Przykładowo może się zdarzyć, że plik nie istnieje lub że nie masz prawa go otworzyć. Dlatego stwierdzenia dotyczące plików prawie zawsze są umieszczane w blokach try / catch. W tym przypadku konstruktor generuje wyjątek, jeśli nie można odczytać zawartości pliku z tego czy innego powodu. Plik tekstowy można odczytać za pomocą BufferedReader, obiektu czytającego wiersz pliku po linii. Podczas czytania linii są dodawane do StringBuilder, który służy do budowania dokumentu. Jeśli wystąpi błąd, konstruktor przechodzi do bloku catch, a wynikiem jest ponownie pusty dokument. Metoda save () próbuje zapisać zawartość (dokument) w pliku, ale jest to możliwe tylko wtedy, gdy plik zmiennej odnosi się do pliku. Jeśli nie, metoda zwraca wartość false. W przeciwnym razie metoda wywoła inną metodę save (), ale z parametrem File. Wygląda jak konstruktor, a ty piszesz tekst do pliku przy użyciu BufferedWriter. Tekst zapisywany jest metodą write (), która zapisuje cały tekst jako całość, a także wszystkie linie podziału. Zwróć uwagę, że klasa posiada także metody pobierania i ustawiania tekstu zmiennej, taki widok programu może odczytać tekst i zaktualizować go ponownie. 7.2 WIDOK Warstwa widoku programu ma dwie klasy: klasę MainView i klasę Narzędzia. Ostatnia to prosta klasa, która zawiera kilka narzędzi, które mogą być również zainteresowane innymi programami. Jeśli wykonasz program, otworzy się okno pokazane poniżej, gdzie na górze znajduje się menu i pasek narzędzi, a na dole linia statusu (jest pusta po uruchomieniu programu). Środek to komponent JTextArea, czyli pole wejściowe, takie jak JTextField, ale pole, w którym można wprowadzić więcej linii.

76 NARZĘDZIA KLASY Program ma klasę Narzędzia, które ma tylko statyczne elementy, co oznacza, że członkowie mogą być wymieniani bez obiektu typu Narzędzia: package paedit; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Tools public static Font deffont = new Font("Liberation Sans", Font.PLAIN, 14); public static Font txtfont = new Font("FreeMono", Font.PLAIN, 16); public static Color statusline = new Color(240, 240, 240); public static ImageIcon createimageicon(string path, int width) java.net.url imgurl = Tools.class.getResource(path); if (imgurl!= null) return new ImageIcon( new ImageIcon(imgURL, "").getimage().getscaledinstance( width, width, Image.SCALE_SMOOTH), ""); return null; public static JButton createcommand(icon icon, String tooltip, ActionListener listener) JButton cmd = new JButton(); cmd.setfont(deffont); cmd.seticon(icon); cmd.setmargin(new Insets(0, 0, 0, 0)); cmd.settooltiptext(tooltip); cmd.addactionlistener(listener); return cmd; Początkowo zdefiniowane są trzy stałe, w których pierwsze dwa definiują czcionkę odpowiednio do domyślnej i przycisków. Trzeci definiuje kolor paska stanu. W wielu kontekstach użytkownik musi chcieć kontrolować czcionki i kolory, okno musi się stosować i zaleca się zdefiniowanie tego rodzaju wartości jako stałych, jak pokazano powyżej, ponieważ w ten sposób można łatwo zmienić wartości i jako takie może również używać ich w wielu oknach. Klasa ma również dwie metody, które są trudne do zrozumienia (ponownie, ponieważ wciąż brakuje wielu szczegółów Java), więc powinieneś w dużej mierze zaakceptować je takimi, jakie są. Pierwszy służy do załadowania ikony z pliku jar aplikacji. Te dwa parametry to nazwa obrazu i rozmiar ikony. Pierwsza instrukcja definiuje odniesienie do obrazu w pliku jar, podczas gdy następna instrukcja tworzy ikonę i skaluje ją do pożądanego rozmiaru. Ostatnia

77 metoda tworzy przycisk z ikoną i kojarzy procedurę obsługi zdarzenia dla przycisku. Ponadto do przycisku dodawana jest etykietka narzędzia. MENU Łatwo jest dodać menu do okna. Menu to po prostu zbiór przycisków, po prostu pokazany w inny sposób jako element menu, ale efekt jest taki sam, że można kliknąć element menu i element wysyła ActionEvent. Menu musi być zdefiniowane i może wypełnić dużo, ale poniżej pokazuje, w jaki sposób menu jest zdefiniowane i MainView w tym przypadku: private void createmenu() JMenuBar menubar = new JMenuBar(); menubar.add(createfilemenu()); menubar.add(createeditmenu()); setjmenubar(menubar); private JMenu createfilemenu() JMenu menu = new JMenu("Files"); menu.add(createmenuitem("new document", this::blank)); menu.add(createmenuitem("open document", this::open)); menu.add(createmenuitem("savve document", this::save)); menu.add(createmenuitem("save document as", this::saveas)); menu.addseparator(); menu.add(createmenuitem("exit", this::close)); return menu; private JMenu createeditmenu() JMenu menu = new JMenu("Edit"); menu.add(createmenuitem("copy", this::copy)); menu.add(createmenuitem("paste", this::paste));

78 menu.add(createmenuitem("cut", this::cut)); menu.addseparator(); menu.add(createmenuitem("search", this::search)); return menu; private JMenuItem createmenuitem(string text, ActionListener listener) JMenuItem item = new JMenuItem(text); item.addactionlistener(listener); return item; W zasadzie kod jest dość prosty i łatwy do zrozumienia. Istnieją trzy składniki. Menu to JMenuBar, który jest składnikiem, który zawiera menu i może zostać dodany do okna i automatycznie znajduje się w górnej części okna. Pasek JMenuBar jest dodawany do okna za pomocą metody setjmenubar (). Drugim komponentem jest JMenu i reprezentuje menu, podczas gdy ostatnie jest JMenuItem i reprezentuje element menu. Powinieneś zauważyć, że przypisujesz detektor w taki sam sposób jak przypisujesz słuchacza do przycisku. Poszczególne procedury obsługi zdarzeń są zapisywane na końcu klasy. NARZĘDZIA TOOLBAR Okno programu ma pasek narzędzi, który jest jedynie kontenerem, który może zawierać komponenty. W tym przypadku są cztery przyciski, ale przyciski nie są tym razem reprezentowane przez tekst, ale obraz. Każda z tych kontrolek zawiera obraz (ikonę), który musi być dostępny dla programu. Można to zrobić na kilka sposobów, ale jeśli, jak tutaj są to małe ikony, możesz skorzystać z następującej procedury: 1. dodaj pakiet do projektu NetBeans - w tym przypadku jest to pakiet dodatkowy do programu paedit o nazwie images, a po utworzeniu pakietu jest to nazwa paedit.images 2. skopiuj obrazy do odpowiedniego folderu (zdjęcia w folderze mają w tym przypadku 4 pliki png) Zaletą tej metody jest to, że ikony są pakowane razem z plikami klas w pliku jar projektu. Następnie znajduje się pasek narzędzi, który jest zdefiniowany w następujący sposób: private JToolBar createtoolbar() JToolBar toolbar = new JToolBar(); toolbar.setbackground(tools.statusline); toolbar.add(tools.createcommand( Tools.createImageIcon("/paedit/images/copy.png", 26), "Copy text to the clip board", this::copy )); toolbar.addseparator(new Dimension(10, 10)); toolbar.add(tools.createcommand( Tools.createImageIcon("/paedit/images/paste.png", 26), "Insert text from the clip board", this::paste )); toolbar.addseparator(new Dimension(10, 10));

79 toolbar.add(tools.createcommand( Tools.createImageIcon("/paedit/images/cut.png", 26), "Delete text and copy the text to the clip board", this::cut )); toolbar.addseparator(new Dimension(20, 20)); toolbar.add(tools.createcommand( Tools.createImageIcon("/paedit/images/search.png", 26), "Search the document", this::search )); toolbar.setpreferredsize(new Dimension(0, 36)); return toolbar; Tutaj używam metod z klasy Narzędzia i przede wszystkim powinieneś zauważyć, jak się odnosi do poszczególnych obrazów. Obraz jest zasobem w pliku jar aplikacji i musisz podać ścieżkę prowadzącą do bieżącego obrazu, ścieżka jest względna w stosunku do projektu. Zwróć też uwagę na użycie tych samych procedur obsługi zdarzeń, które zostały użyte w menu. Klasa JTextArea obsługuje również kopiowanie / wklejanie, więc nie ma potrzeby używania przycisków, ale są one uwzględniane, ponieważ celem jest pokazanie, jak utworzyć pasek narzędzi. W tym przypadku zawiera przyciski paska narzędzi, ale może zawierać dowolne inne składniki. LINIA STATUSU W rzeczywistości nie jest to prawdziwy pasek stanu, ale tylko JLabel, który może wyświetlać wyrównany do lewej strony tekst: private JLabel createstatus() JLabel label = new JLabel(); label.setfont(tools.deffont); label.setopaque(false); label.setbackground(tools.statusline); label.sethorizontalalignment(jlabel.left); label.setpreferredsize(new Dimension(0, 25)); return label; Przypisanie z etykietą to metoda, która służy do aktualizacji tekstu: private void setstatus() status.settext(string.format("%d linje, %d tegn", txtdoc.getlinecount(), txtdoc.gettext().length()+ 1)); Odnosi się do komponentu JTextArea o nazwie txtdoc, a wiersz stanu pokazuje liczbę linii i liczbę znaków wprowadzonych w polu. UKŁAD MainView definiuje cztery zmienne instancji: private JTextArea txtdoc = new JTextArea(); private JLabel status;

80 private Document doc = new Document(); private boolean changed = false; Pierwszym z nich jest komponent JTextArea, który jest komponentem, w którym można wprowadzać i edytować dowolną liczbę wierszy tekstu, a więc dowolny dokument. Następny jest JLabel do linii statusu, a trzeci to Dokument, a następnie model. Ostatni śledzi, czy dokument został zmieniony. Metoda createwindow () jest podobna do poprzednich przykładów i definiuje projekt okna: private void createwindow() createmenu(); setlayout(new BorderLayout()); JPanel panel = new JPanel(new BorderLayout()); panel.setborder(new EmptyBorder(3, 3, 3, 3)); panel.add(createtoolbar(), BorderLayout.NORTH); panel.add(status = createstatus(), BorderLayout.SOUTH); panel.add(createfield()); add(panel); txtdoc.requestfocus(); Pierwsza instrukcja tworzy i dodaje menu do okna. W przeciwnym razie składa się tylko okno JPanel z BorderLayout, który NORTH ma pasek narzędzi, SOUTH ma pasek stanu (powyższa etykieta), natomiast komponent JTextArea zamknięty w JScrollPane wypełnia resztę okna. Następująca metoda inicjuje składnik txtdoc, który jest edytorem: private JScrollPane createfield() txtdoc.setfont(tools.txtfont); txtdoc.setwrapstyleword(true); txtdoc.setlinewrap(true); txtdoc.addkeylistener(new TextChanged()); return new JScrollPane(txtDoc); Metoda definiuje tekst do zawijania do następnej linii, gdy linia nie ma miejsca na więcej, a podział musi być wykonany na granicach słów. Na końcu dołączony jest KeyListener, program obsługi zdarzeń, który jest wykonywany za każdym naciśnięciem klawisza. Ustawia zmienną zmienioną na true, co oznacza, że dokument się zmienił, a następnie wywołał metodę setstatus (), która aktualizuje wiersz statusu o bieżącą liczbę linii i bieżącą liczbę znaków:

81 class TextChanged extends KeyAdapter public void keytyped(keyevent e) changed = true; setstatus(); Procedura obsługi zdarzenia jest zdefiniowana jako metoda w klasie dziedziczącej KeyAdater. Po naciśnięciu klawisza JTextArea podnosi więcej zdarzeń, a KeyAdapter klasy jest klasą implementującą interfejs KeyListener definiujący trzy procedury obsługi zdarzeń dotyczące klawiatury. KeyAdapter implementuje te procedury obsługi jako puste metody, a następnie można napisać klasę, która przesłania te procedury obsługi, których chcesz użyć. Zwróć uwagę, że to jest dokładnie ta sama zasada, której użyłem w poprzednich zdarzeniach związanych z programem, dotyczących zmiany rozmiaru okna, a także użyłeś tej samej zasady w ćwiczeniu 4, aby złapać zdarzenie, gdy dwukrotnie klikniesz na pozycji w polu listy. OBSŁUGA ZDARZEŃ Wreszcie jest 8 programów obsługi zdarzeń (8 pozycji menu). Poniżej znajduje się obsługa zdarzeń, która otwiera dokument: private void open(actionevent e) if (changed && JOptionPane.showConfirmDialog(this, "The document is changed. Should document be saved?", "Warning", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION) save(); JFileChooser filechooser = new JFileChooser(); filechooser.setcurrentdirectory(new filechooser.setdialogtitle("open text document"); File(System.getProperty("user.home"))); if (filechooser.showopendialog(this) == JFileChooser.APPROVE_OPTION) File file = filechooser.getselectedfile(); try doc = new Document(file); txtdoc.settext(doc.gettext()); changed = false; catch (Exception ex)

82 JOptionPane.showMessageDialog(this, "The document could not be opened", "Error message", JOptionPane.OK_OPTION); txtdoc.settext(""); changed = false; setstatus(); Pierwsza instrukcja sprawdza, czy bieżący dokument jest modyfikowany. W tym przypadku otwiera popup, ale tym razem jest to okno dialogowe potwierdzenia, okno dialogowe z przyciskiem Tak i Nie, a użytkownik zostanie zapytany, czy dokument ma zostać zapisany. W takim przypadku wywoływana jest metoda save (), która zapisuje dokument. Następnie zdefiniowałem JFileChooser, który otwiera okno dialogowe, w którym możesz przeglądać system plików dla pliku, który chcesz otworzyć. Akceptując plik, otrzymujesz obiekt File reprezentujący ścieżkę pliku, a obiekt jest używany w konstruktorze w dokumencie klasy, aby otworzyć plik. Następnie pole wejściowe jest inicjowane z zawartością pliku. Należy zauważyć, że tworzenie dokumentu jest umieszczane w try / catch, ponieważ konstruktor klasy Dokument może podnieść wyjątek. Program obsługi zdarzeń prawdopodobnie wywoła metodę save () private void save() doc.settext(txtdoc.gettext()); if (doc.save()) changed = false; else saveas(); Ta metoda kopiuje zawartość pola wejściowego do modelu i prosi model, aby zapisał tekst z powrotem do pliku przy użyciu metody save () modelu. Czy nie jest możliwe (ponieważ jest to nowy dokument, który nie został zapisany) metoda wywołuje saveas (), w której użytkownik ponownie używający obiektu JFileChooser będzie mógł przeglądać system plików i wprowadzać nazwę pliku. Programy obsługi zdarzeń Save, Saveas i New Document działają w zasadzie w ten sam sposób i nie będę tu pokazywał kodu. Następnie są trzy programy obsługi zdarzeń dotyczące schowka. Poniżej znajduje się przewodnik, który kopiuje tekst do schowka: private void copy(actionevent e) try String text = txtdoc.getselectedtext(); Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); cb.setcontents(new StringSelection(text), null);

83 catch (Exception ex) JOptionPane.showMessageDialog(this, "Text could not be copied to the clipboard", "Error message", JOptionPane.OK_OPTION); Najpierw zaznaczony tekst jest zapisany w zmiennej. Następnie zdefiniuj odwołanie do schowka, a tekst zostanie zapisany w obiekcie typu StringSelection, a ten obiekt zostanie zapisany w schowku. Następny moduł obsługi wstawia tekst zapisany w schowku w dokumencie: private void paste(actionevent e) try Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable data = cb.getcontents(this); if (data == null) return; String str = (String)data.getTransferData(DataFlavor.stringFlavor); String text = txtdoc.gettext(); int p = txtdoc.getselectionstart(); int q = txtdoc.getselectionend(); if (q > p) txtdoc.settext(q < text.length()? text.substring(0, p) + str + text.substring(q + 1) : text.substring(0, p) + str); else p = txtdoc.getcaretposition(); txtdoc.settext(text.substring(0, p) + str + text.substring(p)); changed = true; setstatus(); catch (Exception ex) JOptionPane.showMessageDialog(this, "The text could not be pasted from the clipboard", "Error message", JOptionPane.OK_OPTION);

84 Program obsługi najpierw definiuje odwołanie do schowka, a wartość jest traktowana jako obiekt typu Zbywalne. Obiekt jest konwertowany na ciąg za pomocą metody gettransferedata (). Ten ciąg musi zostać wstawiony do pola wejściowego, aby zastąpić wybrany tekst lub wstawić w miejscu kursora. Funkcja obsługi zdarzenia cut () działa w zasadzie w ten sam sposób. Back to program obsługi zdarzeń do wyszukiwania: private void search(actionevent e) String str = JOptionPane.showInputDialog(this, "Enter a search text", "Search", JOptionPane.INFORMATION_MESSAGE); if (str!= null && str.length() > 0) String text = txtdoc.gettext(); int p = text.indexof(str); if (p >= 0) txtdoc.select(p, p + str.length()); txtdoc.requestfocus(); else JOptionPane.showMessageDialog(this, "The text does not exist", "Information", JOptionPane.OK_OPTION); Nie działa tak, jak powinien, ponieważ znajduje tylko pierwsze wystąpienie ciągu wyszukiwania. Jest to ograniczenie JTextArea. Kod jest łatwy do zrozumienia, ale musisz wprowadzić tekst wyszukiwania. W tym celu używane jest okno dialogowe wprowadzania, które jest prostym wyskakującym okienkiem, w którym można wpisać ciąg znaków, a wyskakujące okienko otwiera się za pomocą metody showinputdialog (), która jest metodą w klasie JOptionPane. Kiedy okno jest zamknięte (i program się zatrzymuje), chcę sprawdzić, czy dokument został zmieniony i ewentualnie powinien zostać zapisany. W tym celu napisałem wewnętrzną klasę, która implementuje procedurę obsługi zdarzenia, które zamyka okno: class WindowCloser extends WindowAdapter public void windowclosing(windowevent e) if (changed && JOptionPane.showConfirmDialog(MainView.this, "The document is changed. Do you want to save it?", "Warning", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) save();

85 W kodzie nie ma tajemnicy, ale okno musi być zdefiniowane jako detektor zdarzenia, które ma miejsce w konstruktorze: addwindowlistener (new WindowCloser ()); TEST Po zakończeniu programu należy go przetestować. W tym przypadku nie ma wiele więcej do roboty niż próba skorzystania z programu. Jednak może być trudno zapewnić, że zostaną przetestowane wszystkie sytuacje, które mogą wystąpić. Tutaj może pomóc stworzyć plan testów, w którym zapisujesz, co chcesz przetestować. Naturalnie nie daje żadnej gwarancji, ale po części samo napisanie planu oznacza, że przemyślisz to, co musisz przetestować, a po drugie pomaga pamiętać o tym, by zdobyć wszystkie punkty, gdy wykonujesz test. Plan testów może na przykład wyglądać następująco: 1. wizualny wygląd i sposób działania programu 2. wprowadź dokument 3. zapisz dokument 4. wprowadź więcej tekstu w tym samym dokumencie 5. zapisz ponownie 6. zamknij program 7. otwórz ponownie dokument 8. edytuj zawartość 9. zapisz dokument 10. skopiuj tekst do schowka 11. wklej tekst w dokumencie bez zastępowania 12. wklej tekst w dokumencie i zastąp wybrany tekst 13. wytnij zaznaczony tekst 14. wklej ponownie tekst w dokumencie 15. skopiuj tekst z innego programu do tego programu 16. przetestuj funkcję wyszukiwania 17. zapisz dokument 18. Utwórz nowy dokument 19. ponownie otwórz dokument testowy

86 20. zmodyfikuj dokument 21. zamknij program bez zapisywania dokumentu 22. otwórz ponownie program 23. otwarty testowy dokument 24. otwórz inny dokument tekstowy, jako przykład programu java 25. otwórz dokument, który nie jest tekstem Później zajmuję się programami testującymi, ale prosty plan testowy jak wyżej jest lepszy niż nic. Należy jednak mieć świadomość, że w przypadku stwierdzenia błędów podczas testu, błędy należy oczywiście skorygować, a następnie powtórzyć test - wszystkie punkty w planie testowym ponownie - i powtórzyć proces do czasu ukończenia testu bez błędów. 8 PRZYKŁAD KOŃCOWY Zadanie polega na napisaniu programu symulującego pasjansa. Jest to bardzo prosta gra w pasjansa, w której zasady są następujące: Na stole jest 16 kart. Następnie należy usunąć karty według dwóch kryteriów: 1. karty tego samego koloru o wartości mniejszej niż 10, i gdzie suma wartości karty wynosi 15 (czyli jako przykład as, pięć i dziewięć w tym samym kolorze lub siedem i osiem w tym samym kolorze) 2. 10, Jopek, Dama i Król tego samego koloru Po usunięciu kart nieużywane miejsca muszą zostać wypełnione kartami z talii - o ile jest więcej kart. Pasjans jest rozwiązywany, gdy wszystkie karty są usuwane, ale kiedy dojdziesz do sytuacji, w której nie możesz usunąć kart, oznacza to, że pasjans nie może zostać rozwiązany. 8.1 KLASY PROGRAMU Zasadniczo jest to bardzo prosty program, w którym interfejs użytkownika musi wyświetlać obrazy kart do gry, które użytkownik powinien następnie kliknąć myszką. Program nie ma w zasadzie żadnych innych funkcji, ale musi istnieć możliwość wyboru nowej gry. Należy sprawdzić, które karty znajdują się na stole, które pozostały w talii i które zostały zabrane, oraz w tym celu program powinien zdefiniować model, który zawsze reprezentuje aktualny stan programu. Program musi więc w zasadzie działać w ten sposób, że gdy użytkownik kliknie na kartę, wiadomość zostanie wysłana do modelu, na którym kliknięta jest karta, a model powinien następnie od zaznaczonych kart określić, czy karty są w stanie usunięty ze stołu zgodnie z zasadami pasjansa. W takim przypadku model musi usunąć karty ze stołu i wybrać nowe karty z talii. Podstawową koncepcją programu jest karta do gry, która jest bardzo prostą koncepcją. Karta do gry musi mieć trzy cechy: 1. wartość, która musi być liczbą od 1 do 13: 1 = as, 11 = Jopek, 12 = Królowa i 13 = Król 2. kolor, który powinien być postacią: D (karo), H (kier), S (pik) C (trefl) 3. obraz karty W przeciwnym razie karta jest pasywna i można ją zdefiniować w następujący sposób:

87 Oprócz karty do gry naturalnie jest myśleć o talii 52 kart. To niewiele więcej niż tablica 52 obiektów Card i zmienna, która może śledzić, ile kart zostało w talii: Pierwsza metoda powraca, gdy talia jest pusta, a następna liczba kart pozostała w talii. Trzecia metoda zwraca i usuwa kartę znajdującą się na wierzchu talii i tak samo symuluje, że krupier dzieli kartę. Ostatnia metoda tasuje karty i powinna być używana przy wyborze nowej gry. Model musi mieć przedmiot typu Karty, a tym samym talię kart. Do kontrolowania stanu gry potrzebne są trzy struktury danych - listę kart, które zostały pobrane - tablica, która śledzi, które karty są na stole - tablica, która śledzi, która z kart na stole jest oznaczona, a tym samym można zarysować klasę modelu w następujący sposób: Klasa ma tylko dwie podstawowe metody, gdzie move () jest najważniejsza i jest używana za każdym razem, gdy użytkownik kliknie kartę. Metoda reset () służy do wyboru nowej gry. Projekt programu będzie składał się z następujących klas:

88 8.2 PROGRAMOWANIE Punktem wyjścia jest projekt NetBeans o nazwie Solitaire16. Aby napisać program, musisz mieć zdjęcia kart do gry. Folder tej książki ma pakiet z kartami imiennymi. tar.gz zawierający obrazy kart. Oprócz 52 kart, istnieją również dwie karty boczne i ikona do użycia na prostym pasku narzędzi. Aby zdjęcia zostały spakowane w pliku jar aplikacji, utworzyłem pakiet o nazwie solitaire16.images, rozpakowałem plik tar i skopiowałem wszystkie obrazy do tego folderu. WARSTWA MODELU Warstwa modelowa składa się z trzech klas, o których mowa powyżej, a karta klasy jest banalna i nie jest dalej dyskutowana. To samo dotyczy kart klas, ale to ta klasa musi ładować obrazy na karty, a do tego dodałem klasę pomocniczą z metodą, która może załadować obraz z pliku JAR: package solitaire16; import java.awt.color; import javax.swing.*; public class Tools public static Color selected = Color.darkGray; public static ImageIcon createimage(string path, String description) java.net.url imgurl = Cards.class.getResource(path); if (imgurl!= null) return new ImageIcon(imgURL, description); return null; Klasa naprawdę nie należy do warstwy modelu, ponieważ jej celem jest tworzenie obiektów ImageIcon, które są obiektami należącymi do interfejsu użytkownika. Ogólnie granica między warstwami modelu i widoku w bieżącym rozwiązaniu nie jest dość ostra, ponieważ klasy w warstwie modelu używają obiektów należących do warstwy widoku, a program nie spełnia wtedy zasady stojącej za modelem MVC jako modelem warstwa w sposób zna warstwę widoku. Można stworzyć inny projekt programu, w którym klasy w warstwie modelu nie znają obrazów, ale można również przyjąć obecne rozwiązanie programu jako przykład tego, jak dobre są wzorce i zasady, ale odwrotnie, nie należy komplikować kod

89 tylko po to, aby zachować zgodność z wzorcem. Dzięki dostępnej wyżej klasie łatwo jest napisać kod dla kart klasowych. Musi załadować 52 karty do gry do tablicy, a dodatkowo załadować obrazy na dwie tylne karty. Klasa ma również metodę tasowania kart, która odbywa się za pomocą następującego algorytmu: public void shuffle() for (int n = 0; n < 1000; ++n) int i = rand.nextint(array.length); int j = rand.nextint(array.length); Card temp = array[i]; array[i] = array[j]; array[j] = temp; top = array.length; Klasa Model definiuje następujące zmienne instancji: public class Model private Cards deck = new Cards(); // talia kart do użycia private ArrayList<Card> used = new ArrayList(); // karty są pobierane private Card[][] table = new Card[4][4]; // karty na stole private boolean[][] marked = new boolean[4][4]; // karty oznaczone Oprócz tego, co pokazano w projekcie, klasa jest rozszerzona o szereg innych metod, których jedynym celem jest to, aby interfejs użytkownika mógł odczytać stan modelu. Jak wspomniano, metoda move () jest najbardziej skomplikowana, ponieważ jest to metoda sprawdzania, czy karty mogą zostać usunięte z tabeli. Odbywa się to za pomocą następującego algorytmu: jeśli wszystkie karty mają ten sam kolor, obliczyć sumę wartości kart, jeśli jest tam karta twarzy jeśli suma = 46, przenieś karty inne jeśli suma = 15, przenieś karty WIDOK PROGRAMU Interfejs użytkownika zawiera tylko jedną klasę, którą jest MainWindow. Klasa nie zajmuje tak dużo i definiuje następujące zmienne instancji: public class MainWindow rozszerza JFrame private Model model = new Model ();

90 private JLabel [] [] center = new JLabel [4] [4]; private JLabel [] left = new JLabel [36]; private JLabel [] right = new JLabel [52]; Tutaj znajduje się środek kart na stole, lewa jest talia i musi pokazywać, które karty pozostały w talii, a na końcu prawo do kart, które są brane. Na środku widać karty rozłożone nad stołem z przodu, a prawe karty, które są traktowane jako talię. lewy pokazuje tylko kartę pomocniczą: Układ okna to BorderLayout, gdzie NORTH ma pasek narzędzi z jednym przyciskiem, WEST ma talię z kartami, których jeszcze nie rozdano, EAST ma talię z kartami, a na koniec 16 kart na stole to CENTER. Obrazy kart są wyświetlane za pomocą JLabel, które w szczególności mogą wyświetlać obraz. Aby pokazać, że karta jest zaznaczona po kliknięciu, zmienia się kolor tła komponentu JLabel, który zawiera obraz, i pojawia się jako ramka wokół obrazu. Kolor jest zdefiniowany w klasie Narzędzia. Jest to bardzo prosty pasjans, ale stosunkowo trudno jest rozwiązać pasjansa, a ty dostajesz bardzo szybko w sytuacji, w której musisz się poddać, więc nie ma wątpliwości, że nie jest to najbardziej zabawny pasjans. 9 OSTATNI PRZYKŁAD Jak pokazano tutaj, programowanie GUI wymaga wiele linii kodu, a nawet mówimy o kodzie, który jest trudny do zapamiętania. I odwrotnie, przykłady pokazują również, że jest to to samo, co trzeba napisać za każdym razem, lub przynajmniej, że rozwój różnych interfejsów użytkownika ma wiele wspólnych cech. Można ułatwić pracę, tworząc bibliotekę klas, która zawiera klasy z metodami napotkanych zadań, i ta biblioteka może być następnie udostępniona wszystkim programom GUI, które tworzysz. W tej ostatniej części pokażę, jak napisać taką bibliotekę klasową, którą nazwałbym PaLib, a także pokazuję program korzystający z biblioteki. Biblioteka klas jest używana we wszystkich kolejnych książkach, a nie tylko, że biblioteka będzie stale rozbudowywana, a więcej nadchodzących ćwiczeń i problemów faktycznie ma związek z rozszerzeniem biblioteki. Dlatego zachęcamy do uważnego

91 przestudiowania, w jaki sposób tworzona jest biblioteka klas i jak jest ona wykorzystywana w programie Historia, programie testowym, który pokazuję jako ostatni w tym rozdziale. Chociaż program dotyczący programów GUI nie zawiera niczego nowego, jest to jednak właściwy wniosek dotyczący tego wprowadzenia do aplikacji GUI i Swing. 9.1 TWORZENIE BIBLIOTEKI Zasadniczo utworzenie biblioteki klas jest dość proste, aw NetBeans tworzy się projekt w zwykły sposób, po prostu musi to być projekt Java Class Library: Rezultatem jest projekt, który jest pusty, a następnie można rozpocząć dodawanie pakietów i klas. Moja biblioteka ma nazwę PaLib i jak dotąd składa się tylko z jednego pakietu o nazwie palib.gui i jednej klasy o nazwie Tools (se). Klasa składa się wyłącznie z metod statycznych, które są metodami przydatnymi w projektowaniu interfejsów użytkownika. Nie będę tu pokazywał kodu, ponieważ jest obszerny (zajmuje 800 linii), ale wiele linii to komentarze, a metody są prawie wszystkie używane w poprzednich przykładach. Jako przykład pokażę jedną metodę (w kilku przeciążeniach), która pokazuje trochę o tym, co zawiera klasa. Jest to metoda, która tworzy JTextField: /** * Creates and returns a JTextField with the following properties: width The width of the field height The height of the field A JTextField component

92 */ public static JTextField createfield(int width, int height) return createfield(null, JTextField.LEFT, true, width, height, null, null, null); /** * Creates and returns a JTextField with the following properties: text The text that must initialize the field width The width of the field height The height of the field A JTextField component */ public static JTextField createfield(string text, int width, int height) return createfield(text, JTextField.LEFT, true, width, height, null, null, null); /** * Creates and returns a JTextField with the following properties: text The text that must initialize the field width The width of the field height The height of the field font The font to be used A JTextField component */ public static JTextField createfield(string text, int width, int height, Font font) return createfield(text, JTextField.LEFT, true, width, height, font, null, null);

93 /** * Creates and returns a JTextField with the following properties: text The text that must initialize the field alignment The text alignment, can be JTextField.LEFT or JTextField.RIGHT editable Where the contents of the field may be edited or not width The width of the field height The height of the field font The font to be used A JTextField component */ public static JTextField createfield(string text, int alignment, boolean editable, int width, int height, Font font) return createfield(text, alignment, editable, width, height, font, null, null); /** * Creates and returns a JTextField with the following properties: text The text that must initialize the field alignment The text alignment, can be JTextField.LEFT or JTextField.RIGHT editable Where the contents of the field may be edited or not width The width of the field height The height of the field font The font to be used fg The field's text color bg The field's background color A JTextField component */ public static JTextField createfield(string text, int alignment, boolean editable, int width, int height, Font font, Color fg, Color bg) JTextField field = new JTextField(); if (text!= null) field.settext(text);

94 field.sethorizontalalignment(alignment); field.seteditable(editable); if (font!= null) field.setfont(font); if (fg!= null) field.setforeground(fg); if (bg!= null) field.setbackground(bg); field.setpreferredsize(new Dimension(width, height)); return field; Jeśli chodzi o same metody i sposób ich działania, nie ma wiele do wyjaśnienia, ale powiem wam o rozważaniach dotyczących metody createfield (). W praktyce często potrzebuję stworzyć JTextField i często muszę zainicjować kilka właściwości. Dlatego może być użyteczne w przypadku metody, której parametry mają wartości dla właściwości, które mają zostać ustawione, oraz metody, która tworzy i zwraca JTextField z zainicjowanymi tymi właściwościami. Teraz możesz zdefiniować wiele właściwości JTextField, a nie byłoby to właściwe metodami ze wszystkich możliwych kombinacji właściwości, ale ostatnia wersja metody createfield () ma parametry dla najbardziej typowych właściwości - przynajmniej w odniesieniu do programów że piszę. Ponieważ nie ma zawsze potrzeby wszystkich tych parametrów, napisałem kilka metod przeciążania, które mają mniej parametrów. Kiedy trzeba pisać takie klasy bibliotek, najważniejsze są parametry, jakie powinny mieć metody. Z jednej strony metody powinny mieć tak wiele parametrów, aby były wystarczająco elastyczne, aby mogły być wykorzystywane jako narzędzia w wielu aplikacjach. Z drugiej strony nie powinno być tak wielu parametrów, aby było mylące, a metody równie trudne stają się użyteczne. Wybór powinien odzwierciedlać typowe aplikacje, w tym przypadku zazwyczaj muszę stworzyć JTextField. Nie pokażę reszty klasy, ale istnieją podobne metody tworzenia najbardziej podstawowych komponentów Swing. Ponadto istnieją sposoby umieszczania komponentów w pojemnikach. Jest to klasa z narzędziami i naturalne jest, że klasa jest ciągle poszerzana o nowe metody, jak ich potrzebujesz. Podobnie biblioteka klas może zostać rozszerzona o nowe klasy, a jako przykład rozszerzę bibliotekę o klasę, która ma metody zapisu obiektu i odczytu obiektu z pliku. Najpierw rozszerzyłem bibliotekę o nowy pakiet o nazwie palib.util, a tutaj klasę o nazwie Files: W książce Java 1 pokazano sposób przechowywania abritary obiektu w pliku (serializacja obiektów) i jak ponownie odczytać obiekt (deserialization obiektu). Może być trudno zapamiętać, jak napisać instrukcje, a kiedy jest tak samo, to za każdym razem, kiedy opłaca się pisać, należy pisać dwie metody biblioteczne do tych celów: package palib.util; import java.io.*; public class Files public static boolean serialize(object obj, String filename) try

95 ObjectOutputStream stream = new ObjectOutputStream(new FileOutputStream(filename)); stream.writeobject(obj); stream.close(); return true; catch (Exception ex) return false; public static Object deserialize(string filename) try ObjectInputStream stream = new ObjectInputStream(new FileInputStream(filename)); Object obj = stream.readobject(); stream.close(); return obj; catch (Exception ex) return null; 9.2 PROGRAM TESTOWY Na koniec pokażę, w jaki sposób biblioteka klas może być używana w programie. Napisałem program o nazwie Historia, w którym można prowadzić listę osób historycznych. Wymaga to, aby program mógł gdzieś zapisać listę. Gdy program uruchamia się po raz pierwszy, inicjalizuje listę duńskich królów i za każdym razem, gdy lista jest zmieniana, jest przechowywana w pliku na dysku twardym. Gdy program otworzy się następnym razem, zacznie czytać zaktualizowaną listę z pliku - jeśli to możliwe. Inaczej lista zostanie zainicjowana przez duńskich królów. Plik jest przechowywany w tym samym miejscu co

96 program i nie trzeba się uczyć, jak plik jest przechowywany i czytany, ponieważ biblioteka zawiera niezbędne metody. Osoba jest zdefiniowana w następujący sposób (gdzie usunąłem komentarze i wszystkie metody get i set): package history; import java.io.*; public class Person implements Comparable<Person>, Serializable private String name; // the person's name private String job; // the person's position private String text; // a description private int from; // birth, start of reign or otherwise private int to; // year of when the person is dead public Person(String name, String job, String text, int from, int to) this.name = name; this.job = job; this.text = text; this.from = from; this.to = to;. Kiedy czytasz kod, powinieneś zwrócić szczególną uwagę na sposób porównywania obiektów przez metodę compareto (), w której obiekty porównywane są według numerów roku (klasa implementuje interfejs Porównywalna <Osoba>) i zauważ, że klasa implementuje Interfejs Serializable. Należy również zauważyć, że klasa zastępuje equals (), więc ludzie są porównywane wyłącznie na podstawie ich nazw. Następnie jest klasa Osoby reprezentujące listę obiektów Person. package history; import java.util.*; import palib.util.*; public class Persons implements Iterable<Person> private static String filename = "persons.dat"; private ArrayList<Person> list; public Persons()

97 list = (ArrayList<Person>)Files.deserialize(filename); if (list == null) initialize(); public Iterator<Person> iterator() return list.iterator(); public void add(person pers) list.add(pers); Collections.sort(list); Files.serialize(list, filename); public void remove(person pers) list.remove(pers); Files.serialize(list, filename); public void update(person pers) for (Person p : list) if (p.equals(pers)) p.setjob(pers.getjob()); p.settext(pers.gettext()); p.setfrom(pers.getfrom()); p.setto(pers.getto()); break; Files.serialize(list, filename);

98 private void initialize() list = new ArrayList(); for (int i = 0;i < navne.length; ++i) String job = navne[i][0].equals("margrete d. 1.") navne[i][0].equals("margrethe d. 2.")? "Queen" : "King"; int fra = navne[i][1].length() > 0? Integer.parseInt(navne[i][1]) : -9999; int til = navne[i][2].length() > 0? Integer.parseInt(navne[i][2]) : 9999; list.add(new Person(navne[i][0], job, "", fra, til)); Collections.sort(list); private static String[][] navne = "Gorm den Gamle", "", "958", "Harald Blåtand", "958", "986", ; Najpierw zanotuj instrukcję importu import palib.util.*; odnosząc się do pakietu zawierającego pliki klasy. Aby było możliwe, plik jar dla biblioteki klas musi być dostępny dla programu. Uzyskuje się go dla projektu (historii programu), klikając prawym przyciskiem myszy na biblioteki i wybierając opcję Dodaj JAR / Folder... Następnie można przejść do pliku jar biblioteki klas i dodać go do projektu:

99 Teraz aplikacja może używać pliku jar i jego klas. Jeśli teraz budujemy projekt i kopiujemy plik History.jar do innego folderu i próbujemy uruchomić program z okna Terminala, pojawi się komunikat o błędzie, ponieważ program nie może znaleźć biblioteki klas. Biblioteka klas nie jest częścią pliku JAR programu. Jeśli otworzysz folder dist projektu, zobaczysz podkatalog o nazwie lib. Zawiera plik jar do biblioteki klas, a aby uruchomić program, ten podfolder musi również zostać skopiowany. Klasa Osoby jest w zasadzie prosta i powinieneś zauważyć, jak obiekty Osoby są przechowywane w ArrayList, a klasa ma metody, aby dodać element, zaktualizować element i usunąć element. Zauważ, że każda z tych metod serializuje listę przy użyciu metody serialize () w klasie Pliki, które są klasą w bibliotece klas. Najbardziej złożoną w klasie jest konstruktor. Próbuje deserializować listę z pliku. Jeśli to się nie powiedzie, na przykład dlatego, że plik nie istnieje (i rzeczywiście nie działa on po raz pierwszy), lista jest inicjowana za pomocą danych, które są określone w programie (duńscy królowie i ja pokazałem tylko pierwsze dwa ). Listę tworzy się metodą initialize (), która przebiega przez statyczną tablicę z danymi. Powinieneś również zwrócić uwagę na metodę iterator (). Jeśli uruchomisz program, pojawi się okno pokazane poniżej. Okno jest głównym oknem programu i nie będę tu pokazywał kodu, ponieważ nie ma czegoś nowego, ale powinieneś zauważyć, jak klasa używa biblioteki klas do budowy interfejsu użytkownika. Dwukrotne kliknięcie linii (nazwy) na liście powoduje wyświetlenie okna, w którym można zobaczyć wszystkie informacje, edytować je i ewentualnie usunąć osobę (patrz poniżej). Klasa ma nazwę PersonView, gdzie nie będę wyświetlał kodu, ale układ okna jest definiowany przez GridBagLayout, a klasa szeroko korzysta z biblioteki klas. Jeśli w głównym oknie kliknij przycisk Utwórz osobę, otwiera to samo okno, ale wszystkie pola są puste, a następnie można wprowadzić nazwisko osoby, a tym samym dodać nową osobę do listy. Poniżej znajduje się przykład okna PersonView, po dwukrotnym kliknięciu linii na liście:

100 Jeśli masz teraz wiele programów korzystających z biblioteki klas, każdy program musi mieć kopię pliku jar biblioteki klas. Oczywiście nie jest to szczególnie użyteczne i powinno być takie, że istnieje tylko jedna kopia, z której korzystają wszystkie programy.

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Java: otwórz okienko. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak Java: otwórz okienko Programowanie w językach wysokiego poziomu mgr inż. Anna Wawszczak PLAN WYKŁADU klasy wewnętrzne, lokalne i anonimowe biblioteka AWT zestaw Swing JFrame JPanel komponenty obsługa zdarzeń

Bardziej szczegółowo

Kontenery i komponenty graficzne

Kontenery i komponenty graficzne JAVA Kontenery i komponenty graficzne Bibliografia: JAVA Szkoła programowania, D. Trajkowska Ćwiczenia praktyczne JAVA. Wydanie III,M. Lis Opracował: Andrzej Nowak Kontenery Aplikacja okienkowa składa

Bardziej szczegółowo

Java - interfejs graficzny

Java - interfejs graficzny Java - interfejs graficzny Pakiet Swing Pakiet Swing przygotował: pawel@kasprowski.pl Czym jest Swing? Rozszerzenie AWT (Abstract Windows Toolkit) do tworzenia GUI (Graphical User Interface) w Javie import

Bardziej szczegółowo

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem.

WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM. NetBeans. Wykonał: Jacek Ventzke informatyka sem. WYKONANIE APLIKACJI OKIENKOWEJ OBLICZAJĄCEJ SUMĘ DWÓCH LICZB W ŚRODOWISKU PROGRAMISTYCZNYM NetBeans Wykonał: Jacek Ventzke informatyka sem. VI 1. Uruchamiamy program NetBeans (tu wersja 6.8 ) 2. Tworzymy

Bardziej szczegółowo

Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com

Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.com GUI-Swing Wstęp do tworzenia prostych aplikacji z interfejsem graficznym (GUI) przy pomocy Swing, rysowanie prostych

Bardziej szczegółowo

Tworzenie elementów graficznych

Tworzenie elementów graficznych Tworzenie elementów graficznych Elementy graficzne w Javie pozwalające tworzyć Graficzny Interfejs Użytkownika (GUI) możemy podzielić na dwie grupy: AWT (Abstract Window Toolkit) bibliotek klas służąca

Bardziej szczegółowo

Programowanie Obiektowe GUI

Programowanie Obiektowe GUI Programowanie Obiektowe GUI Swing Celem ćwiczenia jest ilustracja wizualnego tworzenia graficznego interfejsu użytkownika opartego o bibliotekę Swing w środowisku NetBeans. Ponadto, ćwiczenie ma na celu

Bardziej szczegółowo

Rozdział 4 KLASY, OBIEKTY, METODY

Rozdział 4 KLASY, OBIEKTY, METODY Rozdział 4 KLASY, OBIEKTY, METODY Java jest językiem w pełni zorientowanym obiektowo. Wszystkie elementy opisujące dane, za wyjątkiem zmiennych prostych są obiektami. Sam program też jest obiektem pewnej

Bardziej szczegółowo

Laboratorium 8 ( Android -pierwsza aplikacja)

Laboratorium 8 ( Android -pierwsza aplikacja) Dr Mirosław Łątka Informatyka dla medycyny Jesień 2012 Laboratorium 8 ( Android -pierwsza aplikacja) Naszym celem jest stworzenie aplikacji, która wyświetla zdjęcie Alberta Einsteina. Jeden z przycisków

Bardziej szczegółowo

Ćwiczenia 9 - Swing - część 1

Ćwiczenia 9 - Swing - część 1 Ćwiczenia 9 - Swing - część 1 Utwórz nowy projekt wybierając: File->New Project->Java Application, przy czym odznacz opcję Create Main Class. Kliknij prawym przyciskiem myszy na podfolder Source Packages

Bardziej szczegółowo

Informatyka I. Interfejs GUI wysokiego poziomu. Biblioteka Swing. Programowanie zdarzeniowe. Politechnika Warszawska Wydział Transportu 2018

Informatyka I. Interfejs GUI wysokiego poziomu. Biblioteka Swing. Programowanie zdarzeniowe. Politechnika Warszawska Wydział Transportu 2018 Informatyka I Interfejs GUI wysokiego poziomu. Biblioteka Swing. Programowanie zdarzeniowe. dr inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2018 Interfejs GUI wysokiego poziomu Pojęcie

Bardziej szczegółowo

Graphic User Interfaces pakiet Swing

Graphic User Interfaces pakiet Swing Graphic User Interfaces pakiet Swing Streszczenie Celem wykładu jest zaprezentowanie podstaw tworzenia graficznych interfejsów przy użyciu pakietu Swing. Czas wykładu 90 minut. Można śmiało stwierdzić,

Bardziej szczegółowo

JAVA. Strumienie wejścia i wyjścia. Pliki - zapis i odczyt

JAVA. Strumienie wejścia i wyjścia. Pliki - zapis i odczyt JAVA Pliki - zapis i odczyt Opracował: Andrzej Nowak Bibliografia: JAVA Szkoła programowania, D. Trajkowska Ćwiczenia praktyczne JAVA. Wydanie III,M. Lis Strumienie wejścia i wyjścia Strumienie wejścia

Bardziej szczegółowo

Przed rozpoczęciem pracy otwórz nowy plik (Ctrl +N) wykorzystując szablon acadiso.dwt

Przed rozpoczęciem pracy otwórz nowy plik (Ctrl +N) wykorzystując szablon acadiso.dwt Przed rozpoczęciem pracy otwórz nowy plik (Ctrl +N) wykorzystując szablon acadiso.dwt Zadanie: Utwórz szablon rysunkowy składający się z: - warstw - tabelki rysunkowej w postaci bloku (według wzoru poniżej)

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Wykład 7 Marcin Młotkowski 8 kwietnia 2015 Plan wykładu Z życia programisty, część 1 1 Z życia programisty, część 1 2 3 Z życia programisty, część 2 Model View Controller MVC w

Bardziej szczegółowo

Adobe InDesign lab.1 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Podstawy pracy z aplikacją Układ strony... 2.

Adobe InDesign lab.1 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Podstawy pracy z aplikacją Układ strony... 2. Spis treści: 1 Podstawy pracy z aplikacją... 2 1.1 Układ strony... 2 strona 1 z 7 1 Podstawy pracy z aplikacją InDesign jest następcą starzejącego się PageMakera. Pod wieloma względami jest do niego bardzo

Bardziej szczegółowo

Programowanie zdarzeniowe

Programowanie zdarzeniowe Programowanie zdarzeniowe I. Podstawy obsługi zdarzeń Małgorzata Prolejko ZDA JA16Z03 Plan Pojęcie zdarzenia Klasy i obiekty słuchaczy Rejestracja słuchaczy Obsługa naciśnięcia przycisku Rozpoznawanie

Bardziej szczegółowo

Tworzenie szablonów użytkownika

Tworzenie szablonów użytkownika Poradnik Inżyniera Nr 40 Aktualizacja: 12/2018 Tworzenie szablonów użytkownika Program: Plik powiązany: Stratygrafia 3D - karty otworów Demo_manual_40.gsg Głównym celem niniejszego Przewodnika Inżyniera

Bardziej szczegółowo

Temat: Organizacja skoroszytów i arkuszy

Temat: Organizacja skoroszytów i arkuszy Temat: Organizacja skoroszytów i arkuszy Podstawowe informacje o skoroszycie Excel jest najczęściej wykorzystywany do tworzenia skoroszytów. Skoroszyt jest zbiorem informacji, które są przechowywane w

Bardziej szczegółowo

Podstawy Języka Java

Podstawy Języka Java Podstawy Języka Java Wprowadzenie do AWT AWT Abstract Window Toolkit, biblioteka wykorzystywana do budowy graficznych interfejsów użytkownika w Javie AWT do obsługi elementów interfejsu użytkownika wykorzystuje

Bardziej szczegółowo

Programowanie graficznego interfejsu użytkownika. Wykład 8. Maciej Wołoszyn 10 maja 2006

Programowanie graficznego interfejsu użytkownika. Wykład 8. Maciej Wołoszyn 10 maja 2006 Programowanie graficznego interfejsu użytkownika Wykład 8 Maciej Wołoszyn mailto:woloszyn@fatcat.ftj.agh.edu.pl 10 maja 2006 Spis treści 1 JFC/Swing 1 1.1 Prosty przykład.................................

Bardziej szczegółowo

Kurs programowania. Wykład 4. Wojciech Macyna. 23 marca 2016

Kurs programowania. Wykład 4. Wojciech Macyna. 23 marca 2016 Wykład 4 23 marca 2016 Graficzny interfejs użytkownika - GUI W Javie możemy skorzystać z dwóch bibliotek do tworzenia graficznych interfejsów: AWT (Abstract Windowing Toolkit) podstawowa biblioteka będaca

Bardziej szczegółowo

Język Java część 2 (przykładowa aplikacja)

Język Java część 2 (przykładowa aplikacja) Programowanie obiektowe Język Java część 2 (przykładowa aplikacja) Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej pawel.rogalinski @ pwr.wroc.pl Java Java przykładowa

Bardziej szczegółowo

Programowanie graficznych interfejsów użytkownika

Programowanie graficznych interfejsów użytkownika Programowanie obiektowe Programowanie graficznych interfejsów użytkownika Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej pawel.rogalinski pwr.wroc.pl Programowanie

Bardziej szczegółowo

Informatyka II. Laboratorium Aplikacja okienkowa

Informatyka II. Laboratorium Aplikacja okienkowa Informatyka II Laboratorium Aplikacja okienkowa Założenia Program będzie obliczał obwód oraz pole trójkąta na podstawie podanych zmiennych. Użytkownik będzie poproszony o podanie długości boków trójkąta.

Bardziej szczegółowo

Podstawy technologii WWW

Podstawy technologii WWW Podstawy technologii WWW Ćwiczenie 8 PHP, czyli poczatki nowej, dynamicznej znajomosci Na dzisiejszych zajęciach rozpoczniemy programowanie po stronie serwera w języku PHP. Po otrzymaniu żądania serwer

Bardziej szczegółowo

Dodawanie grafiki i obiektów

Dodawanie grafiki i obiektów Dodawanie grafiki i obiektów Word nie jest edytorem obiektów graficznych, ale oferuje kilka opcji, dzięki którym można dokonywać niewielkich zmian w rysunku. W Wordzie możesz zmieniać rozmiar obiektu graficznego,

Bardziej szczegółowo

Programowanie zdarzeniowe

Programowanie zdarzeniowe Programowanie zdarzeniowe II. Biblioteka Swing Małgorzata Prolejko ZDA JA16Z03 Plan Struktura Swing Komponenty proste Ramki Kolejność warstw Zarządca układu Panele Komponenty złożone Okna dialogowe i wewnętrzne

Bardziej szczegółowo

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

5.2. Pierwsze kroki z bazami danych

5.2. Pierwsze kroki z bazami danych 5.2. Pierwsze kroki z bazami danych Uruchamianie programu Podobnie jak inne programy, OO Base uruchamiamy z Menu Start, poprzez zakładkę Wszystkie programy, gdzie znajduje się folder OpenOffice.org 2.2,

Bardziej szczegółowo

Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows XP

Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows XP 5.0 5.3.3.7 Laboratorium - Monitorowanie i zarządzanie zasobami systemu Windows XP Wprowadzenie Wydrukuj i uzupełnij to laboratorium. W tym laboratorium, będziesz korzystać z narzędzi administracyjnych

Bardziej szczegółowo

etrader Pekao Podręcznik użytkownika Strumieniowanie Excel

etrader Pekao Podręcznik użytkownika Strumieniowanie Excel etrader Pekao Podręcznik użytkownika Strumieniowanie Excel Spis treści 1. Opis okna... 3 2. Otwieranie okna... 3 3. Zawartość okna... 4 3.1. Definiowanie listy instrumentów... 4 3.2. Modyfikacja lub usunięcie

Bardziej szczegółowo

Oficyna Wydawnicza UNIMEX ebook z zabezpieczeniami DRM

Oficyna Wydawnicza UNIMEX ebook z zabezpieczeniami DRM Oficyna Wydawnicza UNIMEX ebook z zabezpieczeniami DRM Opis użytkowy aplikacji ebookreader Przegląd interfejsu użytkownika a. Okno książki. Wyświetla treść książki podzieloną na strony. Po prawej stronie

Bardziej szczegółowo

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost; Klasy w C++ są bardzo ważnym narzędziem w rękach programisty. Klasy są fundamentem programowania obiektowego. Z pomocą klas będziesz mógł tworzyć lepszy kod, a co najważniejsze będzie on bardzo dobrze

Bardziej szczegółowo

Tworzenie prezentacji w MS PowerPoint

Tworzenie prezentacji w MS PowerPoint Tworzenie prezentacji w MS PowerPoint Program PowerPoint dostarczany jest w pakiecie Office i daje nam możliwość stworzenia prezentacji oraz uatrakcyjnienia materiału, który chcemy przedstawić. Prezentacje

Bardziej szczegółowo

5.4. Tworzymy formularze

5.4. Tworzymy formularze 5.4. Tworzymy formularze Zastosowanie formularzy Formularz to obiekt bazy danych, który daje możliwość tworzenia i modyfikacji danych w tabeli lub kwerendzie. Jego wielką zaletą jest umiejętność zautomatyzowania

Bardziej szczegółowo

Spis treści 1. Wstęp Logowanie Główny interfejs aplikacji Ogólny opis interfejsu Poruszanie się po mapie...

Spis treści 1. Wstęp Logowanie Główny interfejs aplikacji Ogólny opis interfejsu Poruszanie się po mapie... Spis treści 1. Wstęp... 2 2. Logowanie... 2 3. Główny interfejs aplikacji... 2 3.1. Ogólny opis interfejsu... 2 3.2. Poruszanie się po mapie... 3 3.3. Przełączanie widocznych warstw... 3 4. Urządzenia...

Bardziej szczegółowo

Aplikacje w środowisku Java

Aplikacje w środowisku Java Aplikacje w środowisku Java Materiały do zajęć laboratoryjnych Graficzny Interfejs Użytkownika mgr inż. Kamil Zieliński Katolicki Uniwersytet Lubelski Jana Pawła II 2018/2019 Spis treści Graficzny Interfejs

Bardziej szczegółowo

Wstawianie nowej strony

Wstawianie nowej strony Wstawianie nowej strony W obszernych dokumentach będziemy spotykali się z potrzebą dzielenia dokumentu na części. Czynność tę wykorzystujemy np.. do rozpoczęcia pisania nowego rozdziału na kolejnej stronie.

Bardziej szczegółowo

Dokumentacja do API Javy.

Dokumentacja do API Javy. Dokumentacja do API Javy http://java.sun.com/j2se/1.5.0/docs/api/ Klasy i obiekty Klasa jest to struktura zawierająca dane (pola), oraz funkcje operujące na tych danych (metody). Klasa jest rodzajem szablonu

Bardziej szczegółowo

SWING. dr Jarosław Skaruz http://jareks.ii.uph.edu.pl jaroslaw@skaruz.com

SWING. dr Jarosław Skaruz http://jareks.ii.uph.edu.pl jaroslaw@skaruz.com SWING dr Jarosław Skaruz http://jareks.ii.uph.edu.pl jaroslaw@skaruz.com O czym będzie? Przykład aplikacji z GUI Zarządcy układu Obsługa zdarzeń Komponenty GUI Wprowadzenie obiektowy paradygmat do tworzenia

Bardziej szczegółowo

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku

Przykładowa dostępna aplikacja w Visual Studio - krok po kroku Przykładowa dostępna aplikacja w Visual Studio - krok po kroku Zadaniem poniższego opisu jest pokazanie, jak stworzyć aplikację z dostępnym interfejsem. Sama aplikacja nie ma konkretnego zastosowania i

Bardziej szczegółowo

Delphi podstawy programowania. Środowisko Delphi

Delphi podstawy programowania. Środowisko Delphi Delphi podstawy programowania Środowisko Delphi Olsztyn 2004 Delphi Programowanie obiektowe - (object-oriented programming) jest to metodologia tworzeniu programów komputerowych definiująca je jako zbiór

Bardziej szczegółowo

Cel: Przypisujemy przyciskom określone funkcje panel górny (Panel1)

Cel: Przypisujemy przyciskom określone funkcje panel górny (Panel1) W odcinku III tworzyliśmy paski narzędzi. Umieszczaliśmy na panelach ikony, reprezentujące czynności (charakterystyczne dla edytorów tekstu). Musimy teraz przypisać każdemu przyciskowi jego czynność (wycinanie,

Bardziej szczegółowo

Arkusz kalkulacyjny EXCEL

Arkusz kalkulacyjny EXCEL ARKUSZ KALKULACYJNY EXCEL 1 Arkusz kalkulacyjny EXCEL Aby obrysować tabelę krawędziami należy: 1. Zaznaczyć komórki, które chcemy obrysować. 2. Kursor myszy ustawić na menu FORMAT i raz kliknąć lewym klawiszem

Bardziej szczegółowo

Podręcznik użytkownika

Podręcznik użytkownika Podręcznik użytkownika Moduł kliencki Kodak Asset Management Software Stan i ustawienia zasobów... 1 Menu Stan zasobów... 2 Menu Ustawienia zasobów... 3 Obsługa alertów... 7 Komunikaty zarządzania zasobami...

Bardziej szczegółowo

Ćwiczenia nr 4. Arkusz kalkulacyjny i programy do obliczeń statystycznych

Ćwiczenia nr 4. Arkusz kalkulacyjny i programy do obliczeń statystycznych Ćwiczenia nr 4 Arkusz kalkulacyjny i programy do obliczeń statystycznych Arkusz kalkulacyjny składa się z komórek powstałych z przecięcia wierszy, oznaczających zwykle przypadki, z kolumnami, oznaczającymi

Bardziej szczegółowo

Adobe InDesign lab. 2 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Dokument wielostronicowy Książka Eksport do PDF... 7.

Adobe InDesign lab. 2 Jacek Wiślicki, Paweł Kośla. Spis treści: 1 Dokument wielostronicowy Książka Eksport do PDF... 7. Spis treści: 1 Dokument wielostronicowy... 2 1.1 Książka... 2 1.2 Eksport do PDF... 7 strona 1 z 7 1 Dokument wielostronicowy Poniższa instrukcja zawiera przykład procedury projektowania dokumentów wielostronicowych

Bardziej szczegółowo

UONET+ - moduł Sekretariat. Jak wykorzystać wydruki list w formacie XLS do analizy danych uczniów?

UONET+ - moduł Sekretariat. Jak wykorzystać wydruki list w formacie XLS do analizy danych uczniów? UONET+ - moduł Sekretariat Jak wykorzystać wydruki list w formacie XLS do analizy danych uczniów? W module Sekretariat wydruki dostępne w widoku Wydruki/ Wydruki list można przygotować w formacie PDF oraz

Bardziej szczegółowo

UONET+ moduł Dziennik

UONET+ moduł Dziennik UONET+ moduł Dziennik Sporządzanie ocen opisowych i diagnostycznych uczniów z wykorzystaniem schematów oceniania Przewodnik System UONET+ umożliwia sporządzanie ocen opisowych uczniów w oparciu o przygotowany

Bardziej szczegółowo

MS Word 2010. Długi dokument. Praca z długim dokumentem. Kinga Sorkowska 2011-12-30

MS Word 2010. Długi dokument. Praca z długim dokumentem. Kinga Sorkowska 2011-12-30 MS Word 2010 Długi dokument Praca z długim dokumentem Kinga Sorkowska 2011-12-30 Dodawanie strony tytułowej 1 W programie Microsoft Word udostępniono wygodną galerię wstępnie zdefiniowanych stron tytułowych.

Bardziej szczegółowo

Wprowadzenie do projektu QualitySpy

Wprowadzenie do projektu QualitySpy Wprowadzenie do projektu QualitySpy Na podstawie instrukcji implementacji prostej funkcjonalności. 1. Wstęp Celem tego poradnika jest wprowadzić programistę do projektu QualitySpy. Będziemy implementować

Bardziej szczegółowo

Zadanie Wstaw wykres i dokonaj jego edycji dla poniższych danych. 8a 3,54 8b 5,25 8c 4,21 8d 4,85

Zadanie Wstaw wykres i dokonaj jego edycji dla poniższych danych. 8a 3,54 8b 5,25 8c 4,21 8d 4,85 Zadanie Wstaw wykres i dokonaj jego edycji dla poniższych danych Klasa Średnia 8a 3,54 8b 5,25 8c 4,21 8d 4,85 Do wstawienia wykresu w edytorze tekstu nie potrzebujemy mieć wykonanej tabeli jest ona tylko

Bardziej szczegółowo

Dodanie nowej formy do projektu polega na:

Dodanie nowej formy do projektu polega na: 7 Tworzenie formy Forma jest podstawowym elementem dla tworzenia interfejsu użytkownika aplikacji systemu Windows. Umożliwia uruchomienie aplikacji, oraz komunikację z użytkownikiem aplikacji. W trakcie

Bardziej szczegółowo

LibreOffice Impress. Poziom podstawowy. Materiały szkoleniowe

LibreOffice Impress. Poziom podstawowy. Materiały szkoleniowe LibreOffice Impress Poziom podstawowy Materiały szkoleniowe Nota Materiał powstał w ramach realizacji projektu e-kompetencje bez barier dofinansowanego z Programu Operacyjnego Polska Cyfrowa działanie

Bardziej szczegółowo

Tworzymy projekt File->New Project->Java Application, przy czym tym razem odznaczamy create main class

Tworzymy projekt File->New Project->Java Application, przy czym tym razem odznaczamy create main class Tworzymy projekt File->New Project->Java Application, przy czym tym razem odznaczamy create main class Mamy Prawym przyciskiem na default packeges I wybieramy New JFrame. Teraz pamiętajmy o podaniu jakiejś

Bardziej szczegółowo

Zakładka Obmiar jest dostępna dla pozycji kosztorysowej w dolnym panelu. Służy do obliczania ilości robót (patrz też p ).

Zakładka Obmiar jest dostępna dla pozycji kosztorysowej w dolnym panelu. Służy do obliczania ilości robót (patrz też p ). 1.1.1. Obmiar Zakładka Obmiar jest dostępna dla pozycji kosztorysowej w dolnym panelu. Służy do obliczania ilości robót (patrz też p. 4.3.15). Zakładka przypomina swoim wyglądem uproszczony arkusz kalkulacyjny.

Bardziej szczegółowo

Aktywności są związane z ekranem i definiują jego wygląd. Dzieje się to poprzez podpięcie do aktywności odpowiedniego widoku.

Aktywności są związane z ekranem i definiują jego wygląd. Dzieje się to poprzez podpięcie do aktywności odpowiedniego widoku. Aktywności to podstawowe elementy związane z platformą Android. Dzięki poznaniu aktywności będziesz w stanie napisać pierwszą aplikację przeznaczoną na urządzenie mobilne. Po dodaniu kontrolek możesz w

Bardziej szczegółowo

Visual Studio instalacja

Visual Studio instalacja Visual Studio 2017 - instalacja Do tej pory napisaliśmy wiele programów, z czego niemal wszystkie były aplikacjami konsolowymi. Najwyższy więc czas zająć się tworzeniem aplikacji z graficznym interfejsem

Bardziej szczegółowo

D:\DYDAKTYKA\ZAI_BIS\_Ćwiczenia_wzorce\04\04_poprawiony.doc 2009-lis-23, 17:44

D:\DYDAKTYKA\ZAI_BIS\_Ćwiczenia_wzorce\04\04_poprawiony.doc 2009-lis-23, 17:44 Zaawansowane aplikacje internetowe EJB 1 Rozróżniamy dwa rodzaje beanów sesyjnych: Stateless Statefull Celem tego laboratorium jest zbadanie różnic funkcjonalnych tych dwóch rodzajów beanów. Poszczególne

Bardziej szczegółowo

Podział na strony, sekcje i kolumny

Podział na strony, sekcje i kolumny Formatowanie stron i sekcji Formatowanie stron odnosi się do całego dokumentu lub jego wybranych sekcji. Dla całych stron ustalamy na przykład marginesy, które określają odległość tekstu od krawędzi papieru.

Bardziej szczegółowo

PWSG Ćwiczenia 12. Wszystkie ukończone zadania należy wysłać na adres: lub

PWSG Ćwiczenia 12. Wszystkie ukończone zadania należy wysłać na adres: lub PWSG Ćwiczenia 12 Wszystkie ukończone zadania należy wysłać na adres: sara.m.jurczyk@gmail.com lub sarajurczyk@kul.lublin.pl Zadanie 1: Różnica między zwykłymi polami/metodami, a polami/metodami static

Bardziej szczegółowo

Edytor tekstu OpenOffice Writer Podstawy

Edytor tekstu OpenOffice Writer Podstawy Edytor tekstu OpenOffice Writer Podstawy OpenOffice to darmowy zaawansowany pakiet biurowy, w skład którego wchodzą następujące programy: edytor tekstu Writer, arkusz kalkulacyjny Calc, program do tworzenia

Bardziej szczegółowo

1. Wstęp Niniejszy dokument jest instrukcją użytkownika dla aplikacji internetowej DM TrackMan.

1. Wstęp Niniejszy dokument jest instrukcją użytkownika dla aplikacji internetowej DM TrackMan. Instrukcja korzystania z aplikacji TrackMan wersja WEB 1. Wstęp... 1 2. Logowanie... 1 3. Główny interfejs aplikacji... 2 3.1. Ogólny opis interfejsu... 2 3.2. Poruszanie się po mapie... 2 3.3. Przełączanie

Bardziej szczegółowo

Wstęp 7 Rozdział 1. OpenOffice.ux.pl Writer środowisko pracy 9

Wstęp 7 Rozdział 1. OpenOffice.ux.pl Writer środowisko pracy 9 Wstęp 7 Rozdział 1. OpenOffice.ux.pl Writer środowisko pracy 9 Uruchamianie edytora OpenOffice.ux.pl Writer 9 Dostosowywanie środowiska pracy 11 Menu Widok 14 Ustawienia dokumentu 16 Rozdział 2. OpenOffice

Bardziej szczegółowo

Program EWIDENCJA ODZIEŻY ROBOCZEJ INSTRUKCJA UŻYTKOWNIKA Przejdź do strony producenta programu

Program EWIDENCJA ODZIEŻY ROBOCZEJ INSTRUKCJA UŻYTKOWNIKA Przejdź do strony producenta programu Program EWIDENCJA ODZIEŻY ROBOCZEJ INSTRUKCJA UŻYTKOWNIKA Przejdź do strony producenta programu http://www.jarsoft.poznan.pl/ 1. STRUKTURA PROGRAMU Program EWIDENCJA ODZIEŻY ROBOCZEJ jest aplikacją wspierającą

Bardziej szczegółowo

Nawigacja po długim dokumencie może być męcząca, dlatego warto poznać następujące skróty klawiszowe

Nawigacja po długim dokumencie może być męcząca, dlatego warto poznać następujące skróty klawiszowe Zestawienie wydatków rok 2015 1 Wstaw numerację stron. Aby to zrobić przejdź na zakładkę Wstawianie i w grupie Nagłówek i stopka wybierz Numer strony. Następnie określ pozycję numeru na stronie (na przykład

Bardziej szczegółowo

System Obsługi Zleceń

System Obsługi Zleceń System Obsługi Zleceń Podręcznik Administratora Atinea Sp. z o.o., ul. Chmielna 5/7, 00-021 Warszawa NIP 521-35-01-160, REGON 141568323, KRS 0000315398 Kapitał zakładowy: 51.000,00zł www.atinea.pl wersja

Bardziej szczegółowo

Ćwiczenie 1. Kolejki IBM Message Queue (MQ)

Ćwiczenie 1. Kolejki IBM Message Queue (MQ) Ćwiczenie 1. Kolejki IBM Message Queue (MQ) 1. Przygotowanie Przed rozpoczęciem pracy, należy uruchomić "Kreator przygotowania WebSphere MQ" oraz przejść przez wszystkie kroki kreatora, na końcu zaznaczając

Bardziej szczegółowo

1. Przypisy, indeks i spisy.

1. Przypisy, indeks i spisy. 1. Przypisy, indeks i spisy. (Wstaw Odwołanie Przypis dolny - ) (Wstaw Odwołanie Indeks i spisy - ) Przypisy dolne i końcowe w drukowanych dokumentach umożliwiają umieszczanie w dokumencie objaśnień, komentarzy

Bardziej szczegółowo

Tworzenie i obsługa graficznego interfejsu uŝytkownika

Tworzenie i obsługa graficznego interfejsu uŝytkownika Tworzenie i obsługa graficznego interfejsu uŝytkownika Programowanie w środowisku rozproszonym. Wykład 3. Aplety aplikacje uruchamiane w środowisku przeglądarki - przykład import java.applet.applet; import

Bardziej szczegółowo

BAZY DANYCH Panel sterujący

BAZY DANYCH Panel sterujący BAZY DANYCH Panel sterujący Panel sterujący pełni z reguły rolę centrum, z którego wydajemy polecenia i uruchamiamy różnorodne, wcześniej zdefiniowane zadania, np. wyświetlamy formularze lub drukujemy

Bardziej szczegółowo

Podręcznik użytkownika programu. Ceremonia 3.1

Podręcznik użytkownika programu. Ceremonia 3.1 Podręcznik użytkownika programu Ceremonia 3.1 1 Spis treści O programie...3 Główne okno programu...4 Edytor pieśni...7 Okno ustawień programu...8 Edycja kategorii pieśni...9 Edytor schematów slajdów...10

Bardziej szczegółowo

System Informatyczny CELAB. Terminy, alarmy

System Informatyczny CELAB. Terminy, alarmy Instrukcja obsługi programu 2.18. Terminy, alarmy Architektura inter/intranetowa Aktualizowano w dniu: 2007-09-25 System Informatyczny CELAB Terminy, alarmy Spis treści 1. Terminy, alarmy...2 1.1. Termin

Bardziej szczegółowo

Serwis jest dostępny w internecie pod adresem www.solidnyserwis.pl. Rysunek 1: Strona startowa solidnego serwisu

Serwis jest dostępny w internecie pod adresem www.solidnyserwis.pl. Rysunek 1: Strona startowa solidnego serwisu Spis treści 1. Zgłoszenia serwisowe wstęp... 2 2. Obsługa konta w solidnym serwisie... 2 Rejestracja w serwisie...3 Logowanie się do serwisu...4 Zmiana danych...5 3. Zakładanie i podgląd zgłoszenia...

Bardziej szczegółowo

Pokaz slajdów na stronie internetowej

Pokaz slajdów na stronie internetowej Pokaz slajdów na stronie internetowej... 1 Podpisy pod zdjęciami... 3 Publikacja pokazu slajdów w Internecie... 4 Generator strony Uczelni... 4 Funkcje dla zaawansowanych użytkowników... 5 Zmiana kolorów

Bardziej szczegółowo

Formatowanie tekstu przy uz yciu stylo w

Formatowanie tekstu przy uz yciu stylo w Formatowanie tekstu przy uz yciu stylo w Czy stosowanie wciąż tego samego formatowania albo zmienianie koloru, rozmiaru lub rodzaju czcionki w celu wyróżnienia tekstu należy do często wykonywanych czynności?

Bardziej szczegółowo

e-wsparcie Barbara Muszko Aktualizacja Twojej witryny internetowej tak prosta, jak obsługa Worda

e-wsparcie Barbara Muszko Aktualizacja Twojej witryny internetowej tak prosta, jak obsługa Worda e-wsparcie Barbara Muszko Aktualizacja Twojej witryny internetowej tak prosta, jak obsługa Worda Logowanie do panelu administracyjnego Aby móc zarządzać stroną, należy zalogować się do panelu administracyjnego.

Bardziej szczegółowo

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018 Informatyka I Klasy i obiekty. Podstawy programowania obiektowego dr inż. Andrzej Czerepicki Politechnika Warszawska Wydział Transportu 2018 Plan wykładu Pojęcie klasy Deklaracja klasy Pola i metody klasy

Bardziej szczegółowo

Przewodnik... Tworzenie Landing Page

Przewodnik... Tworzenie Landing Page Przewodnik... Tworzenie Landing Page Spis treści Kreator strony landing page Stwórz stronę Zarządzaj stronami 2 Kreator strony landing page Kreator pozwala stworzyć własną stronę internetową z unikalnym

Bardziej szczegółowo

Formularze w programie Word

Formularze w programie Word Formularze w programie Word Formularz to dokument o określonej strukturze, zawierający puste pola do wypełnienia, czyli pola formularza, w których wprowadza się informacje. Uzyskane informacje można następnie

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Laboratorium 1. Wstęp do programowania w języku Java. Narzędzia 1. Aby móc tworzyć programy w języku Java, potrzebny jest zestaw narzędzi Java Development Kit, który można ściągnąć

Bardziej szczegółowo

Java biblioteka Swing

Java biblioteka Swing Java biblioteka Swing Podstawowe klasy Klasa JComponent Klasa JFrame Klasa JFrame Klasa bazowa dla okien Ważne właściwości: settitle ( ) setdefaultcloseoperation ( ) setsize ( ), setlocation ( ) setlayout

Bardziej szczegółowo

Pierwsza ramka. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 10

Pierwsza ramka. dr Anna Łazińska, WMiI UŁ Podstawy języka Java   1 / 10 Pierwsza ramka dr Anna Łazińska, WMiI UŁ Podstawy języka Java https://www.javatpoint.com 1 / 10 Pierwsza ramka - kod package myframe1; import javax.swing.jframe; import javax.swing.jlabel; class MyFrame1

Bardziej szczegółowo

Laboratorium - Podgląd informacji kart sieciowych bezprzewodowych i przewodowych

Laboratorium - Podgląd informacji kart sieciowych bezprzewodowych i przewodowych Laboratorium - Podgląd informacji kart sieciowych bezprzewodowych i przewodowych Cele Część 1: Identyfikacja i praca z kartą sieciową komputera Część 2: Identyfikacja i użycie ikon sieci w obszarze powiadomień

Bardziej szczegółowo

Rozdział VI. Tabele i ich możliwości

Rozdział VI. Tabele i ich możliwości Rozdział VI Tabele i ich możliwości 3.6. Tabele i ich możliwości W wielu dokumentach zachodzi konieczność przedstawienia danych w formie tabelarycznej. Dlatego też program OO Writer jest wyposażony w

Bardziej szczegółowo

PODRĘCZNIK UŻYTKOWNIKA SYSTEMU MONITOROWANIA KSZTAŁCENIA PRACOWNIKÓW MEDYCZNYCH

PODRĘCZNIK UŻYTKOWNIKA SYSTEMU MONITOROWANIA KSZTAŁCENIA PRACOWNIKÓW MEDYCZNYCH PODRĘCZNIK UŻYTKOWNIKA SYSTEMU MONITOROWANIA KSZTAŁCENIA PRACOWNIKÓW MEDYCZNYCH WNIOSKI O EGZAMIN SPECJALIZACYJNY ROLA: PIELĘGNIARKA/POŁOŻNA 12.06.2018 Spis treści WPROWADZENIE... 3 1. LOGOWANIE DO SYSTEMU...

Bardziej szczegółowo

Ćwiczenie 1: Pierwsze kroki

Ćwiczenie 1: Pierwsze kroki Ćwiczenie 1: Pierwsze kroki z programem AutoCAD 2010 1 Przeznaczone dla: nowych użytkowników programu AutoCAD Wymagania wstępne: brak Czas wymagany do wykonania: 15 minut W tym ćwiczeniu Lekcje zawarte

Bardziej szczegółowo

Zawartość. Wstęp. Moduł Rozbiórki. Wstęp Instalacja Konfiguracja Uruchomienie i praca z raportem... 6

Zawartość. Wstęp. Moduł Rozbiórki. Wstęp Instalacja Konfiguracja Uruchomienie i praca z raportem... 6 Zawartość Wstęp... 1 Instalacja... 2 Konfiguracja... 2 Uruchomienie i praca z raportem... 6 Wstęp Rozwiązanie przygotowane z myślą o użytkownikach którzy potrzebują narzędzie do podziału, rozkładu, rozbiórki

Bardziej szczegółowo

Sekretariat Optivum. Jak przygotować listę uczniów zawierającą tylko wybrane dane, np. adresy e-mail ucznia i jego opiekunów? Projektowanie listy

Sekretariat Optivum. Jak przygotować listę uczniów zawierającą tylko wybrane dane, np. adresy e-mail ucznia i jego opiekunów? Projektowanie listy Sekretariat Optivum Jak przygotować listę uczniów zawierającą tylko wybrane dane, np. adresy e-mail ucznia i jego opiekunów? Program Sekretariat Optivum ma wbudowane różne edytory, które umożliwiają przygotowywanie

Bardziej szczegółowo

Zajęcia nr 15 JavaScript wprowadzenie do JavaScript

Zajęcia nr 15 JavaScript wprowadzenie do JavaScript Zajęcia nr 15 JavaScript wprowadzenie do JavaScript Prowadzący: Andrzej Gąsienica-Samek, strona kółka www.atinea.pl/kolko Wprowadzenie do jsfiddle.net Uruchom Chrome i wejdź na stronę http://jsfiddle.net.

Bardziej szczegółowo

Kadry Optivum, Płace Optivum

Kadry Optivum, Płace Optivum Kadry Optivum, Płace Optivum Jak seryjnie przygotować wykazy absencji pracowników? W celu przygotowania pism zawierających wykazy nieobecności pracowników skorzystamy z mechanizmu Nowe wydruki seryjne.

Bardziej szczegółowo

BIBLIOTEKA LOKALNE CENTRUM WIEDZY PRAKTYCZNEJ PRZEWODNIK PO NARZĘDZIACH WARSZTAT NR 1: ARKUSZE KALKULACYJNE - MINI SKRYPT

BIBLIOTEKA LOKALNE CENTRUM WIEDZY PRAKTYCZNEJ PRZEWODNIK PO NARZĘDZIACH WARSZTAT NR 1: ARKUSZE KALKULACYJNE - MINI SKRYPT BIBLIOTEKA LOKALNE CENTRUM WIEDZY PRAKTYCZNEJ PRZEWODNIK PO NARZĘDZIACH WARSZTAT NR 1: ARKUSZE KALKULACYJNE - MINI SKRYPT 1. Wprowadzenie Arkusze kalkulacyjne Google umożliwiają łatwe tworzenie, udostępnianie

Bardziej szczegółowo

Zadanie 1. Stosowanie stylów

Zadanie 1. Stosowanie stylów Zadanie 1. Stosowanie stylów Styl to zestaw elementów formatowania określających wygląd: tekstu atrybuty czcionki (tzw. styl znaku), akapitów np. wyrównanie tekstu, odstępy między wierszami, wcięcia, a

Bardziej szczegółowo

DODAJEMY TREŚĆ DO STRONY

DODAJEMY TREŚĆ DO STRONY DODAJEMY TREŚĆ DO STRONY SPIS TREŚCI Pasek narzędzi i wyszukiwarka aplikacji... 2 Dodawanie portletów... 3 Widok zawartości stron... 4 Zawartość portletu... 5 Ikonki wybierz oraz dodaj zawartość stron...

Bardziej szczegółowo

Jak dodać własny szablon ramki w programie dibudka i dilustro

Jak dodać własny szablon ramki w programie dibudka i dilustro Aby dodać własną ramkę otwórz moduł administracyjny dibudkaadmin.exe, wejdź do zakładki Ramki, tła, id i następnie Edycja. 1. Kliknij przycisk Dodaj ramkę 2. Określ wymiary nowej ramki Jeżeli dodajesz

Bardziej szczegółowo

1. Dockbar, CMS + wyszukiwarka aplikacji Dodawanie portletów Widok zawartości stron... 3

1. Dockbar, CMS + wyszukiwarka aplikacji Dodawanie portletów Widok zawartości stron... 3 DODAJEMY TREŚĆ DO STRONY 1. Dockbar, CMS + wyszukiwarka aplikacji... 2 2. Dodawanie portletów... 3 Widok zawartości stron... 3 Omówienie zawartości portletu (usunięcie ramki itd.)... 4 3. Ikonki wybierz

Bardziej szczegółowo

Ćwiczenie 1 Galeria zdjęć

Ćwiczenie 1 Galeria zdjęć Galeria zdjęć Pobierz przykład (http://jsekulska.kis.p.lodz.pl/studia.htm). Krok 1 Ustawienie stołu montażowego Otwieramy nowy plik i nazywamy go (np. gallery.fla). Ustawiamy wielkość pola roboczego na

Bardziej szczegółowo

Języki i metody programowania Java. Wykład 2 (część 2)

Języki i metody programowania Java. Wykład 2 (część 2) Języki i metody programowania Java INF302W Wykład 2 (część 2) Autor Dr inż. Zofia Kruczkiewicz 1 Struktura wykładu 1. Identyfikacja danych reprezentowanych przez klasy podczas opracowania koncepcji prostego

Bardziej szczegółowo