Cóż to takiego te wyjątki? Wyobraźmy sobie sytuację, że użytkownik chce na przykład wykonać dzielenie i jako dzielnik w drugie pole tekstowe wprowadzi cyfrę 0. No i stało się – „Houston mamy problem!”. Jak sobie poradzić z takimi sytuacjami? Otóż blok kodu odpowiedzialny za dzielenie musimy w pewien sposób zmodyfikować dodając do niego warunek logiczny oraz umieszczenie kodu metody w bloku „try-catch”. Z czym to się je? Pokażę poniżej na przykładzie metody „dzielenie”.
public void dzielenie()
{
double liczba1,liczba2,wynik;
try{ // Początek bloku try
liczba1 = Double.parseDouble(pole1.getText());
liczba2 = Double.parseDouble(pole2.getText());
}
if(liczba2 == 0){ // Sprawdzenie czy liczba2 nie jest zerem
JOptionPane.showMessageDialog(null,”Błąd dzielenia przez zero!”,”Błąd!”,0);
pole1.setText(“”);// wyczyszczenie pola tekstowego
pole2.setText(“”);
return;
else{
wynik = liczba1/liczba2;
pole3.setText(String.valueOf(wynik));
}
}
catch(Exception e){ // Obsługa błędu/wyjątku
JOptionPane.showMessageDialog(null,”Niepoprawne dane!”,”Błąd”,0);
pole1.setText(‘’’);
pole2.setText(‘’’);
return;
}
}
Do sprawdzenia poprawności wprowadzonych danych w metodzie wykorzystaliśmy blok „try-catch” i prosty warunek logiczny, który sprawdza czy druga z liczb jest zerem. Jeśli jest warunek ów jest spełniony, to po prostu informujemy użytkownika programu stosownym komunikatem i kończymy wykonanie metody. Jeśli warunek nie jest spełniony, metoda wykonuje obliczenie i wyświetla wynik w „polu3”. Ale to nie jedyna sytuacja, jaką musimy oprogramować, aby metoda była w pełni skuteczna. Na pozostałe „sytuacje awaryjne” mamy blok „try-catch”. W „try” umieszczamy kod, który potencjalnie może spowodować błąd lub wyjątek w programie, natomiast w sekcji „catch” obsługujemy ten błąd. W tym przypadku stosownym komunikatem o błędzie i kończymy wykonanie metody. Aby móc korzystać z okienek dialogowych powinniśmy zaimportować do naszej aplikacji klasę „swing”. Kod poniżej.
import javax.swing.*;
Uzupełnienie pozostałych metod w obsługę błędów pozostawiam czytelnikom. Mechanizm „try-catch” jest analogiczny jak w podanym przykładzie.
Komunikat o błędzie dzielenia przez zero
Komunikat o błędzie niepoprawnych danych.
Rozwijamy aplikację
Po wprowadzeniu we wszystkich metodach obsługi błędów, czas na dodanie pola, w którym dobrze byłoby przechowywać wyniki wszystkich operacji. Dodajmy, zatem pole „TextArea” do aplikacji. Można zrobić to tak: W klasie inicjujemy komponent tak jak poprzednio, czyli:
public class nasza klasa extends Frame // klasa
{
TextArea okno;
}
A w konstruktorze musimy powołać nowy obiekt klasy „TextArea” do życia w taki sposób:
public class nasza klasa extends Frame
{
TextArea okno;
Public naszaKlasa() // Konstruktor klasy
{
okno = new TextArea();
okno.setBounds(10,60,480,300);
add(okno);
}
}
Teraz już mamy okno tekstowe, w którym możemy zapisywać wyniki udanych operacji dokonanych przez nas w aplikacji. Żeby tak się działo powinniśmy stworzyć metodę, która będzie nam to umożliwiała.
public void wstawdanezoperacjidoOkna()
{
String rodzajoperacji,liczba1,liczba2,wynik;
String znakoperacji = ‘’’’;
rodzajoperacji = lista.getSelectedItem();
liczba1 = pole1.getText();
liczba2 = pole2.getText();
wynik = pole3.getText();
if(rodzajoperacji.equals(„Dodawanie”))
{
znakoperacji = „+”;
}
if(rodzajoperacji.equals(„Odejmowanie”));
{
znakoperacji = „-‘’;
}
if(rodzajoperacji.equals(„Mnożenie”));
{
znakoperacji = „*”;
}
if(rodzajoperacji.equals(„Dzielenie”));
{
znakoperacji = „/”;
}
okno.append(rodzaj operacji + „ : „ + liczba1 + „ ‘’ + znak operacji + „ ‘’ + liczba2 + „ = „ + wynik);
}
Taka metoda pozwoli nam umieszczenie takiej historii operacji w jednym widocznym miejscu. Oczywiście teraz trzeba wywołać metodę w każdej z metod obliczeniowych w takim miejscu, aby po każdym udanym wywołaniu metody obliczeniowej, zwrócony wynik był zapisany w oknie „TextArea”. Pokażę ten mechanizm na przykładzie metody „Dzielenie”, a ciebie czytelniku zachęcam do twórczego i samodzielnego, „doprogramowania” pozostałych metod.
public void dzielenie()
{
Double liczba1,liczba2,wynik;
try{ // Początek bloku try
liczba1 = Double.parseDouble(pole1.getText());
liczba2 = Double.parseDouble(pole2.getText());
}
If(liczba2 == 0){ // Sprawdzenie czy liczba2 nie jest zerem
JOptionPane.showMessageDialog(null,”Błąd dzielenia przez zero!”,”Błąd!”,0);
pole1.setText(“”);// wyczyszczenie pola tekstowego
pole2.setText(“”);
return;
else{
wynik = liczba1/liczba2;
pole3.setText(String.valueOf(wynik));
wstawdanezoperacjidoOkna(); // tutaj jest wywoływana metoda //wstawiająca dane do okna po prawidłowym wykonaniu metody dzielenia }
}
catch(Exception e){ // Obsługa błędu/wyjątku
JOptionPane.showMessageDialog(null,”Niepoprawne dane!”,”Błąd”,0);
pole1.setText(‘’’);
pole2.setText(‘’’);
return;
}
}
No i jest! Nasze okno operacji w całej krasie.
Dodajemy menu
Każdy „poważny program” nie może obejść się bez własnego paska z menu. Aby stworzyć takie menu w aplikacji powinniśmy skorzystać z klasy „MenuBar”, „ Menu” oraz „MenuItem”.” MenuBar” to nic innego jak kontener na nasze menu. Jak dodać takie menu do aplikacji pokażę poniżej. Komponent menu dodajemy do aplikacji w sposób podobny jak poprzednie komponenty aplikacji. W ciele klasy deklarujemy potrzebne komponenty (fragment kodu). A w konstruktorze powołujemy je „do życia”.
public class klasaTest extends Frame implements ActionListener
{
menuBar pasekMenu; // pasek
menu plik; // menu
menuItem zapiszdoPliku, odczytajzPliku, zamknijProgram; // pozycje menu
public klasaTestowa() // konstruktor
{
…………………………..
PasekMenu = new MenuBar();
setMenuBar(pasek); // dodanie paska do okna aplikacji
plik = New Menu(„Plik”);
pasekMenu.add(plik); // dodajemy menu do paska
zapiszdoPliku = New MenuItem(„Zapisz do pliku”);
zapiszdoPliku.addActionLIstener(this); // dodajemy pozycję menu do nasłuchiwacza zdarzeń
plik.add(zapiszdoPliku); // dodajemy pozycję do menu „Plik”
odczytajzPliku = New MenuItem(„Odczytaj z pliku”);
odczytajzPliku.addActionListener(this);
plik.add(odczytajzPLiku);
zamknij program……analogicznie do poprzednich obiektów
}
}
Zróbmy jeszcze modyfikację interfejsu poprzez obniżenie położenia komponentów interfejsu, które menu może przesłonić. Po dodaniu menu do aplikacji ukaże się naszym oczom widok, jak poniżej.
Menu naszej aplikacji
Menu rozwijane aplikacji. Gwoli wyjaśnienia dodam, że bardzo ważną rzeczą jest dodanie pozycji „menu” do interfejsu „ActionListenr”, nasłuchującego zdarzeń związanych z kliknięciem w każdą z pozycji menu.
Wykorzystamy interfejs „ActionListener” do obsługi jednej z pozycji menu tj: „Zamknij program”. Napiszmy, zatem metodę, która będzie służyła do zamykania okna naszej aplikacji. Metoda ta może wyglądać tak:
public void zamknijProgram()
{
int odpowiedz = JOptionPane.showConfirmDialog(null,”Zamknąć program?”,”Kończenie pracy programu”,JOptionPane.OK_CANCEL_OPTION);
if(odpowiedz == JOptionPane.OK_OPTION)
{
System.exit(0);
}
Else{
Return;
}
}
Metodę „zamknijProgram” umieszczamy w dowolnym miejscu w ciele klasy. Po czym musimy wywołać ją w metodzie „actionPerformed” – reagującej na zdarzenia interfejsu. Możemy ją wywołać tak:
// wewnątrz acionPerformed
if(e.getSource() == zamknijprogram)
{
zamknijProgram(); // tutaj jest wywoływana metoda
}
Okienko potwierdzające zamknięcie aplikacji
W naszym menu znajdują się jeszcze dwie pozycje „Zapisz do pliku” i „Odczytaj z pliku”. W trzeciej części artykułu opiszę jak oprogramować i jak wywołać owe metody, służące do zapisania i odczytywania danych na dysku komputera wygenerowanych podczas używania aplikacji.
„Szlifujemy” interfejs aplikacji
Nasz program jak do tej pory opiera się w większości na komponentach GUI z biblioteki „java.awt”. Komponenty „awt”, użyte w aplikacji nie dają zbyt wiele możliwości, jeśli chodzi o upiększenie i usprawnienie aplikacji. Możemy w tej chwili zmienić kolor tła dla komponentów, rodzaj zastosowanej czcionki czy aktywacji lub wyłączania wybranego komponentu – to mało – prawda?!. Dlatego w następnej części podpowiem jak łatwo i szybo przebudować aplikację tak, aby korzystała i opierała się na komponentach z biblioteki „javax.swing”. (W tej części artykułu już użyliśmy jednej z klas tej biblioteki, przy generowaniu komunikatów w okienkach dialogowych). A dzięki temu uzyskamy lepszy wygląd i poprawimy funkcjonalność aplikacji. Pokażę również jak korzystać z klasy JChooserFile (okno wyboru plików), napiszemy klasę odpowiedzialną za filtrowanie widoku plików w „JChooserFile” oraz rozszerzymy funkcjonalność aplikacji o kolejne metody. Jeśli chcesz utrwalić i pogłębić swoją wiedzę zapraszam na moją stronę z kursem dla początkujących – Kurs Javy