225
Java i objektno orijentirano programiranje Predrag Brođanac

Java i objektno orijentirano programiranje

  • Upload
    tchuxy

  • View
    3.551

  • Download
    24

Embed Size (px)

DESCRIPTION

Knjiga iz informatike za 4. razred prirodoslovno-matematičke gimnazije. Autor: Predrag Brođanac, V. gimnazija Zagreb

Citation preview

Page 1: Java i objektno orijentirano programiranje

Java i objektno orijentirano

programiranje Predrag Brođanac

Page 2: Java i objektno orijentirano programiranje

2

Sadržaj 1. Osnovni pojmovi ..................................................................................................... 3

1.1 Program, programiranje, programski jezik..................................................... 4 1.2 Povijest programskih jezika ............................................................................. 6

1.2.1 Strojni jezici ............................................................................................. 6 1.2.2 Simbolički jezici....................................................................................... 6

1.3 Tehnike pisanja programa................................................................................ 8 2. Uvod u Javu .............................................................................................................. 9

2.1 Programski jezik Java......................................................................................10 2.2 Izvršavanje Java programa .............................................................................11 2.3 BlueJ razvojno okruženje ...............................................................................13 2.4 Elementi Jave...................................................................................................20 2.5 Tipovi podataka...............................................................................................22

2.5.1 Jednostavni tipovi podataka ................................................................23 2.5.1.1. Cjelobrojni tipovi podataka.........................................................23 2.5.1.2. Znakovni tip podataka.................................................................23 2.5.1.3. Realni tip podataka.......................................................................24

2.6 Deklaracija varijabli .........................................................................................25 2.7 Operatori ........................................................................................................26

2.7.1 Aritmetički operatori ............................................................................26 2.7.2 Relacijski operatori ...............................................................................27 2.7.3 Logički operatori...................................................................................28 2.7.4 Prioritet operatora.................................................................................29 2.7.5 Izračunavanje mješovitih izraza ..........................................................29

2.8 Prvi programi...................................................................................................31 3. Naredbe grananja ...................................................................................................33

3.1 if , if/else naredba..................................................................................34 3.2 switch/case naredba...............................................................................36

4. Petlje ........................................................................................................39 4.1 for petlja ........................................................................................................40 4.2 while petlja ...................................................................................................44 4.3 do/while petlja ...........................................................................................47

5. Složeni tipovi podataka .........................................................................................50 5.1 Niz ....................................................................................................................51

5.1.1 Višedimenzionalni nizovi.....................................................................53 5.2 String .................................................................................................................57

6. Objektno orijentirano programiranje ..................................................................59 6.1 Drugačiji pristup programiranju....................................................................60 6.2 Klasa i objekt ...................................................................................................61 6.3 Kreiranje objekta iz klase ...............................................................................66

6.3.1 Pristup elementima klase......................................................................67

Page 3: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

3

6.4 Nasljeñivanje klasa ..........................................................................................69 7. Programi u Javi .......................................................................................................74

7.1 Klasa i program ...............................................................................................75 7.2 Metoda main ....................................................................................................76 7.3 Izvršavanje Java programa iz komandnog prompta ...................................79

8. Elementi grafičkog korisničkog sučelja ...............................................................80 8.1 O grafičkom korisničkom sučelju .................................................................81 8.2 Prozor i njegovi dijelovi .................................................................................82 8.3 Okviri za tekst i gumbi ...................................................................................84

8.3.1 Okviri za tekst .......................................................................................84 8.3.2 Gumbi ....................................................................................................84

9. Dogañaji .................................................................................................................88 10. Iznimke ....................................................................................................................94

10.1 Što je iznimka..............................................................................................95 10.2 Hvatanje iznimki u Javi ..............................................................................95 10.3 Procesiranje iznimki ...................................................................................98

11. Složeniji elementi grafičkog korisničkog sučelja ..............................................102 11.1 Kvadratići za odabir opcija......................................................................102 11.2 Kružići za odabir opcija ...........................................................................103 11.3 Područja za tekst.......................................................................................104 11.4 Trake za pomicanje ..................................................................................105 11.5 Padajuće liste .............................................................................................106 11.6 Izbornici.....................................................................................................107

12. Unos i ispis podataka...........................................................................................111 12.1 Streamovi...................................................................................................112

12.1.1 Bajtovni streamovi..............................................................................113 12.1.2 Znakovni streamovi............................................................................113

12.2 Standardni ulaz i izlaz...............................................................................113 12.3 Tekstualne datoteke..................................................................................116

12.3.1 Čitanje podataka iz datoteka..............................................................116 12.3.2 Spremanje podataka u datoteke ........................................................119

13. Dijaloški prozori...................................................................................................122 13.1 Dijaloški prozori za otvaranje/spremanje dokumenata.......................124 13.2 Poruke, potvrde i jednostavan unos.......................................................126

13.2.1 Metoda showMessageDialog ...................................................127 13.2.2 Metoda showConfirmDialog ...................................................128 13.2.3 Metoda showInputDialog ........................................................129 13.2.4 Metoda showOptionDialog .....................................................130

13.3 Klasa Color i odabir boja .....................................................................131 13.4 Klasa Font ...............................................................................................133

14. Klasa Graphics ................................................................................................135 14.1 Metode klase Graphics .......................................................................137 14.2 Crtanje grafa funkcije ...............................................................................143

15. Java appleti ............................................................................................................148

Page 4: Java i objektno orijentirano programiranje

4

15.1 Primjer appleta ..........................................................................................149 15.2 Integriranje appleta u web stranicu ........................................................151 15.3 Prosljeñivanje parametara appletu iz web browsera.............................155

16. I još dva primjera .................................................................................................160 16.1 Telefonski imenik .....................................................................................161 16.2 Chat ............................................................................................................161

Page 5: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

5

1

Osnovni pojmovi

� Program, programiranje, programski jezik… � Povijest programskih jezika � Tehnike pisanja programa

Page 6: Java i objektno orijentirano programiranje

6

Program, programiranje, programski jezik… Jeste li se ikada zapitali što se u računalu dogaña od trenutka kada pomaknete miša po stolu do trenutka dok se pomakne pokazivač miša na monitoru računala? Kako računalo na osnovu sličice na koju smo kliknuli "zna" koji program treba pokrenuti? Prisjetimo se da je računalo ureñaj sastavljen od niza meñusobno povezanih elektroničkih komponenata, čija je osnovna zadaća omogućiti pamćenje i efikasnu obradu podataka. Računalo kao skup fizičkih komponenata nam neće biti od velike pomoći. Ukoliko ga ne opremimo odgovarajućim programima, pomak miša po stolu mu neće značiti ništa, čak štoviše neće niti prikazati pokazivač miša na ekranu. Dakle, da bismo računalo pretvorili u pomagalo moramo ga opskrbiti odgovarajućim programima. Da bismo mogli slušati glazbu potreban nam je odgovarajući program koji će nam to omogućiti. Kao što možemo primijetiti programi su vrlo bitni za rad računala, stoga ćemo se mi ovdje baviti upravo time, pisanjem programa. Što je to u stvari program? Program je niz naredbi koje su pisane tako da ih računalo razumije i može ih izvesti a koje rješavaju neki problem. Unutar programa se nalaze detaljne upute računalu kako treba reagirati na odreñenu akciju korisnika. Posao oko pripreme i pisanja programa zovemo programiranje, a programiranjem se bave programeri. Kao što znamo računalo sve podatke čuva u digitalnom obliku. Dakle da bi računalo razumjelo program on mora biti napisan kao niz nula i jedinica. Prvi programi su se uistinu tako i pisali. Za takve programe kažemo da su napisani u strojnom jeziku. Takvo programiranje bilo je izuzetno mukotrpno. Danas je programiranje znatno pojednostavljeno. Programi se pišu u nekom od mnoštva programskih jezika. Programski jezik je skup pravila riječi i simbola pomoću kojih se pišu programi, tj. pomoću kojih se detaljno opisuju koraci rješavanja nekog problema. Zadatak programskog jezika je napisani program prevesti u jezik strojni jezik koji računalo razumije. Program – niz naredbi koje rješavaju neki zadatak a pisane su tako da ih računalo može razumjeti. Programiranje – posao oko pripreme i pisanja programa. Programer – osoba koja se bavi programiranjem. Programski jezik – skup pravila riječi i simbola pomoću kojih se pišu programi. Strojni jezik – osnovni jezik računala; jezik nula i jedinica Već smo rekli da računalo sve podatke čuva u digitalnom obliku tj. kao niz nula i jedinica. Znamenka nula ili 1 se naziva binarna znamenka odnosno bit. Niz od 8 bitova nazivamo bajt (byte). Postavlja se pitanje kako je moguće slova, slike, zvuk,… pretvoriti u bitove? Jedan od načina kako se npr. znakovi zapisuju u digitalnom obliku je ASCII kôd (American Standard Code for Information Interchange). ASCII kôdom je moguće kodirati ukupno 128 znakova, koji u tom slučaju imaju kôdove od 0 do 127. Slovo A se u ASCII tablici nalazi na 65. mjestu, B na 66. mjestu,… Mala slova započinju na 97. mjestu,… Osim ASCII kôda često je u upotrebi i tzv. prošireni ASCII kôd, pomoću kojega je moguće zapisati ukupno 256 različitih znakova. Prvih 128 znakova proširenog ASCII kôda isti su kao i kod ASCII kôda i oni su jednaki za sve zemlje. Sljedećih 128 znakova nije standardizirano i tu se nalaze specijalni znakovi za pojedine zemlje. Kod nas se tu nalaze slova Č, Ć, Ž,… Kod oba navedena kôdiranja znakovi se zapisuju pomoću 8 bitova (kod ASCII kôda je prvi bit uvijek 0) i to tako da se redni broj znaka pretvori u binarni zapis. Tako je binarni kôd slova A 01000001,… Osim dva navedena, postoji još niz drugih načina kôdiranja. Jedan od nama značajnijih je tzv. unicode, pomoću kojega je moguće kôdirati ukupno 65536 znakova. Ovaj način kôdiranja nam

Page 7: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

7

ja bitan jer ga koristi Java. Prvih 128 znakova isto je kao i kod ASCII kôda, a za zapis jednog znaka koristi se 16 bitova (2 bajta). Bit – osnovna jedinica podataka sadrži jednu binarnu znamenku (0 ili 1). Bajt (B) – niz od 8 bitova. Kilobajt (KB) – 1024 bajta. Megabajt (MB) – 1024 kilobajta Gigabajt (GB) – 1024 megabajta ASCII kôd – jedan od načina kodiranja znakova, pomoću kojega je moguće kodirati ukupno 128 različitih znakova. Prošireni ASCII kôd – omogućava kôdiranje 256 različitih znakova Unicode – omogućava kodiranje 65536 različitih znakova (koristi ga Java)

Page 8: Java i objektno orijentirano programiranje

8

Povijest programskih jezika Čitava povijest programskih jezika moguće je svrstati u dvije osnovne kategorije:

� strojni jezici � simbolički jezici

Strojni jezici Programi pisani u strojnom jeziku pisani su tako da ih računalo može neposredno izvršavati bez prijašnjeg prevoñenja. Program se sastoji od niza binarnih znamenaka. Programiranje na strojnom jeziku je izuzetno naporan i mukotrpan posao. Mogućnosti pogreške su vrlo velike. Svako računalo ima svoj strojni jezik. Program napisan na jednom računalu ne može se izvršavati na drugom računalu, često čak niti na različitim računalima istog proizvoñača. Simbolički jezici Kao što smo rekli, programiranje u strojnom jeziku nije niti malo ugodan posao. Prvi korak prema nešto naprednijim programskim jezicima bilo je napraviti programski jezik koji će naredbe strojnog jezika zamijeniti riječima, čime će pamćenje i pisane naredbi biti znatno pojednostavljeno. Kao rezultat toga nastao je assembler. Svaka naredba assemblera je u stvari sinonim za odreñenu naredbu strojnog jezika. U tablici 1-1 dan je primjer naredbi u assembleru i nekom strojnom jeziku. Assembler Strojni jezik LOAD 00100100 STOR 00100010 MULT 00100110 ADD 00100101 SUB 00100011

Tablica 1-1 Naredbe zapisane u assembleru i nekom strojnom jeziku Nakon što napišemo program u assebmleru, zadaća assemblera je taj program prevesti u strojni jezik kako bi ga računalo moglo izvršiti. Assembler je još poznat i kao niži simbolički jezik. Iako pojednostavljeno, programiranje u assembleru je i dalje dosta nespretno. Stoga se pojavljuju tzv. viši programski jezici. Viši programski jezici su više orijentirani programeru. Programiranje je daljnje pojednostavljeno. Unutar kategorije viših programskih jezika postoje dvije osnovne potkategorije:

� proceduralni jezici – u središtu ovakvih programskih jezika nalazi se postupak odnosno procedura kako nešto napraviti. U tu kategoriju spada većina danas poznatih programskih jezika Pascal, C, Java,…

� neproceduralni jezici – za razliku od proceduralnih jezika kod kojih je težište stavljeno postupak kako nešto napraviti, kod neproceduralnih jezika je težište stavljeno na ono što želimo dobiti a ne zamaramo se postupkom kako ćemo to dobiti. U ovu skupinu spadali bi jezici kao što su Excel, SQL,… Ovi su jezici još više orijentirani prema programeru. Osnovni nedostatak ovakvih jezika leži u činjenici da su ograničeni na rješavanje samo jedne klase problema (Excel – tablični proračuni, SQL – rad s bazama podataka,…)

Page 9: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

9

Kao i kod nižih simboličkih jezika, programe napisane u nekom višem simboličkom jeziku potrebno je prevesti na strojni jezik. Općenito postoje dva načina na koji se jezici prevode na strojni jezik:

� kompajliranje – čitav program se prevede na strojni jezik a tek potom se izvrši, poznatiji kompajleri bili bi: Pascal, C,…

� interpetiranje – naredba po naredba programa se prevodi i odmah izvršava, poznatiji interpreteri su: ASP, PHP, Basic,…

Java ne spada nije u potpunosti niti komplajler niti interpreter. Više govora o prevoñenju programa pisanih u Javi bit će u nastavku. Program napisan u višem programskom jeziku naziva se izvorni program (source code). Nakon prevoñenja izvornog programa dobiva se izvršna verzija programa (executable program).

Slika 1-1 Shematski prikaz programskih jezika

Primjer 1 – 1: Dio programa, koji računa zbroj dva broja (c=a+b ), zapisan u strojnom jeziku, assembleru i Javi. Strojni jezik Assembler Java 00100100 00010001 00100101 00010010 00100010 00010011

LOAD a ADD b STOR C

c = a + b;

Strojni jezici – jezici kod kojih se naredbe pišu isključivo pomoću binarnih znamenaka. Programi napisani u strojnom jeziku mogu se direktno očitavati u memoriju računala. Assembler – niži simbolički jezik kod kojeg svaka naredba predstavlja odgovarajuću naredbu u strojnom jeziku. Proceduralni jezici – jezici kod kojih programer odreñuje na koji će se način rješavati neki problem. Neproceduralni jezici – jezici kod kojih se programiranje svodi na opisivanje rezultata koji se želi dobiti a ne programira se način na koji se dolazi do rješenja. Kompajler (compiler) – program koji prevodi čitav program na strojni jezik a tek potom se program izvršava.

programski jezici

strojni jezici simbolički jezici

niži simbolički jezici viši simbolički jezici

proceduralni neproceduralni

Page 10: Java i objektno orijentirano programiranje

10

Interpreter – program koji prevodi naredbu po naredbu izvornog programa te ju odmah izvršava. Izvorni program (source code) – program pisan u nekom višem simboličkom jeziku, naredbe su pisane u onom obliku u kojem ih piše programer Izvršni program (executable program) – program koji se dobije prevoñenjem izvornog koda na strojni jezik a koji se može izvršavati na računalu.

Tehnike pisanja programa Sve do prije nekoliko godina većina je programskih jezika bazirala na tzv. strukturnom programiranju. Zadani problem se dijeli na manje probleme koji se zatim neovisno rješavaju i ponovo spajaju kako bi se došlo do rješenja zadanog problema. Strukturno programiranje karakterizira nastojanje da se programer usredotoči na način kako će riješiti neki problem, a da pri tome ne treba puno voditi računa kako će se pojedina naredba izvesti na razini samog hardvera. Programi se rastavljaju na potprograme (funkcije i procedure), koji se tada po potrebi mogu pozivati u različitim dijelovima programa. Strukturno programiranje poznato je još i kao top-down, odnosno modularno programiranje. Najpoznatiji strukturni programski jezici su Pascal, C, Basic… U posljednjih nekoliko informatika se razvija toliko brzo da se javlja potreba za novim načinom programiranja koje će biti još efikasnije. Osnovni cilj je napraviti program čiji će se dijelovi moći ponovo upotrijebiti u drugim programima. Kao posljedica toga javlja se drugačiji način programiranja a to je objektno-orijentirano programiranje. Prvi korak pri rješavanju problema kod objektno-orijentiranog programiranja je unutar zadanog problema identificirati važne dijelove koje nazivamo objekti. Sljedeći korak je pronaći odnose izmeñu objekata. Želimo li npr. napisati program koji će simulirati vožnju automobila, osnovni objekti koji će karakterizirati taj problem bit će automobil i vozač. Sljedeći korak bio bi odrediti neka osnovna svojstva objekata. U našem bi primjeru neka svojstva automobila bila marka automobila, maksimalna brzina, ubrzanje,… dok bi za vozača neka od svojstava mogla biti ime i prezime, visina, težina,… Nadalje nam preostaje definirati neke operacije nad objektima. Neke od operacija mogle bi biti povećavanje brzine, koćenje,… Kao što se može primijetiti na danom primjeru, za svaki su objekt definirane neke osnovne karakteristike koje ga opisuju – svojstva, te operacije koje se nad njim mogu izvršavati – metode. Programski jezici koji omogućavaju objektno-orijentirano programiranje zovu se objektno orijentirani programski jezici. Svi noviji programski jezici su više ili manje objektno-orijentirani. Java je u potpunosti objektno orijentirani programski jezik. I u ovom je trenutku jedan od najboljih izbora za učenje objektno-orijentiranog programiranja. Pascal i C su isto na neki način objektno-orijentirani, u njima je isto moguće kreirati objekte, dodjeljivati im svojstva,… no u osnovi su ti jezici strukturni i sama priroda im nije objektno-orijentirana.

Page 11: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

11

Zadaci za vježbu

1. Što je program? 2. Objasni pojam programiranje. 3. Što je programski jezik? 4. Objasni pojam kodiranje. 5. Koja je razlika izmeñu ASCII i Unicode koda? 6. Objasni razliku izmeñu strojnih i simboličkij programskih jezika. 7. Koji je najpoznatiji niži simbolički jezik? 8. Navedi neke više programske jezike. 9. Objasni razliku izmeñu kompajliranja i interpretiranja. 10. Navedi nekoliko kompajlera i nekoliko interpretera. 11. Koje su dvije najčešće tehnike pisanja programa? Objasni!

Page 12: Java i objektno orijentirano programiranje

12

2 Uvod u Javu

� Programski jezik Java � Izvršavanje Java programa � BlueJ razvojno okruženje � Elementi Jave � Tipovi podataka � Prvi programi

Page 13: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

13

Programski jezik Java Krajem 1990 godine skupina programera tvrtke SUN krenula je u kreiranje jedinstvenog programskog jezika čije će se aplikacije moći izvršavati ne samo na računalima već i na ostalim ureñajima koji u sebi sadrže mikročipove (televizor, perilica rublja, toster, …). Nakon nepunih 5 godina svjetlo dana je ugledao novi programski jezik poznat pod imenom Java. Java je danas poznata kao programski jezik čije se aplikacije mogu izvršavati na Internetu, na računalima različitih proizvoñača i različitih operativnih sustava. To znači da se ista aplikacija može izvršavati na PC-u, Mac-u, … odnosno ista se aplikacije može izvršavati pod operativnim sustavom Windows, Unix, Linux,… Svjedoci smo da se danas Java aplikacije izvršavaju na Internetu, mobilnim telefonima ali i mnogim drugim ureñajima. Java je jednostavan, u potpunosti objektno-orijentirani programski jezik. Sintaksa Jave podsjeća na sintaksu C-a odnosno C++-a. No isto tako, kako zbog potpune objektno-orijentiranosti ali i niza drugih karakteristika dosta razlikuje od njih. Prema nekim autorima poznavanje jezika kao što su C odnosno C++ može biti čak otežavajuće za učenje Jave jer programer u početku koristi ono što već zna iz drugih jezika i teško usvaja mogućnosti koje mu nudi Java. Kod Jave razlikujemo dvije vrste "programa":

� aplikacije (application) � apleti (applet)

Aplikacija je program koji se nalazi na računalu korisnika i izvršavaju se kada ih korisnik pokrene. Klasični primjeri aplikacija bili bi npr. Warcraft III, Microsoft Word,…Da bi se Java aplikacije mogle izvršavati na računalu korisnika računalo mora imati instaliran Javin izvršni program (Java Virtual Machine), koji može pokrenuti aplikaciju pisanu u Javi. Većina današnjih operativnih sustava u sebi imaju ugrañen Java Virtual Machine. Za razliku od aplikacije, aplet je svojevrsna Internet aplikacija koja se izvršava u pregledniku (Internet Explorer, Netscape Navigator,…). Apleti su u stvari aplikacije koje "žive" na Internetu i pokreću se učitavanjem stranice na kojoj se nalaze. Zbog činjenice da se izvršavaju na Internetu apleti su daleko siromašniji u svojim mogućnostima. Kao i ostale Internet aplikacije apleti najčešće nemaju mogućnost pisati po tvrdom disku korisnika. Ne mogu upotrebljavati sve resurse korisnikovog računala, ali imaju jednu veliku prednost a to je činjenica da se nalaze na Internetu i bez instaliranja su dostupne svim korisnicima Interneta. Aplikacija – program koji se samostalno izvršava na računalu korisnika Applet – "mali program" koji se izvršava na Internetu, izvršava se unutar nekog od Web preglednika (Internet Explorer, Netscape Navigator,…)

Page 14: Java i objektno orijentirano programiranje

14

Izvršavanje Java programa Kao što smo već napomenuli programi pisani u Javi mogu se izvršavati ne samo na različitim operativnim sustavima već i na različitim ureñajima. Zbog toga se programi pisani u Javi izvršavaju malo drugačije nego što je to uobičajeno. Kao i kod ostalih programskih jezika, programer u odabranom editoru piše kôd programa sljedeći pravila Jave. Takav program, naziva se izvorni program (source program ili source code). Svaki program napisan u Javi u stvari predstavlja jednu klasu (class) čije se ime navodi u izvornom programu. Tako napisani izvorni program potrebno je spremiti u tekstualni dokument pod imenom ime_klase.java , pri čemu je ime klase ime klase koje smo naveli u izvornom programu. Nakon što je izvorni program napisan i spremljen slijedi druga faza a to je prevoñenje programa (kompajliranje) u tzv. bajt-kôd (bytecode) oblik programa. Prilikom prevoñenja programa prevoditelj analizira sintaksnu i semantičku ispravnost programa. U kôdu traži elemente Jave te ih interpretira i prevodi u univerzalni bajt-kôd, koji će se moći izvršavati neovisno o operativnom sustavu i u tome i jest osnovna razlika izmeñu Jave i ostalih programskih jezika. Kod ostalih se programskih jezika kompajliranjem stvara kôd specifičan za odgovarajući operativni sustav.

Slika 2-1 Kompajliranje Javi programa na različitim operativnim sustavima

Slika 2-2 Standardno kompajliranje programa na različitim operativnim

sustavima Ukoliko prilikom prevoñenja prevoditelj naiñe na izraze ili dijelove koje ne zna interpretirati prijavit će odgovarajuću grešku i kompajliranje neće biti uspješno završeno. Krajnji rezultat kompajliranja je datoteka pod imenom ime_klase.class . Nakon kompajliranja programa, program je spreman za pokretanje. Program se pokreće pokretanjem datoteke .class . Java apleti se pokreću pomoću Web preglednika odnosno

izvorni program

Windows kompajler

Unix kompajler

izvršni program (Windows)

izvršni program (Unix)

izvorni program

Windows Java kompajler

Unix Java kompajler

bajt-kôd

Windows JVM

Unix JVM

Page 15: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

15

pomoću odgovarajućeg programa koji omogućava pokretanje apleta – AppletViewer. Samo izvršavanje Java programa i nije tako jednostavno. Naime, prilikom pisanja programa programer najčešće koristi neke već gotove dijelove kôda. Npr. koristi već gotove naredbe za unos podataka s tipkovnice, ispis podataka na ekran, kreiranje korisničkog sučelja,… koje programeru znatno olakšavaju posao. Java u tu svrhu sadrži svoj Java development kit (JDK). Java development kit u osnovi sadrži niz gotovih klasa koje su vrlo korisne prilikom programiranja. Nakon što je program kompajliran, on se i dalje referencira na gotovi kôd iz JDK-a. Taj dio kôda nalazi se unutar tzv. biblioteka (library). Biblioteke su u Javi organizirane u pakete (package) koji su u stvari skupovi već gotovih klasa. Povezivanje bajt-kôda kreirane aplikacije s dijelovima odgovarajućih biblioteka zadaća je programa koji nazivamo linker. Sada možemo detaljnije objasniti izvršavanje programa pisanih u Javi. Najprije se bajt-kôd napisanog programa povezuje s odgovarajućim bibliotekama a potom se učitava u radnu memoriju računala. Učitavanje programa u radnu memoriju računala automatski izvršava program poznat kao loader. Kao što smo već spomenuli program je u stvari niz instrukcija koje se izvršavaju. Isto smo tako rekli da se računalo razumije samo naredbe napisane u strojnom jeziku. Naš program se i dalje nalazi u bajt-kôdu. Prevoñenje naredbi iz bajt-kôda u strojni jezik obavit će interpreter. Interpreter je još jedan u nizu programa čija je zadaća prevoditi naredbu po naredbu u strojni jezik računala i potom ju izvršiti. Kao što smo već rekli bajt-kôd Java programa može se izvršavati na različitim operativnim sustavima. Jedino što je potrebno da bi se bajt-kôd izvršio na nekom računalu je Java Virtual Machine (JVM). Java Virtual Machine razumije bajt-kôd te omogućava prevoñenje programa na strojni jezik računala.

Slika 2-3 Izvršavanje programa pisanih u Javi

Izvorni program (source program, source code) – program napisan u nekom višem programskom jeziku. Bajt-kôd – optimizirani skup naredbi kreiranih tako da se mogu izvršavati na bilo kojem operativnom sustavu. Nastaje kompajliranjem izvornog programa. AppletViewer – program koji omogućava pokretanje apleta izvan Web preglednika Java development kit (JDK) – programska oprema za pisanje programa u Javi

izvorni program

bajt-kôd

naredbe u strojnom jeziku

kompajler

linker

biblioteke

loader

interpreter

Page 16: Java i objektno orijentirano programiranje

16

Biblioteka (library) – skup svih klasa koje su već definirane i koje se mogu pozivati unutar programa Paket – skup meñusobno povezanih klasa Linker – program koji povezuje bajt-kôd s već gotovim klasama iz JDK Loader – program koji učitava izvršni program u radnu memoriju računala Interpreter – program koji prevodi jednu po jednu naredbu iz bajt-kôda u strojni jezik računala te ju izvršava. Java Virtual Machine – izvršni sustav za izvršavanje Java bajt-kôda na nekom računalu.

BlueJ razvojno okruženje Da bismo započeli programirati u Javi potreban nam je u najmanju ruku Java interpreter koji će izvorni program prevesti u bajt-kôd. Izvorni program moguće je napisati u bilo kojem editoru. Programiranje u nekom običnom editoru nije baš ugodno. U običnom editoru nije vidljiva razlika izmeñu naredbi programskog jezika, komentara, ili teksta koji se ispisuje, što može znatno otežati programiranje. Stoga danas za većinu jezika postoje okruženja za pisanje programa tzv. razvojna okruženja. Razvojna okruženja čine programiranje "ugodnijim". Editori razvojnih okruženja najčešće različitim bojama označavaju ključne riječi, komentare, varijable,… Novija su razvojna okruženja još inteligentnija pa na osnovu prvih nekoliko znakova predviñaju unos, što znatno može olakšati posao programeru. Većina današnjih velikih informatičkih tvrtki nudi razvojna okruženja za Javu. Borland je npr. napravio JBuilder, Microsoft je napravio J++, Sun je napravio Java Workshop,… Većina ovih okruženja je komercijala i cijena im je nerijetko dosta visoka. Naše će razvojno okruženje u ovoj knjizi biti BlueJ. BlueJ je razvojno okruženje koje korisniku omogućava da "razmišlja na objektni način". Osim toga izuzetno je pogodan za kontrolu izvršavanja pojedinog dijela programa. No imajmo na umu i jedan bitan detalj a to je činjenica da je BlueJ besplatan i dostupan svima na Internetu. BlueJ razvojno okruženje napisan je u Javi što omogućava njegovo izvršavanje na svim operativnim sustavima. Razvojno okruženje – skup programa koji programiranje u nekom programskom jeziku čine ugodnijim. Najčešće u sebi imaju ugrañen editor za pisanje programa, omogućavaju kompajliranje programa, omogućavaju kontrolu izvršavanja programa,… BlueJ – besplatno Java razvojno okruženje namijenjeno prvenstveno učenju objektno-orijentiranog programiranja u Javi. Prije instalacije BlueJa na računalo potrebno je instalirati Java 2 runtime (JDK). JDK i BlueJ nalaze se na CD-u u prilogu ove knjige. Pokretanjem BlueJ aplikacije na ekranu će se pojaviti sučelje koje će nam omogućiti pisanje programa.

Page 17: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

17

Slika 2-3 Sučelje BlueJ razvojnog alata

Nakon što smo pokrenuli program za početak ćemo otvoriti novi projekt. Novi projekt ćemo otvoriti tako da u izborniku Project odaberemo New Project.

Slika 2-4 Kreiranje novog projekta

Nadalje ćemo u prozoru koji se otvori upisati ime projekta. BlueJ će potom kreirati poseban direktorij s upisanim imenom te će otvoriti novi prozor za upravo kreirani projekt.

Page 18: Java i objektno orijentirano programiranje

18

Slika 2-5 Prozor kreiranog projekta

Sljedeći korak je dodavanje klase u projekt. Klasu ćemo u ovom trenutku poistovjetiti s programom. Više riječi o klasama bit će u sljedećim poglavljima. Novu ćemo klasu kreirati tako da kliknemo na gumb New Class… koji se nalazi pri vrhu lijevog dijela prozora. U prozoru koji se otvori upišemo ime klase.

Slika 2-6 Prozor za kreiranje klase

Nakon što smo kliknuli na gumb OK prozor će se zatvoriti i u postojećem prozoru će se pojaviti još jedna sličica koja će predstavljati upravo kreiranu klasu, a pri vrhu sličice će se nalaziti ime klase (zbroj).

Page 19: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

19

Slika 2-7 Kreirana klasa je dodana u projekt

Ovime definicija klase nije gotova. Štoviše definicija klase tek slijedi. Stoga ćemo kliknuti desnim gumbom miša na sličicu klase zbroj i u izborniku odabrati Open Editor ili jednostavno 2 puta kliknuti lijevim gumbom miša na ime klase.

Slika 2-8 Pokretanje editora za definiranje klase

U editoru koji se je otvorio nalazi se već upisan dio klase koju želimo kreirati. Za početak ćemo izbrisati sadržaj prozora i upisati sljedeći kôd: public class zbroj { public static int zbroj( int x, int y) {

Page 20: Java i objektno orijentirano programiranje

20

return x + y; } }

Slika 2-9 Izgled prozora nakon što upišemo kôd klase

Sljedeći je korak kompajliranje ovako programa. Da bismo program kompajlirali lijevim ćemo gumbom miša kliknuti na gumb Compile u gornjem izborniku prozora. Prije samog kompajliranja program će se spremiti. Ukoliko kompajler nije naišao na greške u kôdu, u donjem će se dijelu prozora pojaviti poruka: Class compiled - no syntaks errors Ponovo ćemo se vratiti na prozor u kojem su prikazane sve klase našeg projekta (Slika 2-8) te ćemo desnim gumbom miša kliknuti na sličicu klase zbroj te ćemo iz izbornika odabrati int zbroj(x, y). Time ćemo u stvari pokrenuti metodu zbroj() klase zbroj .

Slika 2-10 Pokretanje metode zbroj()

Budući da metoda zbroj() ima dva ulazna parametra (varijable) (x i y ) te vraća njihov zbroj, otvorit će se novi prozor unutar kojeg ćemo upisati vrijednosti za parametre x i y .

Page 21: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

21

Slika 2-11 Okvir za definiranje vrijednosti parametara metode Klikom na gumb OK otvorit će se novi prozor u kojem će se nalaziti vrijednost koju metoda vraća. Budući da naša metoda računa zbroj brojeva x i y rezultat će, za unesene vrijednosti 4 i 5 biti 9.

Slika 2-12 Rezultat izvršavanja metode

Jednom kreiranu klasu moguće je ponovno otvarati i po potrebi mijenjati te izvršavati. Klasu ćemo otvoriti tako da u izborniku Project odaberemo Open Project.

Slika 2-13 Otvaranje postojećeg projekta

Page 22: Java i objektno orijentirano programiranje

22

U prozoru koji se otvori odaberemo ime projekta koji želimo otvoriti.

Slika 2-14Odabiranje projekta koji želimo otvoriti

Na kraju ćemo kliknuti na gumb Open i pojavit će se prozor u kojem će se nalaziti sve klase odabranog projekta.

Slika 2-15 Prozor s klasama odabranog projekta

Pojmove kao što su klasa, metoda,… s kojima smo se ovdje susreli detaljno ćemo objasniti u nastavku knjige. Za sada će za nas klasa biti program a metodu možemo zamisliti kao manji program unutar velikog programa. Metoda ima svoje ulazne parametre, to su u stvari podaci koji su metodi potrebni da bi riješila neki problem. U opisanom primjeru imali smo jednu metodu zbroj() koja je računala zbroj dvaju prirodnih brojeva. Da bi metoda mogla izračunati zbroj dva broja treba znati koji su to brojevi, stoga je imala dva ulazna parametra, brojeve x i y .

Page 23: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

23

Elementi Jave Da bismo uspješno programirali u nekom programskom jeziku trebamo dobro vladati njegovim sintaksnim i semantičkim pravilima, ključnim riječima te specijalnim znakovima. Sintaksa jezika odnosi se na naredbe programskog jezika, objašnjava kako izgledaju ispravno napisani izrazi (naredbe),... Semantika se odnosi na značenje naredbi, tj. što ta naredba radi. Specijalni znakovi su znakovi koji imaju svoje značenje unutar programskog jezika. Neki od specijalnih znakova dani su sljedećom tablicom: Kategorija Specijalni znakovi matemati čki + - * / interpunkcijski . , ? ; relacijski < <= > >= == !=

Tablica 2-1 Najčešće korišteni specijalni znakovi u Javi Kao što postoje simboli koji imaju svoje specijalno značenje, tako postoje i riječi koje imaju specijalno značenje, koje nazivamo rezervirane riječi (keywords). Neke od njih su: class, public, private, static, int, float, boolean,... Kao što smo mogli primijetiti u primjeru iz zadnjeg poglavlja, pri samom kreiranju klase, morali smo joj dodijeliti ime (zbroj), nadalje smo metodi isto tako morali dodijeliti ime (zbroj), a dodatno smo imenovali i parametre (varijable) u metodi (x, y). Općenito ćemo sva takva i slična imena zvati identifikatori. Identifikatori u Javi mogu se sastojati od slova engleske abecede, znamenaka i znakova "_" i "$", pri čemu znamenka ne može biti na prvom mjestu. Duljina identifikatora (broj znakova) u Javi nije ograničena. Ovdje je isto tako bitno napomenuti da je Java case sensitive jezik, što znači da se velika i mala slova razlikuju (npr. Zbroj i zbroj su dva različita identifikatora). Primjer 2 – 1: Sljedeći identifikatori su korektno napisani: prvi $2 _treci$a Primjer 2 – 2: Primjeri neregularnih identifikatora: 1a – na prvom mjestu se ne smije nalaziti znamenka zbroj brojeva – sadrži razmak kuća – nedozvoljeni znak ć Kako bismo se u vlastitom kodu uspješno snalazili i nakon nekog vremena, odnosno kako bismo olakšali razumijevanje koda svima onima koji će ga kasnije čitati, koristit ćemo komentare. Općenito je namjena komentara da se unutar njih stavljaju objašnjenja koda ili neke napomene za izmjene programa. Želimo li u komentar staviti samo jednu liniju koda, na početku te linije ćemo staviti //.

//komentar Više linija koda ćemo staviti u komentar tako da na početku prve linije koda stavimo /*, te iza posljednjeg znaka stavimo */.

Page 24: Java i objektno orijentirano programiranje

24

/* komentar1 komentar2 komentar3 */ Npr. //ovo je komentar ili /* ovo je komentar */

Page 25: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

25

Tipovi podataka U osnovi kod Jave razlikujemo dvije kategorije tipova podataka:

− objektni tipovi podataka − neobjektni tipovi podataka

Objektni tipovi podataka definirani su klasama i o njima će biti govora nešto kasnije. Neobjektni (jednostavni) tipovi podataka i shematski su prikazani na sljedećoj slici:

Slika 2-16 Jednostavni tipovi podataka

cjelobrojni

realni

logički

byte

short

int

long

float

double

boolean

znakovni char

Page 26: Java i objektno orijentirano programiranje

26

Jednostavni tipovi podataka Cjelobrojni tip podataka Unutar cjelobrojnog tipa podataka postoji nekoliko podtipova. Podtipovi se razlikuju s obzirom na raspon vrijednosti za koje su definirani, što neposredno utječe na količinu memorije koju zauzimaju. Raspon vrijednosti i količina memorije potrebne za spremanje jedne varijable dani su sljedećom tablicom: Tip podataka Raspon vrijednosti Zauzeće memorije

(bitovi) byte -128 do 127 8 short -32768 do 32767 16 int -2147483648 do 2147483647 32 long -922337203684547758808 do 922337203684547758807 64

Tablica 2-2 Cjelobrojni tipovi podataka Znakovni tip podataka Tip podataka char namijenjen je radu s znakovima. Vrijednosti koje ovaj tip podataka može primiti su bilo koji znak iz tzv. Unicode skupa znakova. Znakovi se navode unutar jednostrukih navodnika npr. ' A', ' 0', ' +', ' %',... Osim ovakvih znakova, tip podataka char sadrži i neke znakove koji postoje na tipkovnici, ali za njih ne postoji posebna oznaka (npr. tipka tab). Takvi znakovi sastoje se od oznake "\" i odgovarajućeg znaka. Neki od takvih oznaka dani su u sljedećoj tablici:

Znak Opis \' jednostruki navodnik \" dvostruki navodnik \\ kosa crta "\" \r prelazak u novi red (carriage return) \n prelazak u novi red (line feed) \t horizontalni tabulator \b backspace

Tablica 2-3 Neki od specijalnih znakova

Page 27: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

27

Realni tip podataka Kao što mu i ime govori, ovaj ćemo tip podataka koristiti pri radu s realnim vrijednostima. Java brojeve prikazuje u tzv. eksponencijalnom obliku. Kod takvog prikaza broj se sastoji od sljedećih elemenata:

− jednoznamenkasti cijeli broj − decimalna točka − 6 decimala − znak "E" − eksponent

Primjer 2 – 3: Primjer zapisa realnih brojeva u eksponencijalnom obliku broj eksponencijalni zapis objašnjenje 315.46 3.154600E2 315.46 = 3.1546 · 102 0.02 2.000000E-2 0.02 = 2 · 10-2 -3.14 -3.140000E0 -3.14 = -3.14 · 100 Osnovni podtipovi realnog tipa podataka su dani su sljedećom tablicom: Tip podataka Raspon vrijednosti Zauzeće memorije

(bitovi) float -3.4 · 1038 do 3.4 · 1038 32 double -1.7 · 10308 do 1.7 · 10308 64

Tablica 2-4 Realni tipovi podataka Osim po rasponu vrijednosti i količini memorije koju zauzimaju, ovi se tipovi podataka razlikuju i s obzirom na preciznost, tj. s obzirom na broj bitnih decimalnih znamenaka. Broj decimalnih znamenaka koje će se uzimati u obzir kod float tipa podataka je 6 ili 7, odnosno 15 kod double . Logički tip podataka Logički tip podataka (boolean ) može sadržavati samo dvije vrijednosti true ili false (istina ili laž). Memorija potrebna za pohranjivanje vrijednosti tipa boolean je 1 bit.

Page 28: Java i objektno orijentirano programiranje

28

Deklaracija varijabli Kao što smo već rekli, varijable su u stvari "oznake" za memorijske lokacije na koje ćemo privremeno pohranjivati podatke tijekom izvršavanja programa. Prije pohranjivanja vrijednosti trebamo odrediti koji tip vrijednosti ćemo pohraniti na odgovarajuću lokaciju, te rezervirati (alocirati) prostor. To sve ćemo napraviti deklaracijom varijabli. Opći oblik deklaracije varijabli u Javi je:

tip ime_varijable; gdje je tip bilo koji tip podataka (int , float , boolean , char ,...). Ukoliko se istovremeno deklarira više varijabli istog tipa, one se meñusobno odvajaju zarezom. Primjer 2 – 4: Primjeri deklaracija varijabli: int n; float a, b; char c; boolean t; Neki programski jezici deklariranjem varijable automatski postavljaju na neku početnu (inicijalnu) vrijednost, tj. inicijaliziraju ih na neku vrijednost. Npr. u Pascalu će varijabla tipa byte deklariranjem biti inicijalizirana na vrijednost 0. Kod Jave to nije slučaj. Kod Jave vrijednosti varijable nakon deklaracije ne moraju biti inicijalizirane, i ukoliko to ne napravimo eksplicitno a u programu koristimo takve varijable prilikom kompajliranja će se pojaviti greška. Varijabli ćemo pridružiti vrijednost operatorom "=". Primjer 2 – 5: Primjeri pridruživanja vrijednosti varijablama: n = 2; x = 3.14; c = 'c'; t = false ; Prilikom pridruživanja vrijednosti varijablama valja voditi računa da vrijednost koja se pridružuje varijabli bude istog tipa kao i varijabla. Vrijednost varijable moguće je inicijalizirati na neku vrijednost i prilikom deklaracije varijabli. U takvim slučajevima će deklaracija varijable imati sljedeći oblik:

tip ime_varijable = vrijednost; Primjer 2 – 6: Primjer deklaracije varijabli gdje se varijable inicijaliziraju neposredno iza deklaracije int i = 3; float x = -8.17;

Page 29: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

29

char c = 'y', d = 'n'; Isto tako je prilikom deklariranja varijabli i njihovog inicijaliziranja, moguće koristiti i izraze koji će varijabli inicijalno pridružiti vrijednost tog izraza. Kod ovakve inicijalizacije trebamo voditi računa da su sve varijable, koje koristimo s desne strane znaka jednakosti inicijalizirane. Primjer 2 – 7: Primjer deklaracije varijabli gdje se varijable inicijaliziraju neposredno iza deklaracije i to dodjeljivanjem vrijednosti izraza. int i = 3; int j = i*2; Operatori Osnovni cilj programiranja je na osnovu ulaznih podataka dobiti potrebne rezultate. Da bismo iz ulaznih podataka dobili rezultate trebamo nad podacima izvršiti odgovarajuće manipulacije. Manipulacije nad podacima izvršit ćemo pomoću operatora. Operatore u Javi dijelimo u nekoliko osnovnih kategorija:

− aritmetički operatori; − relacijski operatori; − logički operatori; − bitovni operatori.

S obzirom na koliko se podataka operator primjenjuje razlikujemo dvije vrste operatora:

− unarni operatori – primjenjuju se samo na jednu vrijednost (npr. operator ++, koji povećava vrijednost varijable za 1);

− binarni operatori – primjenjuju se na dvije vrijednosti (npr. operator + za zbrajanje dvaju brojeva).

Aritmetički operatori U Javi je moguće koristiti sljedeće aritmetičke operatore:

Operator Znaćenje + zbrajanje - oduzimanje * množenje / dijeljenje % ostatak cjelobrojnog dijeljenja ++ povećava vrijednost varijable za 1 -- smanjuje vrijednost varijable za 1 += povećavanje vrijednosti varijable za odreñeni broj -= analogno kao += *= analogno kao += /= analogno kao += %= analogno kao +=

Tablica 2 – 5 Aritmetički operatori

Page 30: Java i objektno orijentirano programiranje

30

Primjer 2 – 8: Koja će biti vrijednost varijable x nakon djelovanja odgovarajućih operatora, ako je x cjelobrojna varijabla čija je vrijednost postavljena na 5? a) x++; b) x = x + 3; c) x = x / 2; d) x = x % 3; e) x *= 3; Rješenja: a) 6 b) 8 c) 2 (budući da je x cjelobrojna varijabla operator / se tumači kao operator cjelobrojnog dijeljenja) d) 2 (5 cjelobrojno podijeljeno s 3 je 1 i 2 je ostatak) e) 15 Relacijski operatori Relacijski operatori koristi se za odreñivanje odnosa izmeñu dviju vrijednosti. Relacijski operatori dani su sljedećom tablicom:

Operator Znaćenje == jednako != različito > veće >= veće ili jednako < manje <= manje ili jednako

Tablica 2 – 6 Relacijski operatori Relacijski operatori == i != mogu biti upotrijebljeni nad svim tipovima podataka (neobjektnim i objektnim), dok operatori >, <, >=, <= mogu biti upotrijebljeni samo nad onim tipovima podataka koji imaju poredak, tzv. ordinalni ili redni tipovi podataka. Vrijednosti relacijskih operatora mogu biti true ili false. Primjer 2 – 9: Koje će biti vrijednosti sljedećih izraza? a) 3 <= 5 b) 'a' < 'A' c) 3 != 5 Rješenja: a) true (3 je manje od 5) b) false (slovo 'a' se u Unicode tablici nalazi iza slova 'A') c) true (3 je različito od 5)

Page 31: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

31

Logički operatori Logički operatori definirani su nad logičkim tipom podataka (boolean), vrijednosti na koje se ovi operatori primjenjuju i rezultati mogu biti samo vrijednosti true ili false. Najčešće korišteni logički operatori dani su sljedećom tablicom:

Operator Znaćenje ! negacija && logički I || logički ili

Tablica 2 – 7 Logički operatori Djelovanje logičkih operatora prikazano je u sljedećom tablicom:

a b !a a && b a || b false false true false false false true true false true true false false false true true true false true true Tablica 2 – 8 Djelovanje logičkih operatora

Primjer 2 – 10: Koje će biti vrijednost varijable c nakon odgovarajućih operacija, ako je vrijednost varijable a = true i b = false ? a) ! a b) b && a c) ! (a && b) d) a && (b || (!b)) Rješenja: a) false b) false c) false d) true e) true

Page 32: Java i objektno orijentirano programiranje

32

Prioritet operatora Promotrimo sljedeći izraz: c = 2 + 3 * 5; nije sasvim jasno koju će vrijednost imati varijabla c nakon ovakvog pridruživanja. Hoće li se najprije izvršiti zbrajanje pa nakon toga množenje ili će se najprije izvršiti množenje pa nakon toga zbrajanje? Kao što postoji prioritet operatora u matematici, tako postoji i u Javi i štoviše dosta su slični. Prioritet operatora dan je sljedećom tablicom:

Prioritet Operatori 1 () 2 ++, --, ! 3 *, /, % 4 +, - 5 <, <=, >, >= 6 ==, != 7 && 8 ||

Tablica 2 – 9 Prioritet operatora Općenito se izrazi izvršavaju od lijeva na desno. Primjer 2 – 11: Vrijednost izraza 2 + 3 * 4 će biti 14, najprije se izvršava množenje (3 * 4), a zatim zbrajanje (2 + 12) Izračunavanje mješovitih izraza Mješoviti izrazi su oni koji u sebi sadrže cjelobrojne i realne vrijednosti. Primjer takvog izraza je: 8 / 3 + 2.7 Primijetimo da nije svejedno hoćemo li brojeva 8 i 3 podijeliti kao cijele brojeve ili kao realne. Pravila za izvršavanje mješovitih izraza:

− ako su oba operanda, na koje se odnosi operator istog tipa (oba su cijeli ili realni brojevi), operator će se izvršiti kao operator nad tim tipom podataka

− ako operandi nisu istog tipa (jedan je cijeli a drugi realni broj), prilikom izračunavanja će se cijeli broj pretvoriti u realni

Primjer 2 – 12: Kolika će biti vrijednost izraza 5 / 3 + 3.5

Page 33: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

33

Budući da su brojevi 5 i 3 oba cijeli brojevi, vrijednost operatora 5 /3 bit će 1, te je izraz poprimio oblik 1 + 3.5. Kako je 3.5 realan broj a 1 cijeli, broj jedan će isto postati realan i tada će izraz imati oblik 3.5 + 1.0 = 4.5 Konverzija tipova (casting) U prethodnom smo odjeljku naučili kako se izračunavaju mješoviti izrazi. Meñutim često puta ćemo trebati neki tip podataka konvertirati u neki drugi (realni broj u cijeli ili obrnuto). Java omogućava konverziju tipova podataka pomoću posebnog operatora i to na sljedeći način:

(tip) (izraz); Ukoliko realni broj pretvaramo u cijeli, realnom će se broju jednostavno odbaciti decimale. Primjer 2 – 13: Izraz Vrijednost ( int ) (3.14); 3 ( float ) (10); 10.0 ( float ) (10) / 4; = 10.0 / 4 = 2.5 ( float ) (10 / 4); = float (2) = 2.0 Osim konverzije cijelih brojeva u realne i obrnuto, moguće je konvertirati i znakove u cijele brojeve i obrnuto. Pretvaranje znakova u cijele brojeve i obrnuto temelji se na Unicode tablici gdje je svaki broj predstavljen odgovarajućim brojem (kodom). Tako je npr. ( int ) ('b') 98 ('b' je na 98. mjestu u Unicode tablici), ( int ) ('8') je 56,... Analogno tome je ( char ) (98) 'b'.

Page 34: Java i objektno orijentirano programiranje

34

Prvi programi Sada, nakon što smo naučili osnovno identifikatorima, tipovima podataka, inicijalizaciji te operatorima, možemo započeti s pisanjem jednostavnih programa u Javi. Za nas će u ovom trenutku program biti jedna metoda unutar neke klase, koju ćemo pokretati direktno i prosljeñivati joj vrijednosti preko dijaloškog prozora (Slika 2 - 11). Svaki naš "program" će u ovom trenutku imati sljedeći oblik: public class ime_klase { public static tip ime_metode(parametri) { kod metode; return vrijednost; } } Primjer 2 – 14: Napišimo metodu kojoj ćemo prosljeñivati duljine stranica pravokutnika (cijeli brojevi), a koja će vraćati površinu tog pravokutnika. Rješenje: Budući da se radi o pravokutniku čije su stranice cijeli brojevi, površina tog pravokutnika bit će isto tako cijeli broj. Budući da naša metoda vraća površinu (cijeli broj), zaglavlje metode (prvi red) će biti: public static int povrsina (int a, int b) public i static ćemo za sada pisati u svim primjerima, a detaljno ćemo ih objasniti kasnije. int je tip podataka koji metoda vraća (cijeli broj) povrsina je ime metode int a, int b su popisi parametara koji se prosljeñuju metodi (duljine stranica pravokutnika) Budući da je površina pravokutnika jednaka umnošku duljina stranica, deklarirat ćemo varijablu P (cjelobrojnog tipa), u koju ćemo zapisati površinu pravokutnika. int P; P = a * b; Na kraju će metoda vratiti površinu, naredbom: return P; Dakle naš program će imati sljedeći oblik: public class pravokutnik { public static int povrsina( int a, int b) { int P; P = a * b; return P; } }

Page 35: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

35

Metodu ćemo nadalje pokrenuti na način kao što je to opisano na početku poglavlja. Primjer 2 – 15: Napišimo metodu koja će unositi duljine stranica trokuta i vraćati površinu tog trokuta. Površinu trokuta, čije su stranice a, b i c računat ćemo Heronovom formulom:

( )( )( )csbsassP −−−= , pri čemu je 2

cbas

++= .

Drugi korijen iz realnog broja računat ćemo naredbom Math.Sqrt (). Dakle, rješenje će biti: public static double povrsina( int a, int b, int c) { double P, s; s = (a + b + c) / 2; P = Math.sqrt (s * (s - a) * (s - b) * ( s - c)); return P; }

U prošlom smo primjeru koristili naredbu Math.sqrt () . Ova naredba računa drugi korijen iz realnog broja. Vrijednost koju ova naredba vraća je tipa double . Općenito Math je gotova Javina klasa koja sadrži metode za rad s matematičkim funkcijama. Neke od metoda klase Math dane su u sljedećoj tablici:

Metoda Opis abs (x) apsolutna vrijednost broja x ceil (x) najmanji cijeli broj koji je veći ili jednak od realnog broja x

(vrijednost koju vraća je tipa double ) exp (x) vraća vrijednost funkcije ex floor (x) najveći cijeli broj koji je manji ili jednak od realnog broja x

(vrijednost koju vraća je tipa double ) log (x) prirodni logaritam broja x max (x, y) veći od brojeva x i y min (x, y) manji od brojeva x i y random () vraća slučajan broj izmeñu 0.0 i 1.0 round (x) cijeli broj koji je najbliži realnom broju x (vrijednost koju

vraća je tipa double ) sqrt (x) drugi korijen iz broja x cos (x) kosinus kuta x (x je u radijanima) sin (x) sinus kuta x (x je u radijanima) tan (x) tangens kuta x (x je u radijanima)

Tablica 2 – 10 Neke od metoda klase Math .

Page 36: Java i objektno orijentirano programiranje

36

Zadaci za vježbu:

1. Što je aplikacija, a što applet? 2. Objasni postupak prevoñenja Java programa. 3. Što je razvojno okruženje? 4. Što je BlueJ i koje su mu osnovne karakteristike? 5. Zadana je klasa zad1 koja sadrži jednu metodu poruka () :

public class zad1 { public static String poruka() { return "Dobro jutro"; } }

a) Što će biti rezultat izvršavanja metode poruka () ? b) Izmjeni metodu poruka () tako da vraća poruku "Dobar dan"

6. Zadana je klasa zad2 koja sadrži jednu metodu potencija (x) :

public class zad2 { public static int potencija( int x) { return x * x; } }

b) Što će biti rezultat izvršavanja metode potencija (x) za vrijednost parametra x

= 3 ? c) Izmjeni metodu potencija (x) tako da vraća x * x * x

7. Zadana je klasa zad3 koja sadrži jednu metodu pravokutnik (a, b) :

public class zad3 { public static int pravokutnik( int a, int b) { return a * b; } }

b) Što će biti rezultat izvršavanja metode pravokutnik (a, b) za vrijednost

parametara a = 7 i b = 3 ? c) Izmjeni metodu pravokutnik (a, b) tako da vraća opseg pravokutnika

stranica duljina a i b

8. Zadana je klasa zad4 koja sadrži jednu metodu pozdrav (ime) :

public class zad4 { public static String pozdrav( String ime) {

Page 37: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

37

return "Ja sam " + ime; } }

a) Što će biti rezultat izvršavanja metode pozdrav (ime) za vrijednost parametra

ime = "Ana"? b) Izmjeni metodu pozdrav (ime) tako da npr. za vrijednost parametra ime =

"Iva" vraća poruku "Iva, jesi li dobro?"

9. Zadana je klasa zad5 koja sadrži jednu metodu izracunaj (x, y) :

public class zad5 {

public static String izracunaj (int x , int y) { int z = x + y ; return "Zbroj je " + z ; } }

a) Što će biti rezultat izvršavanja metode izracunaj (x, y) za parametre x = 3

i y = 5 ? b) Izmjeni metodu izracunaj (x, y) tako da računa razliku brojeva x i y te

ispisuje poruku "Razlika je " (operator oduzimanja je -) c) Izmjeni metodu izracunaj (x, y) tako da računa umnožak brojeva x i y te

ispisuje poruku "Umnožak je " (operator množenja je *)

10. Zadana je klasa zad6 koja sadrži jednu metodu zbroj (x, y) : public class zad6 { public static String zbroj( int x, int y) { int z = x + y; return x + " + " + y + " = " + z; } }

a) Što će biti rezultat izvršavanja metode zbroj (x, y) za vrijednost parametara x

= 7 i y = 11? b) Klasi zad6 dodaj metodu razlika (x, y) koja će vraćati razliku brojeva x i y i

to u obliku x – y = razlika, npr. za x = 9 i y = 2 treba vratiti 9 – 2 = 7 c) Klasi zad6 dodaj metodu umnozak (x, y) koja će vraćati umnožak brojeva x i

y i to u obliku x * y = umnozak, npr. za x = 4 i y = 9 treba vratiti 4 * 9 = 36 11. Definiraj klasu zad7 koja će sadržavati metodu sekunde (h, m, s) , čiji će

parametri biti vrijeme u satima (h), minutama (m) i sekundama (s). Metoda treba vraćati vrijeme izraženo u sekundama (1 sat ima 3600 sekundi, 1 minuta ima 60 sekundi).

12. Što je sintaksa a što semantika programskog jezika? 13. Što je identifikator? 14. Što znači da je neki jezik case senisitve? 15. Koje su dvije osnove kategorije tipova podataka u Javi? Objasni razliku. 16. Nabroji neke jednostavne tipove podataka. 17. Koji su podtipovi cjelobrojnog tipa podataka?

Page 38: Java i objektno orijentirano programiranje

38

18. Navedi realne tipove podataka u Javi. 19. Deklariraj varijable a, b, x i y tako da a i b budu cjelobrojnog a x i y realnog tipa. 20. Deklariraj cjelobrojnu varijablu a te joj prilikom deklaracije pridruži vrijednost 5. 21. Što će pisati u varijabli a nakon sljedeće naredbe:

a. a++; b. a--; c. a += 4; d. a *= 2; e. a = a % 5; f. a /= 2;

Ako varijabla a ima vrijednost 3; 20. Neka je a cjelobrojna varijabla. Napiši naredbu koja će:

g. vrijednost varijable a smanjiti za 5; h. vrijednost varijable a povećati za 1; i. vrijednost varijable a povećati 5 puta.

22. Odredi vrijednost sljedećih izraza:

a. 2 < 3 && 3 <= 2 b. ! (5 > 3 || ! (5 > 4))

23. Odredi vrijednost sljedećih izraza, ako varijabla a ima vrijednost true a varijabla b vrijednost

false: a. ! a; b. ! (a || b) c. (a || b) && ! b d. ( ! b && ! a) || ( ! a || ! b)

24. Što će pisati u varijabli c nakon izvršavanja sljedećih naredbi, ako je vrijednost varijable a jednaka 8, a varijable b 10: a) c = a + 2*b; b) c = 2 * (a + b); c) c = a % 3 * 4;

25. Izračunajte vrijednosti sljedećih izraza:

a. a * b; b. a * c; c. a / b; d. a / c; e. ( int ) a + c; f. ( int ) (a + c); g. a + ( int ) c + ( int )(c * a)

26. Napiši metodu čiji će ulazni parametri biti duljine stranica pravokutnika, metoda treba

vračati opseg pravokutnika.

ulaz izlaz 2 3

10

27. Napiši metodu čiji će ulazni parametar biti dvoznamenkasti prirodan broj n. Metoda treba

vračati apsolutnu vrijednost razlike znamenaka broja n.

Page 39: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

39

ulaz izlaz 48 4

28. Napiši metodu čiji će ulazni parametar biti troznamenkasti prirodan broj n. Metoda treba

vračati broj koji se dobije okretanjem broja n.

ulaz izlaz 123 321

29. Napiši metodu čiji će ulazni parametri biti realni i imaginarni dio dvaju kompleksnih

brojeva. Metoda treba vračati: a) zbroj kompleksnih brojeva;

ulaz izlaz 1 2 3 4

4 + 6i

b) umnožak kompleksnih brojeva;

ulaz izlaz 1 2 3 4

-5 + 10i

c) zbroj apsolutnih vrijednosti kompleksnih brojeva.

ulaz izlaz 1 2 3 4

7.236

30. Napiši metodu čiji će parametri biti sati, minute i sekunde početka te kraja filma. Metoda

treba vraćati trajanje filma (u satima, minutama i sekundama). Napomena: film će započeti i završiti u istom danu.

ulaz izlaz 19 10 00 21 05 11

1:55:11

Page 40: Java i objektno orijentirano programiranje

40

3

Naredbe grananja

� if, if/else naredba � switch/case naredba

Page 41: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

41

if, if/else naredba Metode koje smo do sada pisali su dobivale parametre izvana, uvijek su obavile iste operacije nad parametrima i vraćale rezultate. U praksi su takvi problemi izuzetno rijetki. Prvi sljedeći korak nakon ovakvih problema su problemi kod kojih se ovisno o nekom uvjetu izvršava odreñeni dio programa. U takvim slučajevima ćemo koristiti neku od naredbi grananja. U ovom ćemo se poglavlju detaljnije upoznati s naredbom if i svim njenim oblicima. Najjednostavniji oblik if naredbe je:

if (uvjet) naredba;

Shematski bi se ova naredba mogla prikazati kao:

Slika 3 – 1 Shematski prikaz naredbe grananja

Ukoliko je uvjet istinit izvršava se naredba , ukoliko je uvjet lažan ne dogaña se ništa, tj. prelazi se na prvu sljedeću naredbu iza if . Ukoliko je naredba složena naredba složena, tj. sastoji se od više jednostavnih naredbi, ona se navodi unutar vitičastih zagrada {}. Primjer 3 – 1: Ukoliko je vrijednost varijable n jednaka 65 varijabli, vrijednost varijable c će postati 'A'. if (n == 65) c = 'A'; Napomena: Ukoliko uvjet ne stavimo unutar zagrada, doći će do greške prilikom kompajliranja. Osim gore opisanog oblika if naredbe, često puta se koristi i tzv. if/else oblik. Sintaksa takvog oblika if naredbe je:

if (uvjet) naredba1;

else naredba2; Shematski bi takvu naredbu prikazali na sljedeći način:

uvjet naredba istina

laž

Page 42: Java i objektno orijentirano programiranje

42

Slika 3 – 2 Shematski prikaz if/else naredbe

Ukoliko je uvjet istinit izvršava se naredba1 , inače se izvršava naredba2 . Primjer 3 – 2: Napišimo metodu kojoj ćemo prosljeñivati koeficijente kvadratne jednadžbe a metoda će vraćati true ukoliko jednadžba ima realnih rješenja, inače će vraćati false . Rješenje: Prisjetimo se da će jednadžba imati realnih rješenja ako joj je diskriminanta veća ili jednaka od 0. Diskriminanta kvadratne jednadžbe 02 =++ cbxax dana je s acbD 42 −= . Dakle rješenje bi bilo: public static boolean RRjesenje ( int a, int b, int c) {

int D; D = b * b – 4 * a * c; if (D >= 0) return true; else return false;

} Primjer 3 – 4: Napišimo metodu koja će unositi iznos bruto plaće u kunama. Procedura treba vraćati iznos poreza na plaću, ako je poznato da je do iznosa od 5000 kn porez 15%, za iznos od 5000 do 10000 je porez 25%, te je za iznos iznad 10000 porez 35%. Rješenje:

uvjet naredba1 istina laž

naredba2

Page 43: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

43

switch/case naredba Često puta kod grananja nailazimo na više disjunktnih uvjeta. Korištenje if naredbe u takvim slučajevima može biti nespretno. Osim if naredbe, Java nam, kao i većina ostalih programskih jezika, nudi i naredbu switch . Opći oblik ove naredbe je:

switch (izraz) { case v_1: naredba_1; break ; case v_2: naredba_2; break ; ... case v_n: naredba_n; break ;

} Shematski prikaz switch naredbe je:

Slika 3 – 3 Shematski prikaz switch naredbe Pri čemu su:

− izraz – bilo koji izraz čija je vrijednost ordinalnog tipa (najčešće cjelobrojni ili znakovni tip)

− v_1, v_2,... v_n – vrijednosti odgovarajućeg tipa (isti kao izraz) − naredba_1, naredba_2,... naredba_n – naredba koja se izvršava ukoliko

vrijednost izraza odgovara odgovarajućoj vrijednosti.

naredba_1

v_1

naredba_2

v_2

naredba_n v_n

Da

Da

Da

Ne

Ne ...

uvjet

Page 44: Java i objektno orijentirano programiranje

44

Odnosno, ako je vrijednost izraza izraz jednaka v_1 izvršava se naredba_1 , ukoliko je vrijednost izraz jednaka v_2 izvršava se naredba_2 ,... Naredba break općenito služi za prekidanje nekog niza naredbi (najčešće izlazak iz petlje). Možda nije sasvim jasno koja je ovdje uloga naredbe break . Radi se o sljedećem. Ukoliko ne bismo stavili naredbu break nakon naredba_1 , te ako bi vrijednost izraza izraz bila jednaka v_1 , izvršila bi se naredba_1 , ali i sve naredbe iza nje, naredba_2 itd. Stoga koristimo naredbu break da bismo, nakon što se odgovarajuća naredba izvrši, izašli iz switch naredbe. Općenito ćemo switch naredbu koristiti kada imamo više od 2 uvjeta kod grananja. Korištenje switch naredbe uglavnom se može zamijeniti if naredbom Napomena: Primijetimo izraz kod switch naredbe uvijek dolazi unutar zagrada – (). "Tijelo" switch naredbe pišemo unutar vitičastih zagrada – {}. Prije nego započnemo rješavati sljedeći primjer reći ćemo par riječi o još jednom tipu podataka: String . O tipu podataka String detaljnije ćemo govoriti u nastavku. Na String ćemo u ovom trenutku gledati kao na složeni tip podataka, čije su vrijednosti riječi – niz od jednog ili više znakova. Vrijednosti tipa String se pišu unutar dvostrukih navodnika ("). Napomena: Primijetimo da se vrijednosti tipa String pišu unutar dvostrukih navodnika ("), za razliku od tipa char , gdje se vrijednosti pišu unutar jednostrukih navodnika ('). Deklaracija varijable tipa String identična je deklaracije bilo koje druge varijable nekog jednostavnog tipa (char , int ,...). Primjer 3 – 5: Napišimo metodu čiji će ulazni parametar biti jednoznamenkasti prirodan broj n. Metoda treba vraćati broj n ispisan riječima. Rješenje: Dani problem ćemo za usporedbu riješiti na dva načina: pomoću if i pomoću switch naredbe: //rješenje pomo ću if naredbe public static String broj1( int n) {

String s = ""; if (n == 0) s = "Nula"; else if (n == 1) s = "Jedan"; else if (n == 2) s = "Dva"; else if (n == 3) s = "Tri"; else if (n == 4)

Page 45: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

45

s = " Četiri"; else if (n == 5) s = "Pet"; else if (n == 6) s = "Šest"; else if (n == 7) s = "Sedam"; else if (n == 8) s = "Osam"; else if (n == 9) s = "Devet"; return s;

} //rješenje pomo ću switch naredbe public static String broj2 ( int n) {

String s = ""; switch (n) { case 0: s = "Nula"; break ; case 1: s = "Jedan"; break ; case 2: s = "Dva"; break ; case 3: s = "Tri"; break ; case 4: s = " Četiri"; break ; case 5: s = "Pet"; break ; case 6: s = "Šest"; break ;

case 7: s = "Sedam"; break ; case 8: s = "Osam"; break ; case 9: s = "Devet"; break ;

} return s;

}

Page 46: Java i objektno orijentirano programiranje

46

Zadaci za vježbu 1. Objasni if naredbu. 2. Što će pisati u varijabli n nakon sljedećeg dijela programa:

int k = 3, n; if (k < 0)

n = 3*k; else

n = k * k;

3. Što će pisati u varijabli n nakon izvršavanja sljedećeg dijela programa:

int k = 5, n; if (k < 0)

n = 2 * k + 3; else if (k >= 0 && k < 10)

n = - Math . abs (k * k - 5 * k - 7); else

n = k * k - k + 3;

4. Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vračati true ako je

broj paran, inače će vračati false.

ulaz izlaz 4 true

5. Napiši metodu čiji će ulazni parametar biti prirodni brojevi n i m. Metoda treba vraćati veći od

brojeva n i m.

ulaz izlaz 4 6

6

6. Za godinu ćemo reći da je prijestupna ako je djeljiva s 4 i nije djeljiva sa 100 ili je djeljiva s

400. Napiši metodu čiji će ulazni parametar biti godina n, a metoda će vračati odgovarajuću poruku ("Godina je prijestupna" odnosno "Godina nije prijestupna").

ulaz izlaz 2004 Godina je prijestupna

7. Napiši metodu čiji će ulazni parametri biti tri prirodna broja (a, b i c). Ukoliko učitani brojevi

zadovoljavaju nejednakost trokuta (zbroj bilo koja dva broja je manji od trećeg), metoda treba vraćati opseg trokuta čije su duljine stranica a, b i c, odnosno poruku "Uneseni brojevi ne mogu biti duljine stranica trokuta".

ulaz izlaz 3 4 5

6.0

Page 47: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

47

8. Napiši metodu čiji će ulazni parametri biti tri prirodna broja (a, b i c). Ukoliko stranice zadovoljavaju nejednakost trokuta, metoda treba ispisati je li trokut jednakostraničan, jednakokračan ili raznostraničan.

ulaz izlaz 4 3 3

Trokut je jednakokra čan

9. Napiši metodu koja će unositi datum roñenja neke osobe te današnji datum (datum se unosi

kao tri broja – dan, mjesec, godina). Metoda treba vračati točnu starost te osobe (u danima).

ulaz izlaz 6 1 1977 28 3 2005

10308

10. Što će pisati u varijabli n nakon izvršavanja sljedećeg dijela programa:

int n = 0, k = 4; switch (k) {

case 1: n = 5 * k; break ; case 2: n = 4 * k; break ; case 3: n = 3 * k; break ; case 4: n = 2 * k; break ; case 5: n = 1 * k; break ;

}

11. Napiši metodu čiji će ulazni parametri biti dva prirodna broja n i m te jednu od operacija +,

-, * ili /. Metoda treba vraćati prirodan broj koji se dobije primjenom operacije nad varijablama n i m.

ulaz izlaz 3 5 +

8

12. Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vračati ni , pri

čemu je i imaginarna jedinica za koju vrijedi: 12 −=i .

ulaz izlaz 5 i

Page 48: Java i objektno orijentirano programiranje

48

13. Napiši metodu čiji će ulazni parametri biti dvoznamenkasti prirodan broj n. Metoda treba vratiti broj n ispisan riječima.

ulaz izlaz 23 dvadeset tri

14. Napiši metodu koja će unositi datum u 21 stoljeću (dan, mjesec i godina) i ispisivati na koji

dan u tjednu dolazi taj datum. Napomena: Poznato je da je 1. siječnja 2001. bio ponedjeljak.

ulaz izlaz 30 3 2005

srijeda

Page 49: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

49

4

Petlje

� for petlja � while petlja � do/while petlja

Page 50: Java i objektno orijentirano programiranje

50

for petlja Petlje ćemo općenito koristiti kada neki dio programa, niz naredbi, trebamo ponoviti više puta. Općenito for petlju koristimo kada unaprijed znamo koliko puta trebamo izvršiti neki dio programa. U Javi for petlja ima nešto općenitiji oblik i možemo ju koristiti i u nekim slučajevima kada ne znamo unaprijed koliko puta trebamo izvršiti neki dio programa. Opći oblik for petlje je: for (kon_var = poc_vrij; uvjet; promj_kon_var)

naredba; ili dijagramom toka bi to izgledalo ovako:

Slika 4 – 1 Shematski prikaz for petlje

pri čemu je:

− kon_var – kontrolna varijabla; − uvjet – najčešće je oblika kon_var >(<, >=, <=, ==, !=) vrijednost

– uvjet izvršavanja for petlje; − promj_kon_var – promjena vrijednosti kontrolne varijable kon_var . Najčešće je

oblika kon_var++ odnosno kon_var--.

Izvršavanje for petlje:

− na samom početku se kontrolnoj varijabli (kon_var ) pridruži neka početna vrijednost (poc_vrij )

− ako je uvjet istinit: 1. izvršava se naredba 2. mijenja se vrijednost kontrolne varijable (promj_kon_var )

uvjet

naredba

Da

Ne

kon_var = poc_vrij

promj_kon_var

...

Page 51: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

51

3. vraćamo se na početak for petlje i provjeravamo uvjet Napomena: Ukoliko je naredba složena naredba trebamo ju pisati unutar {}. Trebamo biti jako oprezni prilikom promjene vrijednosti kontrolne varijable (prom_kon_var ), trebamo osigurati da nakon konačnog broja koraka kontrolna varijabla (kon_var ) poprimi takvu vrijednost koja više neće zadovoljavati uvjet . Ukoliko to ne osiguramo ući ćemo u beskonačnu petlju i morat ćemo program prekinuti nasilno. Primjer 4 – 1: Koliko će se puta izvršiti sljedeći dio programa: ... int n = 5, t = 0; for ( int i = 0; i <= n; i++) t++; ... Rješenje: - pri ulasku u for petlju varijabli i će se pridružiti vrijednost 0 (i = 0 ). Budući da je i (0) uistinu <= od n (5) izvršit će se naredba (t++ ) te će se vrijednost varijable i povećati za 1 (i++ ) i iznosit će 1; - budući da je i (2) <= n (5) izvršit će se naredba (t++ ) te će se vrijednost varijable i povećati za 1 (i++ ); - i (2) je i dalje manje ili jednako od n (5) – ponovo se izvršava naredba t++ te vrijednost varijable i postaje 3; - kako je i (3) <= n (5) izvršava se t++ , a i postaje 4; - i (4) <= n (5), dakle, izvršava se t++ te i poprima vrijednost 5; - i (5) <= n (5), izvršava se t++ , a i postaje 6; - budući da i (6) nije <= n (5) izlazimo iz for petlje i idemo na prvu sljedeću naredbu iza for petlje. Prebrojimo li koliko smo puta izvršili naredbu t++ , dobit ćemo traženi broj izvršavanja for petlje. U ovom slučaju je taj broj 6. Primjer 4 – 2: Napišimo metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vraćati ukupni broj djelitelja broja n. Rješenje: public static int pr42 ( int n) {

int t = 0; for ( int i = 1; i <= n; i++) if (n % i == 0) t++; return t;

} U oba prethodna primjera smo vrijednost kontrolne varijable povećavali za 1. U sljedećem ćemo primjeru vrijednost kontrolne varijable smanjivati za 1. Primjer 4 – 3:

Page 52: Java i objektno orijentirano programiranje

52

Napišimo metodu čiji će ulazni parametar biti dva prirodna broja n i m. Metoda treba vraćati najmanji zajednički višekratnik brojeva n i m. Rješenje: Prisjetimo se, najmanji zajednički višekratnik dvaju prirodnih brojeva (n i m) je najmanji prirodan broj koji se može podijeliti s n i s m. Sigurno je da je jedan od višekratnika brojeva n i m njihov umnožak (n * m), no možda postoji i manji višekratnik od njega. Stoga ćemo pomoću for petlje ići od broja n * m do nekog od brojeva n ili m (ili do 1), te ćemo vrijednost kontrolne varijable (i), kada bude djeljiva s n i s m zapisati u varijablu v. Kako u for petlji idemo od većeg broja prema manjem, na kraju će u varijabli v pisati najmanji broj koji se može podijeliti s n i s m. public static int pr43 ( int n, int m) {

int v = n * m; for (int i = n * m; i >= n; i--)

if (i % n == 0 && i % m == 0) v = i; return v;

} Do sada smo u svim primjerima imali po jednu for petlju. Često ćemo nailaziti na probleme gdje će unutar jedne petlje biti imati još jednu petlju, pa ćemo za takve petlje reći da su ugniježñene. Ilustrirajmo to na sljedećem primjeru: Primjer 4 – 4: Za prirodan broj n ćemo reći da je prost ako je djeljiv samo s 1 i sa samim sobom. Prvih nekoliko prostih brojeva su: 2, 3, 5, 7, 11, 13,... (broj 1 nije prost broj). Poznato je da prostih brojeva ima beskonačno mnogo, no ne postoji nikakva egzaktna formula koja će nam reći koji je npr. n-ti prosti broj ili koliko ima prostih brojeva koji su manji od prirodnog broja n. Napiši metodu čiji će ulazni parametar biti prirodan broj m, a vraćati će broj prostih brojeva koji su manji ili jednaki od m. Rješenje: Jedan od načina na koji možemo provjeriti je li neki broj prost je da mu prebrojimo sve djelitelje. Ukoliko broj ima samo 2 djelitelja, bit će prost. Ovom ćemo metodom za velike brojeve imati jako puno dijeljenja, što može znatno usporiti izvršavanje programa. Jedan od teorema iz matematike kaže da će broj biti prost ako nema niti jednog djelitelja izmeñu dva i korijena iz broja za koji provjeravamo je li prost. Npr. želimo li provjeriti je li broj 113 prost, nije nužno dijeliti ga sa svim brojevima izmeñu 1 i 113, već će biti dovoljno provjeriti postoji li djelitelj broja 113

izmeñu 2 i 11113 ≈ . U ovom primjeru ćemo očito morati proći po svim brojevima koji izmeñu 2 i m, te ćemo za svaki broj provjeravati je li prost i, u slučaju da je prost povećavati vrijednost neke varijable za 1. Dakle, očito ćemo imati ugniježñene petlje. Kontrolna varijabla (i) prve for petlje ići će po brojevima od 2 do m. Druga for petlja će za svaki takav broj (i) provjeriti je li prost i to će raditi

tako da prebroji koliko broj i ima djelitelja izmeñu 2 i i . public static int pr44 ( int n) {

int p = 0; for ( int i = 2; i <= n; i++) { int d = 0;

Page 53: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

53

for ( int j = 2; j <= Math . sqrt (i); j++) if (i % j == 0) d++; if (d == 0) p++; } return p;

} Rješenje prošlog primjera je ispravno. Meñutim kod takvog rješenja je dosta velika mogućnost pogreške: zamijenimo kontrolne varijable (i, j), zaboravimo inicijalizirati brojač na 0 (d),... Stoga ćemo u nastavku dati još jedno rješenje problema iz primjera 4 – 4. Ovo drugo rješenje temelji se na pisanju još jedne pomoćne metode. Pomoćna metoda, nazovimo ju prost, imat će jedan parametar, prirodan broj n te će vraćati true ako je broj n prost, inače će vraćati false. Metodu prost ćemo pozivati u svojoj metodi te ćemo na taj način izbjeći ulančane petlje. Općenito ćemo u metodi pozvati drugu metodu tako da joj napišemo ime i proslijedimo odgovarajuće parametre. public static boolean prost ( int n) {

int d = 0; for ( int i = 2; i <= Math . sqrt (n); i++) if (n % i == 0) d++; if (d == 0) return true ; else return false ;

} public static int pr44a ( int n) {

int p = 0; for ( int i = 2; i <= n; i++) { if (prost (i)) p++; } return p;

}

Primijetimo da smo u obje metode koristili i kao varijablu. Možda nije sasvim jasno kako se ne "pomiješaju" varijable i iz tih dviju metoda. Radi se o tome da je varijabla i lokalna varijabla i u jednoj i u drugoj metodi. Lokalnu varijablu jedne metode vidi samo ta metoda. Dakle, metoda pr44a uopće ne vidi varijablu i metode prost. Isto tako bi zbuniti mogao i parametar metode prost. Pri definiciji metode prost parametar je n, a u metodi pr44a metodu prost pozivamo s parametrom i. Pojednostavljeno objašnjenje ovoga je činjenica da je n tzv. formalni parametar metode prost. Prilikom poziva metode prost u varijabli i piše konkretan broj i taj broj se pri pozivu metode prost prepisuje u formalni parametar n, s kojim onda radi metoda prost.

Page 54: Java i objektno orijentirano programiranje

54

while petlja while petlju ćemo, slično kao i for petlju, koristiti u slučajevima kada dio programa trebamo izvršiti više puta. Za razliku od for petlje, koju koristimo uglavnom kada znamo koliko puta trebamo ponoviti neki niz naredbi, while petlju ćemo koristiti kada ne znamo unaprijed koliko puta trebamo izvršiti neki niz naredbi. Opći oblik while petlje je: while (uvjet)

naredba;

Slika 4 – 2: Shematski prikaz while petlje

Dok je uvjet istinit izvršavat će se naredba . Ukoliko je naredba složena naredba potrebno ju je staviti unutar {}. Slično kao i kod for petlje, unutar naredbe koja se nalazi u tijelu petlje trebamo osigurati da nakon konačnog broja koraka uvjet postane lažan. U suprotnom ćemo uči u beskonačnu petlju. Primjer 4 – 5: Što će pisati u varijabli s nakon izvršavanja sljedećeg dijela programa? ... int s = 0, i = 1, n = 4; while (s <= n) {

s += i; i++;

} ... Rješenje: Na početku programa očito varijabli s pridružujemo vrijednost 0, varijabli i pridružujemo 1, dok varijabli n pridružujemo vrijednost 4. - budući da je s (0) <= od n (4) – s se povećava za 1 te sada iznosi 1, te se i povećava za 1 i sada iznosi 2; - s obzirom da je s (1) <= n (4) – s se povećava za i (2) te sada poprima vrijednost 3, dok i postaje 3; - s (3) <= n (4) – dakle, s se povećava za i (3) i postaje 6, a i postaje 4;

uvjet

naredba

istinit

lažan

...

Page 55: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

55

- s (6) više nije manje ili jednako od n (4), što znači da izlazimo iz while petlje Dakle, nakon petlje će u varijabli s pisati vrijednost 6. Primjer 4 – 6: Napišimo metodu čiji će ulazni parametar biti dva prirodna broja n i m. Metoda treba računati mjeru brojeva n i m (mjera brojeva n i m je najveći prirodan broj koji dijeli broj n i broj m). Rješenje: Primjer ćemo riješiti modificiranom metodom Euklidovog algoritma za mjeru dvaju brojeva. Ovakav modificirani Euklidov algoritam glasi ovako: - ako su n i m jednaki, onda je njihova mjera jednaka bilo kojem od njih (jednaki su); - ukoliko brojevi n i m nisu jednaki, njihova mjera ista je kao mjera brojeva: - manji od brojeva n i m; - razlike većeg i manjeg od brojeva n i m; Npr. ako je n = 27 a m = 18 , Euklidov algoritam bi mogao ići ovako: - kako 27 i 18 nisu jednaki slijedi da je njihova mjera jednaka mjeri brojeva 18 (manji od brojeva 27 i 18) i 9 (razlika brojeva 27 i 18); - budući da 18 i 9 nisu jednaki, prema Euklidovom algoritmu je njihova mjera jednaka mjeri brojeva 9 (manji od brojeva 18 i 9) i 9 (razlika brojeva 18 i 9); - kako su brojevi 9 i 9 jednaki, dakle njihova mjera je 9, pa je onda i mjera brojeva 27 i 18 isto tako 9. Na osnovu izrečenog lako možemo zaključiti da dok brojevi ne postanu jednaki usporeñujemo ih te na mjesto većeg zapisujemo razliku većeg i manjeg broja, dok manji broj ostaje nepromijenjen: public static int pr46 ( int n, int m) {

while (n != m) if (n > m) n = n - m; else m = m - n; return n;

}

Slično kao što možemo imati ulančane for petlje, možemo imati i ugniježñene while petlje, pa čak i više, možemo ulančavati for petlju s while petljom i obrnuto. Primjer 4 – 7: Za prirodan broj n ćemo reći da je simetričan ako se jednako čita s obje strane (npr. 121, 56765,...). Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vraćati n-ti po redu simetrični broj. Rješenje: Prvih nekoliko simetričnih brojeva su: 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22,... Da bismo za neki broj provjerili je li simetričan trebamo ga okrenuti i provjeriti je li tako okrenut isti kao polazni broj. Broj k ćemo okrenuti tako da mu "skidamo" jednu po jednu znamenku i dodajemo na kraj drugog broja (m). Pod "skidanjem" znamenke podrazumijevamo da posljednju znamenku spremimo u privremenu varijablu z (z = k % 10 ), te broju k "prekrižimo" posljednju znamenku (k = k / 10 ). Znamenku z ćemo dodati na kraj broja m tako da broj m pomnožimo s 10 i dodamo z (m = m * 10 + z ). Znamenke broju k ćemo "skidati" sve dok k ne postane 0 (primijetimo da smo na taj način zauvijek izgubili početnu vrijednost broja k, stoga ju na samom početku trebamo pospremiti u neku pomoćnu varijablu t).

Page 56: Java i objektno orijentirano programiranje

56

Budući da u zadatku trebamo pronaći n-ti po redu simetrični broj, varijabli k ćemo pridruživati vrijednosti 1, 2, 3,... i svaki puta kada se u varijabli k bude nalazio broj koji je simetričan vrijednost brojača (b) ćemo povećati za 1. Stat ćemo kada vrijednost brojača b bude bila jednaka n, te ćemo vratiti broj koji u tom trenutku piše u k. public static int pr47 ( int n) {

int k = 0, b = 0, z, t, m; while (b < n) { k++; t = k; m = 0; //okre ćemo broj t while (t > 0) { z = t % 10; t /= 10; m = m * 10 + z; } if (m == k) b++; } return k;

}

Page 57: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

57

do/while petlja do/while petlja gotovo je identična while petlji o kojoj smo govorili u prethodnom poglavlju. Jedina razlika je što se kod while petlje uvjet provjerava na početku pa se naredba unutar while petlje ne mora izvršiti niti jednom (ako je uvjet odmah lažan), dok se kod do/while petlje uvjet provjerava na kraju pa se petlja, tj. naredba unutar petlje uvijek izvrši najmanje jednom. Opći oblik do/while petlje je: do

naredba; while (uvjet);

Slika 4 – 3: Shematski prikaz do/while petlje Primjer 4 – 8: Što će pisati u varijabli t nakon izvršavanja sljedećeg dijela programa: ... int t = 0, i = 5; do {

t++; i += 5;

} while (i < 12); ...

Rješenje: Na početku varijabli t pridružujemo vrijednost 0, dok varijabli i pridružujemo vrijednost 5. - ulaskom u do/while petlju vrijednost varijable t povećavamo za 1 (t++ ) i sada ona ima vrijednost 1, dok vrijednost varijable i povećavamo za 5 i sada ona iznosi 10. Budući da je i (10) < 12 vraćamo se na početak do/while petlje; - vrijednost varijable t povećavamo za 1 (t++ ) te ona sada iznosi 2, dok vrijednost varijable i povećavamo za 5 i ona sada iznosi 15. Budući da je i (15) veće od 12 izlazimo iz do/while petlje, dakle u varijabli t će pisati vrijednost 2. Primijetimo da bi u slučaju while petlje:

uvjet

naredba

istinit lažan ...

...

Page 58: Java i objektno orijentirano programiranje

58

... int t = 0, i = 5; while (i < 12) {

t++; i += 5;

} ... vrijednost varijable t nakon izvršavanja petlje bila 1. Na samom kraju dajmo još jedan primjer u kojem ćemo imati ugniježñene do/while i for petlju. Primjer 4 – 9: Štediša je tijekom posljednjih nekoliko godina u banku stavljao odreñene iznose. Prve godine je stavio iznos x. Svake sljedeće godine je stavio y kuna više nego prethodne godine. Na ulagane iznose nije dobivao nikakve kamate, a nakon n godina je raspolagao sa ukupno k kuna. Danas, dok o tome ponosno govori svojim prijateljima zanima ga koji je iznos u banku stavio prve godine i tu za njega započinju problemi. Napišimo metodu čiji će ulazni parametri biti: - prirodan broj y – razlika uloga izmeñu svake dvije godine; - prirodan broj n – broj godina koje je štediša stavljao novac u banku; - prirodan broj k – iznos u kunama s kojim štediša raspolaže. Metoda treba vraćati prirodan broj, a koji će predstavljati iznos x – koji je štediša uplatio prve godine. Rješenje: Prije nego započnemo rješavati ovaj problem, simulirajmo ovaj problem na jednom konkretnom primjeru. Pretpostavimo da je štediša prve godine u banku uložio 100 kuna (x), svake sljedeće je ulagao 100 kuna više (y), dakle, nakon 5 (n) godina u banci je imao 100 + 200 + 300 + 400 + 500 = 1500 (k) kuna. Uz elementarno znanje matematike mogli bismo doći do formule prema kojoj bismo iz poznatih podataka (y, n i k) lako izračunali nepoznati podatak (x). Iako bi to rješenje bilo nešto elegantnije, mi zadatak nećemo riješiti na taj način, već ćemo ga riješiti "pogañanjem" broja x. Budući da je traženi broj (x) prirodan broj, krenut ćemo od x = 1 i simulirati ulaganja. Ukoliko za dane y i n simulacijom dobijemo n, to će značiti da je 1 traženi broj. Inače ćemo povećavati broj x za 1 sve dok simulacijom iz brojeva x, y i n ne dobijemo broj k. public static int pr49 ( int y, int n, int k) {

int x = 0, s, p; do { x++; s = 0; p = x; //simuliramo rješenje problema, tj. //ra čunamo koliko bi štediša imao nakon n godina //ako je prve godine u banku stavio x kuna a svak e //sljede će godine je iznos pove ćavao za y for ( int i = 1; i <= n; i++) { s += p;

Page 59: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

59

p += y; } } while (s != k); return x;

}

Page 60: Java i objektno orijentirano programiranje

60

Zadaci za vježbu 1. Što je petlja? 2. U kojim ćemo slučajevima koristiti for petlju? 3. Objasni izvršavanje for petlje. 4. Što će pisati u varijabli n nakon izvršavanja sljedećeg dijela programa:

... int n = 1; for ( int i = 1; i <= 5; i++)

n *= i; ...

5. Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vračati true ako je n:

a. prost – za broj ćemo reći daje prost ako je djeljiv samo s 1 i sa samim sobom (npr. 2, 3, 5, 7,...);

ulaz izlaz 13 true

b. savršen – za broj ćemo reći da je savršen ako je jednak zbroju svojih djelitelja, ne

računajući njega samog (npr. 6, 28,...).

ulaz izlaz 7 false

inače metoda treba vračati false.

6. Napiši metodu čiji će ulazni parametri biti dva prirodna broja n i m. Metoda treba vračati

mjeru brojeva n i m. Mjera brojeva n i m je najveći zajednički djelitelj brojeva n i m.

ulaz izlaz 27 18

9

7. Napiši metodu čiji će ulazni parametri biti prva dva člana (a i b) te broj elemenata (n)

a. aritmetičkog niza b. geometrijskog niza metoda treba vračati zbroj prvih n elemenata danog niza. a.

ulaz izlaz 1 3 5

25

b.

ulaz izlaz 1 3 5

121

Page 61: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

61

8. Dan je pravokutnik površine p. Napišite metodu koja će vračati opseg pravokutnika čija je

površina p, a opseg najmanji moguć.

ulaz izlaz 30 22

9. Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vračati n-ti po

redu element Fibonaccijevog niza. Fibonaccijev niz je niz čiji su prva dva elementa jednaka 1, a svaki sljedeći element jednak je zbroju prethodna dva elementa Fibonacijevog niza. Prvih nekoliko elemenata Fibonacijevog niza su: 1, 1, 2, 3, 5, 8, 13, 21,...

ulaz izlaz 13 233

10. Pretpostavlja se da se svaki paran prirodan broj n može prikazati kao zbroj dvaju prostih

brojeva (broj je prost ako je djeljiv samo s 1 i sa samim sobom). Napiši metodu čiji će ulazni parametar biti paran prirodan broj n. Metoda treba vračati broj načina na koje se n može prikazati kao zbroj dvaju prostih brojeva.

ulaz izlaz 10 2

11. Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba vračati broj načina

na koje se prirodan broj n može zapisati kao zbroj kvadrata 5 različitih prirodnih brojeva ( )54321 ,,,, xxxxx za koje vrijedi 54321 xxxxx ≤≤≤≤ .

ulaz izlaz objašnjenje 2 3 ( ) ( )

( )211000

210001

200011

22222

22222

22222

=++++=++++−

=+++−+−

12. U kojim ćemo slučajevima koristiti while petlju? 13. Koja je razlika izmeñu for i while petlje? 14. Što će pisati u varijabli p nakon izvršavanja sljedećeg dijela programa:

... int n = 5, p = n; while (n > 1)

p *= n; ...

15. Napiši metodu čiji će ulazni parametri biti prirodni brojevi n i m. Metoda treba vraćati mjeru

brojeva n i m (najveći zajednički djelitelj). Mjeru treba računati Euklidovim algoritmom. Eulidov algoritam za traženje mjere dvaju prirodnih brojeba kaže sljedeće: ako su brojevi jednaki, ondaje mjera upravo taj broj, ukoliko brojevi nisu jednaki, mjera brojeva bit će jednaka mjeri sljedećih brojeva: raulici većeg i manjeg od brojeva i manjeg broja. Primjerice ako su zadani brojevi 24 i 18, budući da brojevi nisu jednaki, njihova je mjera jednaka mjeri brojeva 6 (24 - 18) i 18. Budući da brojevi i dalje nisu jednaki, mjera je jednaka mjeri brojeva 6 i 12 (18 - 6),...

Page 62: Java i objektno orijentirano programiranje

62

ulaz izlaz 18 24 6

16. Napiši metodu čiji će ulazni parametar biti prirodan broj n. Metoda treba:

a. zbrojiti sve znamenke broja n;

ulaz izlaz 581 14

b. ispisati najveću znamenku broja n.

ulaz izlaz 581 8

17. Napišite metodu čiji će ulazni parametar biti prirodan broj n:

a. broj zapisan u binarnom brojevnom sustavu. Metoda treba vraćati broj n zapisan u dekadskom brojevnom sustavu;

ulaz izlaz 1011 11

b. broj zapisan u dekadskom brojevnom sustavu. Metoda treba vraćati zapis broja n u

binarnom brojevnom sustavu

ulaz izlaz 12 1100

Page 63: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

63

5

Složeni tipovi podataka

� Niz � String

Page 64: Java i objektno orijentirano programiranje

64

Niz Često ćemo prilikom programiranja trebati u varijable spremati i nekoliko desetaka pa čak i stotina podataka. Deklarirati 100 varijabli i onda još njima uspješno manipulirati bilo bi poprilično komplicirano. U takvim slučajevima u pomoć nam stižu indeksirane varijable tzv. nizovi. Prisjetimo se matematike i npr. sustava linearnih jednadžbi. Ako imamo sustav od npr. 3 linearne jednadžbe s 3 nepoznanice, tada ćemo najčešće nepoznanice označavati s x, y i z. Meñutim imamo li sustav od 5 jednadžbi s 5 nepoznanica, nepoznanice ćemo najčešće označavati s x1, x2, x3, x4, i x5. Slično je i s nizovima kod programiranja. Jedina razlika je što elemente nizova nećemo označavati s: x1, x2, ..., xn nego s: x[1], x[2],...x[n].

x[1] x[2] ... x[n]

Slika 5 – 1: Niz //ovdje može npr. slika vlaka s vagonima na kojima piše x[1], x[2],..., x[n] Neke od prednosti korištenja su:

− unos/ispis elemenata moguć je pomoću jedne petlje; − ne deklariramo svaki element niza posebno, već ih deklariramo sve istovremeno; − lakše manipuliranje podacima (sortiranje, pretraživanje,...); − ...

U Javi je moguće kreirati niz bilo kojeg tipa podataka (int, char, String,...), poslije ćemo vidjeti da je moguće kreirati čak i niz objekata. Elementi niza u Javi počinju se indeksirati od 0. To znači da prvi element niza ima indeks 0, drugi 1,... Npr. ako je x niz od n elemenata, tada će elementi toga niza biti: x[0], x[1], x[2],..., x[n-1]. Niz ćemo u Javi deklarirati na jedan od sljedećih načina:

tip[] ime_niza ; ili

tip ime_niza[] ; Primjer 5 – 1: Deklarirajmo niz a čiji će elementi biti cijeli brojevi: Rješenje: Kao što smo rekli niz možemo deklarirati na dva načina: int [] a; odnosno: int a[]; Mi ćemo od sada pa na dalje niz uvijek deklarirati na prvi način: tip[] ime_niza;

Page 65: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

65

Prilikom deklaracije niza, kao i kod deklaracije ostalih jednostavnih tipova podataka, elementima niza možemo pridružiti inicijalne vrijednosti:

tip[] ime_niza = { vr_1, vr_2, ..., vr_n }; Primjer 5 – 2: Deklarirajmo niz c čiji će elementi biti znakovnog tipa, a inicijalno će vrijednosti elemenata niza biti samoglasnici: Rješenje: char [] c = {'a', 'e', 'i', 'o', 'u'}; Nakon ovakve deklaracije niza vrijednosti elemenata niza bit će redom: c [0] = 'a'; c [1] = 'e'; c [2] = 'i'; c [3] = 'o'; c [4] = 'u'; Ukoliko deklariramo neki niz i nakon deklaracije prvom elementu niza pokušamo pridružiti neku vrijednost: int [] a; a [0] = 2; te pokušamo kompajlirati taj dio koda, doći će do greške. Kompajler će javiti sljedeću grešku: variable a might not have been initialized

a[0] = 2; U čemu je problem? Izgleda sve korektno napisano. Da uistinu smo sve korektno napisali. Meñutim, ako nismo elementima niza inicijalno pridružili vrijednosti, tada prije pridruživanja vrijednosti nekom elementu niza trebamo još "rezervirati prostor" za taj niz, tj. trebamo alocirati memoriju. Memoriju za elemente nekog niza alocirat ćemo na sljedeći način:

ime_niza = new tip[ broj_elemenata ]; pri čemu je tip onaj isti tip podataka koji smo naveli kod deklaracije niza, dok je broj_elemenata maksimalni broj elemenata koje će niz sadržavati. Često se deklaracija niza spaja s alociranjem prostora za niz, pa u tom slučaju deklaracija niza ima oblik:

tip[] ime_niza = new tip[ broj_elemenata ];

Page 66: Java i objektno orijentirano programiranje

66

Primjer 5 – 3: Deklarirajmo znakovni niz od 20 elemenata te elementima niza pridružimo sva velika slova engleske abecede. Rješenje: ... char [] c; c = new char [26]; for ( int i = 65; i <= 90; i++)

c[i - 65] = ( char ) i; ...

Pokušamo li u prethodnom primjeru npr. 30-tom elementu niza pridružiti neku vrijednost, prilikom izvršavanja programa doći će do sljedeće greške: ArrayIndexOutOfBoundsException null

Ulazni parametar metode isto tako može biti i niz. U tom slučaju elemente niza pišemo unutar vitičastih zagrada - {}, meñusobno odvojene znakom zareza - , (isto kao kad inicijaliziramo elemente niza prilikom deklaracije niza). Broj elemenata nekog niza (za koje je alociran prostor) vratit će nam naredba:

ime_niza. length ; Primjer 5 – 4: Napišimo metodu čiji će ulazni parametri biti niz a te prirodni broj n, n manji od broja elemenata niza. Metoda treba sortirati niz a te vratiti element niza a čiji je indeks n. Rješenje: Niz ćemo sortirati najjednostavnijom metodom razmjene koju ovdje nećemo specijalno objašnjavati. Princip sortiranja niza metodom razmjene je sljedeći: - općenito i-ti element niza (i ide od prvog do pretposljednjeg elementa niza) usporeñujemo sa svim elementima iza njega. Ukoliko naiñemo na element, s indeksom j, koji je manji od i-tog elementa i-tom i j-tom elementu niza zamjenjujemo vrijednosti. public static int pr54 ( int [] a, int n) {

int tmp; for ( int i = 0; i < a. length - 1; i++) for ( int j = i + 1; j < a. length ; j++) if (a [i] > a [j]) { tmp = a [i]; a [i] = a [j]; a [j] = tmp; } return a[n];

}

Page 67: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

67

Višedimenzionalni nizovi Nizovi s kojima smo se upoznali u prethodnom poglavlju imaju jedan indeks te ih stoga zovemo jednodimenzionalni nizovi. Osim takvih jednodimenzionalnih nizova u praksi se vrlo često koriste i višedimenzionalni, najčešće dvodimenzionalni nizovi. Dvodimenzionalni nizovi će imati dva indeksa i zvat ćemo ih matrice. Princip korištenja matrica analogan je principu korištenja jednodimenzionalnih nizova. Elementi matrice će imati dva indeksa, te će opći oblik elementa matrice biti:

ime_niza [i][j]; Deklaracija matrice biti će sljedećeg oblika:

tip[][] ime_niza; odnosno, deklaracija s inicijalizacijom: tip[][] ime_niza = {{vr_11, vr_12,..., vr1m},...,{vr_n1,.. .,vr_nm}}

odnosno, deklaracija s alokacijom memorije:

tip[][] ime_niza = new tip [broj_el1][broj_el2] Na matricu možemo gledati kao na tablicu od broj_el1 redaka i broj_el2 stupaca.

ime_niza[0][0] ime_niza[0][1] ... ime_niza[0][broj_el2]

ime_niza[1][0] ime_niza[1][1] ... ime_niza[1][broj_el2]

... ... ... ...

ime_niza[broj_el1][0] ime_niza[broj_el1][1] ... ime_niza[broj_el1][broj_el2] Slika 5 – 2: Matrica

Dimenzija matrice je broj redaka i stupaca te matrice. Općenito ćemo dimenziju matrice koja ima n redaka i m stupaca označavati s mn × . Primjer 5 – 5: Napiši metodu čiji će ulazni parametar biti dimenzija matrice (n i m) te prirodan broj k <= n*m. Metoda treba popuniti matricu prirodnim brojevima do n * m i to tako da redom popunjava elemente matrice počevši od gornjeg lijevog kuta do donjeg desnog kuta matrice. Npr. ako je unesena dimenzija matrice 34× , tada metoda treba kreirati sljedeću matricu: 1 2 3 4 5 6 7 8 9 10 11 12 Nadalje metoda treba vratiti zbroj svih susjeda broja k u matrici. Npr. susjedi broja 8 su: 4, 5, 6, 7, 9, 10, 11 i 12, pa je onda njihov zbroj jednak 64. Rješenje:

Page 68: Java i objektno orijentirano programiranje

68

//metoda kreira traženu matricu dimenzije nxm public static int [][] matrica ( int n, int m) {

int k = 1; int [][] a = new int [n][m]; for ( int i = 0; i < n; i++) for ( int j = 0; j < m; j++) { a[i][j] = k; k++; } return a;

} public static int pr55( int n, int m, int t) {

int [][] a = matrica (n, m); int x = 0, y = 0, s = 0; //tražimo poziciju broja t for ( int i = 0; i < n; i++) for ( int j = 0; j < m; j++) if (a[i][j] == t) { x = i; y = j; } if (x > 0) { if (y > 0) s += a [x - 1][y - 1] + a [x][y - 1]; s += a [x - 1][y]; if (y < m - 1) s += a [x - 1][y + 1] + a [x][y + 1]; } if (x < n - 1) { if (y > 0) s += a [x + 1][y - 1]; s += a [x + 1][y]; if (y < m - 1) s += a [x + 1][y + 1]; } return s;

} Primjer 5 – 6: Svima nam je dobro poznata igra križić-kružić. Napiši metodu čiji će ulazni parametar biti matrica koja predstavlja jednu odigranu igru križić-kružić i ispisivati pobjednika (križić ili kružić) odnosno da nema pobjednika ako u odigranoj igri nema pobjednika. Npr. kombinaciju: x o x o x x x o o ćemo unijeti kao: {{'x', 'o', 'x'},{'o', 'x', 'x'},{'x', 'o', 'o'}} i pobjednik je očito x. Rješenje: //metoda koja na osnovu u čitane matrice vra ća true ako je c pobjednik

Page 69: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

69

public static boolean pobjednik ( char [][] a, char c) {

//provjeravamo postoji li redak sastavljen samo od znakova c for ( int i = 0; i < 3; i++) if (a[i][0] == c && a[i][1] == c && a[i][2] == c) return true ; //provjeravamo postoji li stupac sastavljen samo od znakova c for ( int i = 0; i < 3; i++) if (a[0][i] == c && a[1][i] == c && a[2][i] == c) return true ; //postoji li dijagonala sastavljena samo od znakova c //glavna dijagonala if (a[0][0] == c && a[1][1] == c && a[2][2] == c) return true ; //sporedna dijagonala if (a[0][2] == c && a[1][1] == c && a[2][0] == c) return true ; return p;

} public static String pr56 ( char [][] a) {

if (pobjednik (a, 'x') && pobjednik (a, 'o')) return "Neriješeno"; else if (pobjednik (a, 'x'))

return "Pobjednik je x"; else if (pobjednik (a, 'o')) return "Pobjednik o"; else return "Nema pobjednika";

}

Page 70: Java i objektno orijentirano programiranje

70

String O tipu podataka String smo već nešto govorili u prethodnim poglavljima. Ovdje ćemo nastojati kroz nekoliko jednostavnih primjera u potpunosti usvojiti tip podataka String , ukazati na mjesta na kojima ćemo ga koristiti, prednosti korištenja ovog tipa podataka, a s druge strane ćemo dati uvod u sljedeće poglavlje u kojem će biti riječi o klasama. Za razliku od jednostavnog tipa podataka char , koji može sadržavati samo jedan znak, koji se u tom slučaju navodi unutar jednostrukih navodnika ('), tip podataka String može sadržavati više znakova, tj. u tip podataka String ćemo pohranjivati riječi pa čak i čitave rečenice, a takve riječi odnosno rečenice ćemo u tom slučaju navoditi unutar dvostrukih navodnika ("). Za razliku od svih tipova podataka koje smo do sada naučili, nad kojima smo mogli izvršavati neke jednostavnije operacije (najčešće matematičke), tip podataka String je jedan znatno složeniji tip podataka sa mnoštvom radnji koje možemo nad njim izvršavati. Takve složene tipove podataka nad kojima su definirane mnoge radnje općenito ćemo zvati klase. Dakle tip podataka String je u stvari jedna klasa u Javi. O klasama još nismo do sada govorili, o njima ćemo više govoriti u sljedećem poglavlju. Dok još ne znamo puno o klasama, klase možemo zamišljati kao složene tipove podataka. Nad takvim složenim tipovima podataka moči ćemo izvršavati odreñene radnje, tzv. metode. Neke od "radnji" koje bi mogli izvršavati nad riječima (stringovima) bile bi:

- prebrojati broj znakova u riječi; - provjeriti koji se znak nalazi na nekom mjestu u riječi; - ...

Pa upravo su za takve nad stringovima definirane metode. No vratimo se na početak. Varijablu u koju ćemo moći spremati riječi, odnosno varijablu tipa String deklarirat ćemo na sljedeći način:

String ime_varijable; odnosno, deklaracija s inicijalizacijom:

String ime_varijable = "vrijednost"; Najčešće radnje (metode) koje ćemo izvršavati nad tipom podataka String su: int length () – vraća broj znakova u stringu boolean equals (String s) – usporeñuje dva stringa i vraća true ako su jednaka, inače vraća false int indexOf (String s) – vraća poziciju prvog pojavljivanja stringa s u stringu u kojem se nalazimo int lastIndexOf (String s) – vraća poziciju zadnjeg pojavljivanja stringa s u stringu u kojem se nalazimo void replaceAll (String s1, String s2) – svako pojavljivanje stringa s1 u stringu u kojem se nalazimo zamjenjuje sa stringom s2 String substring (int poc, int kraj) – vraća dio stringa od znaka s rednim brojem pos do znaka s rednim brojem kraj stringa u kojem se nalazimo String toUpperCase () – sva mala slova stringa zamjenjuje s odgovarajućim velikim slovima, ostala slova ostavlja nepromijenjenim String toLowerCase () – sva velika slova stringa zamjenjuje s odgovarajućim malim slovima, ostala slova ostavlja nepromijenjenim

Page 71: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

71

Ilustrirajmo sve rečeno na nekoliko jednostavnih primjera: Primjer 5 – 7: Napišimo metodu čiji će ulazni parametar biti ime i prezime neke osobe (ime i prezime su jedan string i meñusobno su odvojeni točno jednim razmakom), a vraćati će inicijale te osobe (prvo slovo imena i prvo slovo prezimena). Rješenje: public static String pr57 (String ime) {

/*uzima prvo slovo imena, dodaje mu to čku i razmak te sve to sprema u string s */ String s = ime. substring (0, 1) + ". "; //traži razmak u stringu int n = ime. indexOf (" "); /*na kraju stringa s dodaje prvi znak nakon razmaka te na kraju još jednu to čku */ s = s + ime. substring (n + 1, n + 2) + "."; return s;

}

Napomena: Kod pokretanja metoda čiji su ulazni parametri stringovi, stringove trebamo navesti unutar dvostrukih navodnika. Primjer 5 – 8: Napišimo metodu čiji će ulazni parametar biti jedna riječ. Metoda treba rastaviti riječ na slogove (u ovom slučaju ćemo riječ rastavljati na slogove tako da iza svakog samoglasnika stavimo znak -, osim u slučaju kada je zadnji znak samoglasnik, u tom slučaju iza njega nećemo stavljati znak -). Rješenje: public static String pr58 (String rijec) {

String s = ""; for ( int i = 0; i < rijec. length () - 1; i++) { String z = rijec. substring (i, i + 1); s = s + z; z = z. toUpperCase (); if (z. equals ("A") || z. equals ("E") || z. equals ("I") ||

(z. equals ("O")) || (z. equals ("U"))) s = s + "-"; } s = s + rijec. substring (rijec. length () - 1, rijec. length ()); return s;

}

Page 72: Java i objektno orijentirano programiranje

72

Zadaci za vježbu 1. Koja je uloga nizova u programiranju? 2. Deklariraj niz x čiji će elemnti biti realni brojevi. 3. Napiši metodu čiji će ulazni parametar biti niz. Metoda treba vratiti najveći element unesenog

niza.

ulaz izlaz {12, 4, 5, 1, 9, 6} 1

4. Napiši metodu čiji će ulazni parametri biti niz a – koeficijenti polinoma n-tog stupnja

12210)( −+++= n

n xaxaxaaxp K , te prirodan broj 0x . Metoda treba vraćati vrijednost

polinoma u točki 0x , tj. 10

2020100 )( −+++= n

n xaxaxaaxp K .

ulaz izlaz objašnjenje {-1, -2, 3, 2} 3

74 Radi se o polinomu: 32 2321)( xxxxp ++−−= i očito je

743233321)3( 32 =⋅+⋅+⋅−−=p 5. Ivica se sa svojim društvom želi igrati lovice, no prije samog početka igre potrebno je odrediti

tko će loviti. Ivica je kao najstariji zadužen odrediti tko će loviti. Ivičin način odreñivanja onoga tko će loviti je sljedeći: svi igrači, njih n, poslože se u krug, i to tako da svaki igrač ima svoj broj i iza svakog broja dolazi njegov sljedebenik (iza n je 1). Potom netko kaže jedan prirodan broj m i Ivica počinje izbacivati igrače iz kruga. Lovi onaj koji posljednji ostane u krugu. Postupak izbacivanja je sljedeći: Ivica započne odbrojavanje od igrača s brojem 1 i odbrojava m igrača. m-ti igrač ispada iz igre, nakon toga nastavlja brojati od (m+1)-vog igrača.... Napišite metodu čiji će ulazni parametri biti prirodni brojevi n i m, a metoda će vratiti redni broj igrača koji će loviti.

ulaz izlaz objašnjenje 10 7 9 Igrači ispadaju sljedećim redom: 7, 4, 2, 1, 3, 6, 10, 5, 8

6. Napišite metodu čiji če ulazni parametar biti matrica. Metoda treba računati zbroj svih

pozitivnih elemenata unesene matrice.

ulaz izlaz {{-4, 7},{2, -2}} 9

7. Napišite metodu čiji će ulazni parametar biti kvadratna matrica (ima isti broj redaka i stupaca)

metoda treba vraćati: a. zbroj elemenata na glavnoj dijagonali – glavnu dijagonalu čine elementi kojima je

oznaka stupca jednaka oznaki retka;

ulaz izlaz {{4, 7, 5},{3, 2, 3},{6, 5, 1}} 7

b. umnožak elemenata na sporednoj dijagonali – elementi sporedne dijagonale kvadratne

matrice koja ima n redaka i n stupaca su: 0,12,11,0 ,,, −−− nnn aaa K .

Page 73: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

73

ulaz izlaz {{4, 7, 5},{3, 2, 3},{6, 5, 1}} 60

8. Navedi neke od metoda definirane nad stringovima. 9. Što će pisati u varijabli n nakon izvršavanja sljedećeg dijela programa: ... String s = "Programski jezik Java" int n = s.indexOf (" "); ...

10. Napiši metodu čiji će ulazni parametar biti riječ. Metoda treba vraćati broj znakova u

unesenoj riječi.

ulaz izlaz Stringovi u Javi su lagani 26

11. Napiši metodu čiji je ulazni parametar biti jedna riječ. Metoda treba vratiti novu riječ koja se

iz ulazne dobiva tako da se iza svakog slova ulazne riječi doda razmak.

ulaz izlaz Java J a v a

12. Napiši metodu čiji će ulazni parametar biti jedna riječ. Metoda treba vraćati true ako je riječ

palindrom, inače treba vraćati false. Za riječ ćemo reći da je palindrom ako se jednako čita s lijeva na desno i s desna na lijevo (npr. kisik, oko,...).

ulaz izlaz kapak true

13. Napiši metodu čiji će ulazni parametar biti rečenica (niz riječi odvojenih jednim ili više

razmaka). Metoda treba vraćati broj riječi u rečenici.

ulaz izlaz Ova recenica ima pet rijeci 5

14. Tekst je moguće kompresirati tako da uzastopno pojavljivnaje nekog znaka zamijenimo

znakom i brojem koji predstavlja broj uzastopnih pojavljivanja toga znaka (uvijek će se raditi o jednoznamenkastom broju). Napiši metodu koja će:

a. unositi kompresirani i vraćati odgovarajući nekompresirani tekst; ulaz izlaz A1C2d4 ACCdddd

b. unositi nekompresirani i vraćati odgovarajući kompresirani tekst. ulaz izlaz ACCdddd A1C2d4

Page 74: Java i objektno orijentirano programiranje

74

15. Jedan od načina šifriranja teksta je da sve znakove ciklički pomaknemo za nekoliko znakova. Napišite metodu čiji će ulazni parametar biti tekst (samo velika slova engleske abecede) i pomak, a vraćat će tekst koji dobijemo šifriranjem ulaznog teksta uz zadnai pomak. Napomena: Niti jedan znak šifriranog teksta ne smije izaći izvan velikih slova engleske abecede. Znakovi se ciklički ponavljaju, nakon Z dolazi ponovo A.

ulaz izlaz ZASTO 2

BCUVQ

16. Ponekad se umjesto nekih naših slova (LJ,NJ,Ć,Č,Š,Ž,ð,DŽ) pišu zamjenski znakovi, i to

prema sljedećoj tablici:

Znak LJ NJ Ć Č Š Ž ð DŽ Zamjena LJ NJ C- C= S= Z= D- DZ=

Napišite metodu čiji će ulazni marametar biti riječ zapisana zamjenskim znakovima a vraćati

će broj stvarnih slova u toj riječi.

ulaz izlaz LJULJAC=KA 7

17. Težinu znaka u riječi možemo definirati kao broj pojavljivanja toga znaka u toj riječi. Težinu riječi definirati ćemo kao zbroj težina svih znakova od kojih se riječ sastoji. Napišite metodu čiji će ulazni parametar biti jedna riječ (sastoji se samo od velikih slova engleske abecede). Metoda treba vraćati težinu ulazne riječi.

ulaz izlaz MASA 6

18. Napišite metodu čiji će ulazni parametar biti string koji se može sastojati od slova, znamenaka

i specijalnih znakova. Metoda treba vratiti najmanji cijeli broj koji se nalazi u tom stringu (treba uzimati u obzir i predznake).

ulaz izlaz a-123b42cc3 -123

19. Napiši metodu čiji će ulazni parametri biti dva velika prirodna broja (mogu imati do 200

znamenaka) metoda treba vratiti zbroj unesenih brojeva.

ulaz izlaz 1234567891234567891 2

1234567891234567893

Page 75: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

75

6

Objektno orijentirano programiranje

� Drugačiji pristup programiranju � Klasa i objekt � Kreiranje objekta iz klase � Nasljeñivanje klasa

Page 76: Java i objektno orijentirano programiranje

76

Drugačiji pristup programiranju O važnosti i brzini razvoja informatičke tehnologije te potrebe za informatikom, besmisleno je uopće raspravljati. Da bi informatičari, ponajviše programeri mogli držati korak sa zahtjevnim potrebama tržišta, bilo je potrebno zamijeniti neke starije tradicionalne pristupe programiranju. Osnovna ideja, ovakvog novog programerskog pristupa je: što je više moguće koristiti već napisani kôd u svojim programima. Kao što je poznato većina današnjih aplikacija ima gumbe, izbornike,... svaki puta iz početka pisati sav kod za rad s takvim elementima programskog sučelja, uistinu može biti naporno. Dakle, ideja je da ili koristimo kôd za takve elemente koji je već netko definirao ili smo ga mi sami definirali, a onda mi samo mijenjamo npr. tekst na gumbu, veličinu gumba, akciju koja će se dogoditi klikom na gumb,... Ovakav pristup nam omogućava da nakon što jednom napišemo npr. funkciju koja će provjeravati je li broj prost, više nikada ne moramo tu funkciju pisati, čak ju nećemo morati niti kopirati u svoje nove programe, već ćemo ju "zapakirati" i samo pozivati u svojim programima. Ovakav pristup programiranju je osobito prigodan za ispravljanje grešaka ili bilo kakve izmjene. Npr. ako smo primijetili da naša funkcija koja provjerava je li broj prost ne radi dobro, nećemo morati mijenjati kod svih programa u kojima smo koristili tu funkciju, jer smo ju tamo samo pozivali. Dovoljno će biti samo promijeniti definiciju te funkcije na jednom mjestu i automatski će ona ispravno raditi i u svim ostalim programima. Slično je i s gumbima, ukoliko u jednom trenutku doñu u modu okrugli gumbi a ne više pravokutni kao što su danas, neće biti potrebno mijenjati sve programe koje u sebi imaju pravokutne gumbe već ćemo jednostavno izmijeniti gotovi kod koji smo koristili za kreiranje gumba i automatski će svi gumbi u svim programima, u kojima smo pozivali taj kod biti okrugli. Ovakav pristup programiranju znatno je olakšao rad velikim programerskim kućama. Naime, većina današnjih programa kreirana je od nezavisnih dijelova koda koji se pozivaju u "glavnom programu". Ukoliko se ustanovi greška u programu, ona se ispravlja u točno odreñenoj komponenti koda. Ispravljena komponenta koda pošalje se korisniku, koji staru komponentu zamijeni novom i program radi ispravno. Upravo gore opisani način programiranja osnova je objektno-orijentiranog programiranja.

Page 77: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

77

Klasa i objekt Motiv za objektno-orijentirano programiranje naveli smo u prošlom naslovu, sama ideja objektno-orijentiranog programiranja potekla je iz našeg, realnog svijeta. Okrenemo se oko sebe vidjet ćemo neke objekte, npr. automobile, avione, zgrade, kuće, motocikle, televizore,... Prilikom programiranja nerijetko ćemo u svojim programima koristiti upravo njih ili neke druge imaginarne objekte, kao što su trokut, krug, jednadžba, broj,... Kažemo li npr. automobil, avion ili trokut, mislimo na čitavu klasu automobila, aviona ili trokuta, tj. mislimo na sve automobile, avione ili trokute. Meñutim kažemo li npr. crveni A3, izbor će biti već malo smanjen, znat ćemo da su to samo crveni automobili marke Audi tip A3. Znamo li npr. još i registarsku oznaku znat ćemo točno koji je to automobil, a ako radimo u policiji, znat ćemo sve i o vlasniku automobila, jačinu motora, godinu proizvodnje,... Nakon što znamo sve te detalje, više ne govorimo o čitavoj klasi automobila već o konkretnom automobilu tj. o objektu automobil. Upravo tako je i u programiranju. Klasa će biti svojevrstan predložak za objekt, ona sadrži općenita svojstva. Nakon što neku klasu detaljno opišemo ona postaje objekt odnosno instanca. Instanca je samo drugi naziv za objekt. Dakle objekt odnosno instanca su konkretizacija klase. Takva konkretizacija klase, tj. definiranje osnovnih svojstava klase nazivamo kreiranje (instanciranje) objekta. Primjer 6 – 1: Neka osnovna svojstva automobila bila bi: marka, tip, snaga, maksimalna brzina, snaga, boja, broj šasije, registracijska oznaka. Ukoliko ne znamo sva navedena svojstva ili bar većinu njih, govorimo o klasi automobil. Meñutim ako kažemo to je Mazda, 121, snaga je 38 kw, maksimalna brzina je 180 km/h plave je boje, klasu smo uvelike smanjili. Znamo li još i broj šasije ili registracijsku oznaku znat ćemo točno o kojem se automobilu na ulici radi i tada govorimo o tom automobilu kao objektu. Osnovna svojstva trokuta bila bi duljine stranica i mjere kutova. Kažemo li trokut mislim na bilo koji trokut koji postoji i u tom slučaju je trokut klasa. Meñutim, kažemo li trokut čije su duljine stranica 3, 4 i 5 cm, znamo točno o kojem se trokutu radi i znamo sve o njemu te govorimo o objektu trokut čije su stranice 3, 4 i 5 cm. Do sada smo rekli da klase općenito imaju neka svojstva. Kod automobila su to bili marka, tip,... Osim svojstava, nad klasama je moguće izvršavati odreñene radnje. Neke radnje kod automobila bi bile: upali motor, ubaci u prvu brzinu dodaj gas, pritisni spojku,... Slično je i u programiranju, što znači da će klase moći imati neka svojstva i neke radnje koje će se nad klasama moći izvršavati tzv. metode. Svojstva će u stvari biti neke globalne varijable, dok će metode biti funkcije (metode) definirane unutar neke klase. Općenito ćemo svojstva i metode zvati elementima klase. Općenito je cilj klase da njenim svojstvima i metodama možemo pristupati iz drugih klasa. Npr. definiramo li klasu koja će izmeñu ostalih sadržavati metodu koja će provjeravati je li neki broj prost, tada bismo htjeli toj metodi pristupati iz drugih klasa. Općenito, da bismo svojstvu ili metodi neke klase mogli pristupati iz druge klase, one trebaju biti deklarirane public (javne). Osim public, klasa može imati i elemente (svojstva ili metode) koje će biti samo pomoćne za definiciju public metoda i ne trebaju se moći pozivati u drugim klasama. Za takve ćemo metode reći da su private. Npr. u klasi u kojoj se nalazi metoda koja provjerava je li neki broj prost, može postojati metoda koja će brojati koliko neki broj ima djelitelja, ta metoda može biti pomoćna za metodu koja provjerava je li neki broj prost, no nju ne moramo moći pozivati iz drugih klasa, stoga ona može biti private metoda.

Page 78: Java i objektno orijentirano programiranje

78

Sljedeći važan pojam kada govorimo o klasama je konstruktor klase. Konstruktor klase je metoda unutar klase, koja ima isto ime kao klasa a ne vraća nikakav tip. Konstruktor se izvršava prilikom kreiranja objekta. On ne vraća nikakvu vrijednost, a namjena mu je inicijaliziranje svojstava objekta, tj. postavljanje svojstava na neku početnu vrijednost. Jedna klasa može imati jedan ili više konstruktora. Već smo rekli da konstruktor ima isto ima kao klasa. Sama po sebi se nameću pitanje, koja je namjena više konstruktora? Kako je moguće da dvije ili više metoda imaju isto ime? Kako će klasa znati koju metodu treba izvršiti? U stvari se radi o tome da ako klasa ima dva ista konstruktora, onda oni moraju imati različiti broj parametara. Već smo rekli da je namjena konstruktora inicijalizacija svojstava objekta. Mi objekt možemo kreirati bez da znamo vrijednosti svih svojstava, u tom slučaju će se svojstva postaviti na neke inicijalne vrijednosti. U tom slučaju ćemo vrijednosti svojstava definirati kada ih saznamo. Npr. ako imamo klasu auto, nije nužno da prilikom kreiranja objekta tipa auto znamo sva njegova svojstva. U tom slučaju ćemo svojstva inicijalizirati na neke početne vrijednosti, npr. za maksimalna brzina će biti 100 km/h ako drugačije nije rečeno,... Ukoliko prilikom kreiranja objekta znamo vrijednosti svih svojstava klase, možemo kreirati objekt s tim svojstvima. Upravo je to namjena više konstruktora. U prvom slučaju ćemo pozvati konstruktor bez parametara, koji će svojstva inicijalizirati na neku početnu vrijednost, najčešće 0 ako se radi o numeričkim vrijednostima odnosno prazan string ako se radi o tekstualnim vrijednostima, to definira sam programer klase. U drugom slučaju ćemo pozvati konstruktor sa parametrima, koji će vrijednosti svojstava postaviti na vrijednosti koje smo proslijedili preko parametara. Općenito je slučaj da klasa može imati dvije ili više metode koje se jednako zovu. U tom slučaju one moraju imati različiti broj parametara ili parametri moraju biti različitog tipa, a za takve metode kažemo da su preopterećene (overloadane) metode. Nakon što smo se upoznali s pojmom klase i svim važnijim pojmovima koji dolaze s klasom, vrijeme je da naučimo kako kreirati klasu. Klasu u Javi ćemo općenito kreirati na sljedeći način:

public class ime_klase { svojstva_i_metode; }

Primjer 6 – 2: Definirajmo klasu Trokut, čija će svojstva biti duljine stranica trokuta (a, b i c) a metode će biti Opseg() i Povrsina() koje će vraćati opseg i površinu trokuta. Rješenje: Ovdje ćemo očito imati tri svojstva (duljine stranica a, b i c), koja će biti public svojstva jer im trebamo moći pristupiti iz drugih klasa. Nadalje ćemo imati dvije isto tako public metode Opseg () i Povrsina () za računanje opsega i površine trokuta. Osim toga imat ćemo jednu private metodu Poluopseg () koja će vraćati poluopseg trokuta, a koja nam je potrebna za računanje

površine trokuta Heronovom formulom: ( ) ( ) ( )csbsassP −⋅−⋅−⋅= , pri čemu je s poluopseg:

(2

cba ++). Ovdje je logično imati najmanje dva konstruktora:

prvi konstruktor bez parametara, koji će vrijednosti parametara a, b i c postaviti na 0. Drugi konstruktor će imati tri parametra i inicijalizirati svojstva a, b i c na vrijednosti parametara. Ovdje

Page 79: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

79

čak ima smisla staviti i konstruktor koji će imati jedan parametar a odnosit će se na jednakostranične trokute i on će vrijednosti parametara a, b i c postaviti na vrijednost proslijeñenog parametra. Konstruktor s dva parametra nema previše smisla, on bi se odnosio na jednakokračne trokute, no on nije spretan jer bi moglo doći do zbrke koji je parametar duljina osnovice jednakokračnog trokuta a koji duljina kraka trokuta. public class Trokut { public int a, b, c; public Trokut () { a = 0; b = 0; c = 0; } public Trokut( int x, int y, int z) { a = x; b = y; c = z; } public Trokut ( int x) { a = x; b = x; c = x; } private double Poluopseg () { return ( double )(a + b + c) / 2; } public double Povrsina () { double s = Poluopseg (); return Math . sqrt (s * (s - a) * (s - b) * (s - c)); } public int Opseg () { return a + b + c; } }

Primijetimo da smo kod metode Poluopseg () pisali return ( double ) (a + b + c) / 2 . Da nismo pisali (double) poluopseg ne bi bio točan. Naime, kako su a, b i c cijeli brojevi rezultat bi bio cijeli broj pa bi npr. poluopseg trokuta s duljinama stranica 3, 3 i 3 bio 4 a ne 4.5. Stoga smo najprije zbroj pretvorili u double pa smo tek onda dijeliti i u tom slučaju će poluopseg biti double. Napomena: Da smo zaglavlje drugog konstruktora: public Trokut( int x, int y, int z)

pisali kao public Trokut( int a, int b, int c)

Page 80: Java i objektno orijentirano programiranje

80

došlo bi do problema jer se svojstva klase i parametri metode zovu jednako. U tim slučajevima bi definicija ove metode trebala imati oblik: public Trokut( int a, int b, int c) { this .a = a; this .b = b; this .c = c; }

this u ovom slučaju znači da je u nastavku navedeno svojstvo ili metoda klase. Dakle, interpretacija ovoga bi bila svojstvu a klase u kojoj se nalazim (Trokut) pridruži vrijednost parametra a i tu ne bi bilo nikakvih problema. this možemo pisati općenito ispred elemenata klase, no ako nemamo ovakvog miješanja parametara metoda s elemenata klase, to nije potrebno.

Page 81: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

81

Kreiranje objekta iz klase Kao što smo već rekli, osnovna namjena klase je koristiti je u drugim klasama, odnosno svojim programima. Nakon što smo naučili kreirati vlastitu klasu, vrijeme je da pokažemo kako tu klasu pozivati u drugim klasama, te kako pozivati definirati njena svojstva i pozivati njene metode. Na klasu možemo gledati kao na jedan novi tip podataka, koji će imati neke vrijednosti i nad kojim ćemo moći izvršavati neke operacije (pozivati metode). Kao i svaki drugi tip podataka, klasu trebamo deklarirati. Opći oblik deklaracije objekta čiji će tip biti neka klasa je:

ime_klase ime_objekta;

Na ovaj način smo u stvari samo najavili da ćemo koristiti objekt ime_objekta, koji će biti tipa ime_klase. Taj objekt još zapravo ne postoji. S takvim objektom ne možemo još ništa raditi. Da bismo mogli nešto raditi nad tim objektom (npr. izvršavati metode koje smo definirali u pripadnoj klasi) moramo ga instancirati, tj. zaista ga stvoriti. Objekt ćemo instancirati na sljedeći način:

ime_objekta = new ime_klase ([parametri]);

Prisjetimo se, kada smo govorili o klasama, rekli smo da klasa može imati jedan ili više konstruktora i to smo nazivali preopterećenje konstruktora, preopterećeni konstruktori su se razlikovali po broju parametara, odnosnu tipu parametara. Prilikom instanciranja klase, mi u stvari izvršavamo odreñeni konstruktor i to onaj čiji broj i tip parametara odgovaraju broju i tipu parametara koje smo naveli prilikom instanciranja klase. Često ćemo posljednje dvije naredbe ujediniti te ćemo istovremeno deklarirati i kreirati objekt. To ćemo napraviti sljedećom naredbom:

ime_klase ime_objekta = new ime_klase ([parametri]);

Primjer 6 – 3: Kolike će biti duljine stranica trokuta nakon sljedećih naredbi: a) Trokut t = new Trokut (); b) Trokut t = new Trokut (3, 4, 5); c) Trokut t = new Trokut (2); ako je Trokut klasa koju smo kreirali u primjeru 4 – 2. Rješenje: Očito smo u svakom od primjera kreiranjem objekta t koji je tipa Trokut pozivali drugi konstruktor klase Trokut. Stoga će duljine stranica biti: a) a = 0, b = 0, c = 0; u ovom slučaju se izvršava prvi konstruktor (bez parametara), koji duljine stranica postavlja na 0.

Page 82: Java i objektno orijentirano programiranje

82

b) a = 3, b = 4, c = 5; izvršava se drugi konstruktor (s tri parametra), prvi proslijeñeni parametar bit će duljina stranice a, drugi duljina stranice b, dok će treći proslijeñeni parametar biti duljina stranice c. c) a = 2, b = 2, c = 2; izvršava se treći konstruktor, koji će duljine svih stranica postaviti na jedinu proslijeñenu vrijednost, koja je u ovom slučaju 2. Pristup elementima klase Upravo smo naučili kako kreirati objekt iz neke klase. Što ćemo sada s tim objektom? Već prije smo prije rekli da svaka klasa ima svoja svojstva i metode tj. neke radnje koje se nad njom mogu izvršavati. Pa jedino što ćemo mi raditi s objektima je mijenjati im svojstva i izvršavati radnje nad njima (pozivati metode). To znači da npr. kada smo jednom definirali klasu Trokut, čija su svojstva duljine stranica trokuta a metode računaju opseg i površinu, tada više nikada nećemo morati u svojim programima pisati formulu za računanje površine trokuta. Jednostavno ćemo kreirati objekt iz klase Trokut, postaviti mu duljine stranica i jednostavno pozivati metodu Povrsina (), koja nam vraća površinu tog trokuta. Dakle, slobodno možemo zaboraviti na Heronovu formulu Ukoliko ikada itko zaključi da Heronova formula za računanje površine trokuta nije točna i pojavi se neka nova formula za računanje površine trokuta (što nije vjerojatno), jednostavno ćemo izmijeniti svoju metodu Povrsina () u klasi Trokut i svi programi će automatski računati površinu trokuta prema novoj formuli. Sada kada smo uvidjeli smisao objekta, postavlja se pitanje kako pristupiti elementima objekta (svojstvima i metodama)? pa pristupat ćemo im prema sljedećem principu:

ime_objekta.element;

Primjer 6 – 4: Kreirajmo objekt t koji će biti instanca klase Trokut koju smo kreirali u primjeru 4 – 2, pri čemu će duljine stranica biti postavljene na 3, 4 i 5, a zatim u varijablu p spremimo površinu tog trokuta. Rješenje: Najprije kreirajmo objekt t, koji će biti instanca klase Trokut i čije će duljine stranica biti 3, 4 i 5. Prvi način na koji možemo ovo riješiti je da duljine stranica proslijedimo konstruktoru odmah prilikom kreiranja objekta:

Trokut t = new Trokut (3, 4, 5);

Isto ovo mogli smo napraviti tako da kreiramo objekt t iz klase Trokut, ali ovaj puta bez parametara. U tom će slučaju vrijednosti svojstava a, b i c biti postavljene na 0, a zatim postavimo vrijednosti svojstava na vrijednosti 3, 4 i 5, što bi izgledalo ovako:

Trokut t = new Trokut (); t.a = 3; t.b = 4;

t.c = 5; U prvom će se slučaju prilikom kreiranja objekta t izvršavati drugi konstruktor, dok će se u drugom slučaju izvršavati prvi konstruktor. Nakon što smo kreirali objekt tipa Trokut, trebamo još u varijablu p spremiti površinu tog trokuta. To ćemo napraviti pozivanjem metode Povrsina () nad objektom t, na sljedeći način:

double p = t.Povrsina ();

Page 83: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

83

Napišemo li npr.: Trokut t = new Trokut (3, 4, 5);

U memoriji će se alocirati prostor za objekt Trokut te će se vrijednosti svojstava (stranice a, b i c postaviti na vrijednosti 3, 4 i 5) a u varijablu t će biti pohranjena adresa objekta u memoriji.

Općenito nad objektima nije moguće izvršavati standardne operacije npr. +, -, ==,... Razmislimo li malo, to uistinu ima smisla. Što bi značilo t + j ako su t i j dvije instance klase Trokut? Što bi značilo zbrojiti dva trokuta? Operator pridruživanja (=) nad objektima je moguće pozivati, samo on ne radi uvijek ono što bismo možda očekivali. Pretpostavimo da smo kreirali dvije instance klase Trokut, t i j. Kao na sljedećoj slici:

Izvršavanjem izraza: t = j , dogodit će se sljedeće:

To znači da smo samo promijenili referencu i sada t i j pokazuju na isti objekt. Izvršavanjem izraza: t.a = 4 svojstvo a (duljina stranice a) objekta j će takoñer imati vrijednost 4.

t

3

4

5

a

b

c

varijabla objekt

t

3

4

5

a

b

c

8

8

8

a

b

c

j

3

4

5

a

b

c

8

8

8

a

b

c

t j

Page 84: Java i objektno orijentirano programiranje

84

Nasljeñivanje klasa Nasljeñivanje je vrlo čest pojam u objektno orijentiranom programiranju. Kao i kod samog objektno orijentiranog programiranja, osnovna ideja nasljeñivanja je izbjeći višestruko pisanje istih dijelova koda. Ideja je vrlo jednostavna: imamo jednu osnovnu klasu s osnovnim svojstvima i metodama koje ju opisuju, a onda po potrebi kreiramo nove klase koje ju "nadopunjuju" s nekim dodatnim svojstvima i metodama. Za takve klase koje "nadopunjuju" osnovnu klasu reći ćemo da ju nasljeñuju. Ilustrirajmo nasljeñivanje na jednom jednostavnom primjeru: pretpostavimo da želimo organizirati svoju kolekciju DVD-a i želimo napraviti program koji će nam to omogućiti. Očito ćemo imati dvije vrste DVD-a: s filmovima i s glazbom. Dakle kreirat ćemo dvije klase s pripadnim svojstvima i metodama:

Page 85: Java i objektno orijentirano programiranje

Glazba

naslov

velicina

komentar

izvodac SVOJSTVA

brojPjesama

dodajNaslov ()

vratiNaslov ()

dodajKomentar ()

vratiKomentar ()

vratiVelicinu ()

dodajIzvodaca ()

vratiIzvodaca ()

dodajBrojPjesama ()

METODE

vratiBrojPjesama ()

Kao što možemo primijetiti, neka svojstva i metode se nalaze u obje klase i stoga i moramo ih dva puta definirati. Problem možemo riješiti tako da elemente koji se pojavljuju u obje klase definiramo u jednoj posebnoj klasi DVD:

DVD

naslov

velicina

SVOJSTVA

komentar

dodajNaslov ()

vratiNaslov ()

dodajKomentar ()

vratiKomentar () METODE

vratiVelicinu ()

Sad kada imamo definiranu klasu DVD, možemo kreirati klase Film i Glazba koje nasljeñuju klasu DVD. Nasljeñivanjem klase DVD klase Film i Glazba automatski nasljeñuju i sva svojstva i metode klase DVD. Dakle sva ta svojstva i metode ne trebamo još jednom definirati. Općenito pretpostavimo da imamo neku klasu A, koja ima svoja svojstva i metode. Klasu A može naslijediti klasa B, koja će u tom slučaju imati sva svojstva i metode kao i klasa A, ali može imati i još neka svoja dodatna svojstva i metode. U tom slučaju je A nadklasa klase B, dok ćemo za B reći da je podklasa od A.

Film

naslov

velicina

komentar

trajanje SVOJSTVA

reziser

dodajNaslov ()

vratiNaslov ()

dodajKomentar ()

vratiKomentar ()

vratiVelicinu ()

dodajTrajanje ()

vratiTrajanje ()

dodajRezisera ()

METODE

vratiRezisera ()

Page 86: Java i objektno orijentirano programiranje

86

Kreiranjem instance klase B moći ćemo pozivati sve koje smo definirali u klasi B, ali i one definirane u klasi A, dok ćemo kreiranjem instance klase A moći pozivati samo elemente klase A. Podklasa tako takoñer može biti nadklasa nekoj drugoj klasi i na taj način je moguće izgraditi hijerarhiju klasa.

Klasu B koja će naslijediti klasu A kreirat ćemo na sljedeći način: class B extends A { definicija_klase; {

Kod ovakve hijerarhije može se dogoditi da je metoda s istim imenom kreirana u dvije klase koje su na različitoj razini u hijerarhiji. Npr. pretpostavimo da je u klasi A definirana metoda test () i metoda s istim imenom je definirana i u klasi B, koja nasljeñuje klasu A.

Kako klasa B nasljeñuje klasu A ona nasljeñuje i njenu metodu test (), a isto tako ona ima i svoju metodu test (). Kreiramo instancu klase B te pozovemo metodu test (), nije sasvim jasno koja metoda test () će se izvršiti. U ovakvim slučajevima izvršit će se metoda test () koja je definirana u klasi B i to se zove prekoračenje (override) metoda. Općenito smo mogli imati klasu C, koja nasljeñuje klasu B (klasa C nema metodu test ()). Pozivanjem metode test () nad instancom klase C izvršit će se metoda test () iz klase B. Dakle, pravilo je takvo da se izvršava metoda iz prve nadklase.

klasa B ... public int test() { ... } ...

klasa A ... public int test() { ... } ...

klasa C

klasa B

klasa A

Page 87: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

87

Primjer 6 – 5: Kreirajmo klasu Cetverokut, čija će svojstva biti duljine stranica (a, b, c, d) četverokuta, dok će jedina metoda biti Opseg (), koja će vraćati opseg četverokuta. Nadalje kreirajmo klasu Pravokutnik koja nasljeñuje klasu Cetverokut te ima još metode Povrsina (), koja računa površinu pravokutnika i Dijagonala (), koja vraća duljinu dijagonale pravokutnika. Rješenje: public class Cetverokut { public int a, b, c, d; public Cetverokut() { a = b = c = d = 0; } public Cetverokut ( int a, int b, int c, int d) { this .a = a; this .b = b; this .c = c; this .d = d; } public int Opseg () { return a + b + c + d; } } public class Pravokutnik extends Cetverokut { public Pravokutnik () { a = b = c = d = 0; } public Pravokutnik ( int a, int b) { this .a = a; this .b = b; this .c = a; this .d = b; } public int Povrsina () { return a * b; } public double Dijagonala () { return Math.sqrt (a * a + b * b); } }

Page 88: Java i objektno orijentirano programiranje

88

Napomena: Svaka klasa može nasljeñivati samo jednu klasu, tj. klasa može imati samo jednu nadklasu. S druge strane neku klasu može nasljeñivati bilo koja klasa, tj. klasa može biti podklasa.

Page 89: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

89

Zadaci za vježbu 1. Objasni razliku izmeñu klase i objekta. 2. Navedi nekoliko primjera klasa iz stvarnog života, navedite nekoliko njihovih svojstava i

metoda te objasnite što bi bio pripadni objekt. 3. Što su po strukturi metode, a što svojstva? 4. Što je konstruktor klase? 5. Što znači preopterečenje (overloadanje) metoda? 6. Definriaj klasu krug, čije će svojstvo biti polumjer kruga (r), osim toga imat će seljedeće

metode: � public double povrsina () – koja će vračati površinu kruga; � public double oseg () – koja će vračati opseg kruga.

Potom napiši novu klasu u kojoj ćeš kreirati instancu klase krug i pozivati njene metode. 7. Definiraj klasu osoba čija će svojstva biti ime, prezime i starost osobe. Nad klasom treba

definirati i sljedeće metode: � public String ispis () – vraća ime i prezime osobe; � public String inicijali () – vraća inicijale osobe; � public boolean stariji (osoba o) – vraća true ako je trenutna

osoba starija od osobe o, inače vraća false; Potom napiši novu klasu u kojoj ćeš kreirati instancu osoba krug i pozivati njene metode.

8. Definiraj klasu razlomak čija će svojstva biti brojnik i nazivnik nekog razlomka, osim tpoga imat će i sljedeće metode:

� public razlomak krati () – krati razlomak; � public razlomak zbroj (razlomak r) – vraća zbroj trenutnog

razlomka i proslijeñenog; � public razlomak razlika (razlomak r) – vraća razliku

trenutnog razlomka i proslijeñenog; � public razlomak umnozak (razlomak r) – vraća umožak

trenutnog razlomka s proslijeñenim; � public razlomak kvocijent (razlomak r) – vraća kvocijent

trenutnog razlomka s proslijeñenim; � public String ispis () – vraća zapis razlomka kao String (npr. 3/4).

Potom napiši novu klasu u kojoj ćeš kreirati instancu klase razlomak i pozivati njene metode. 9. Objasni pojam nasljeñivanje klasa. 10. Navedi nekoliko primjera nasljeñivanja klasa iz svakodnevnog života. 11. Definiraj klasu trokut čija će svojstva biti duljine stranica trokuta (a, b, c) a imat će i dvije

metode: � public double opseg () – vraća opseg trokuta � public double povrsina () – vraća površinu trokuta

Nadalje definiraj klasu jednakokracan koja nasljeñuje klasu trokut, ima još jedan dodatni konstruktor (koji ima samo jedan parametar) te ima još metodu:

� public double visina () – vraća visinu jednakostraničnog trokuta Potom napiši novu klasu u kojoj ćeš kreirati instance klasa trokut i jednakokracan i pozivati njihove metode.

Page 90: Java i objektno orijentirano programiranje

90

7

Programi u Javi

� Klasa i program � Metoda main � Izvršavanje Java programa iz komandnog

prompta

Page 91: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

91

Klasa i program Sve što smo do sada radili svodilo se je na pisanje metoda, koje smo pozivali iz sučelja BlueJ razvojnog okruženja. Pomoću tog okruženja smo mogli metodi proslijediti parametre i na kraju vidjeti što metoda vraća. Nadalje smo naučili kako kreirati čitave klase. Iz tih klasa smo kreirali objekte i nad njima izvršavali metode, ali sve na razini metoda koje smo izvršavali iz BlueJ razvojnog okruženja. Cilj programiranja je napraviti program koji će se moći samostalno izvršavati na računalu korisnika. Konkretno, htjeli bismo napisati program koji će se moći izvršavati izvan BlueJ razvojnog okruženja. Program u Javi je isto tako jedna klasa. Da bi neka klasa postala program treba imati još jednu metodu koju nazivamo main . Dakle, da bi neka klasa bila program koji ćemo moči izvršavati neovisno o BlueJ razvojnom okruženju, ta klasa treba imati metodu main . Kada želimo pokrenuti program napisan u Javi prvo se traži metoda main i izvršava se. Ukoliko želimo pokrenuti klasu koja nema metodu main , doći će do pogreške i klasa se naravno neće pokrenuti. Za one koji su programirali u Pascalu, main je u stvari ekvivalent glavnom programu u Pascalu. U Pascalu smo isto tako mogli definirati svoje funkcije i procedure (metode), koje smo pozivali u glavnom programu. Pokretanjem programa se je u stvari izvršavao glavni program. Da nismo imali glavnom programa, isto tako bi došlo do greške.

Page 92: Java i objektno orijentirano programiranje

92

Metoda main Već smo rekli da će neka klasa biti program ako izmeñu ostalih ima metodu main . Opći oblik definicije metode main je:

public static void main (String[] s) { definicija_metode; }

Ova metoda je izuzetno važna stoga ćemo ju detaljno objasniti. Osobito je bitno zaglavlje metode (prvi red), stoga ćemo objasniti značenje jedne po jedne riječi unutar konteksta metode main . Riječ s kojom započinje definicija metode main je public . O njoj smo već govorili. Prisjetimo se: public općenito znači da je neki element klase javan i može mu se pristupiti i iz drugih klasa. Osim što može biti public , elementi klase mogu biti još i private i protected . Ukoliko je neki element private , tada tom elementu ne možemo pristupiti izvan klase u kojoj se taj element nalazi. Negdje izmeñu public i private elemenata su protected elementi. Ako je neki objekt protected , tada takvom elementu možemo pristupiti u klasi koja nasljeñuje dotičnu klasu, ali ne i u ostalim klasama. U kontekstu metode main , bitno je da je ona public iz razloga što nju pokrećemo prvu prilikom pokretanja klase. Nju pokreće Java Virtual Machine. Sljedeća riječ u nizu je static . Da je neka metoda static znači da ju je moguće pozivati na razini klase. Prisjetimo se, kada smo htjeli pozvati metodu Povrsina () klase Trokut, morali smo kreirati instancu klase Trokut i nad tom instancom pozvati metodu Povrsina (). Trokut t = new Trokut (a, b, c); double p = t.Povrsina ();

a nismo mogli pisati double p = Trokut.Povrsina ();

s druge strane imamo klasu Math i npr. metodu sqrt () koja je definirana nad tom klasom. Želimo li računati drugi korijen nekog broja, ne moramo kreirati instancu klase Math i nad njom pozivati metodu sqrt (), već metodu sqrt () pozivamo na razini klase Math. double x = Math.sqrt (7);

U prvom slučaju metoda Povrsina () nije bila static i stoga smo ju morali pozivati na razini objekta koji je bio tipa Trokut. U drugom slučaju je metoda sqrt () static metoda i ona se može pozivati na razini klase. void znači da metoda ništa ne vraća. Na kraju metode koja je tipa void nije potrebno pisati return . main je ime metode.

Page 93: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

93

String [] s se odnosi na parametre metode. Metoda main kao parametre ima niz stringova. Primjer 7 – 1: Napišimo program koji će zbrajati dva prirodna broja i ispisivati njihov zbroj. Rješenje: Budući da trebamo napisati program koji će zbrajati dva prirodna broja, napisat ćemo klasu koja će morati sadržavati metodu main . Brojeve ćemo unijeti kao parametre metode main . public class Zbroj { public static void main ( String [] s) { int a = Integer . parseInt (s[0]); int b = Integer . parseInt (s[1]); System . out . println ( a + b ); } } U s obzirom da su parametri metode main stringovi, trebamo ih pretvoriti u cijele brojeve i to smo napravili naredbom Integer . parseInt (). Rezultat smo ispisali naredbom System.out.println (). Nakon što smo definirali klasu zbroj te ju uspješno kompajlirali, preostaje nam još pokrenuti program. Program ćemo u BlueJ razvojnom okruženju pokrenuti pozivanjem metode main .

Nakon pozivanja metode main otvorit će nam se okvir gdje ćemo unijeti parametre koje prosljeñujemo metoda main . Budući da je parametar niz stringova, brojeve koje želimo zbrojiti zapisat ćemo unutar vitičastih zagrada, unutar navodnika, meñusobno odvojene zarezom:

Klikom na gumb OK izvršit će se program i rješenje će biti ispisano u posebnom okviru:

Page 94: Java i objektno orijentirano programiranje

94

Page 95: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

95

Izvršavanje Java programa iz komandnog prompta U prošlom primjeru smo napravili program, meñutim ponovo smo ga pozvali iz BlueJ razvojnog okruženja. Na samom početku ovog poglavlja rekli smo da nam je cilj pisati programe koji će se moći izvršavati neovisno o BlueJ razvojnom okruženju. U nastavku ćemo pokazati kako napisani program pokrenuti neovisno o BlueJ okruženju. Prethodni program je bio primjer jednog programa pisan za operativni sustav DOS, tzv. konzolni program. Da bismo pokrenuli ovaj program pokrenut ćemo DOS-ov komandni ekran. To možemo napraviti tako da kliknemo na Start pa na Run, gdje upišemo cmd te kliknemo na gumb OK:

Otvorit će nam se prozor u kojem zadajemo naredbe upisivanjem. Premjestit ćemo se u mapu u kojoj se nalazi klasa Zbroj, koju smo kreirati u primjeru 5 – 1. te ćemo upisati: java Zbroj 2 3. Pritiskom na tipku enter na ekranu će se pojaviti 5 (zbroj brojeva 2 i 3).

Primijetimo da smo program pokretali naredbom: java Zbroj 2 3. Java ovdje znači da pozivamo Javin interpreter, zbroj je ime klase (dokument s nastavkom class Zbroj.class) dok su 2 i 3 parametri koje prosljeñujemo programu odnosno metodi main . Napomena: Da bismo mogli pokrenuti program iz komandnog prompta, on mora biti kompajliran tj. mora postojati dokument s nastavkom .class. Program kompajliramo u BlueJ-u.

Page 96: Java i objektno orijentirano programiranje

96

Zadaci za vježbu 1. Što mora imati neka klasa da bismo ju mogli izvršavati kao program? 2. Zašto metoda main mora biti public i static? 3. Neke od klasa koje si kreirao u proćlim poglavljima pretvori u programe te ih izvrši. 4. Definiraj komandnu aplikaciju, koja će se moći pokretati iz komandnog prompta a aplikacija

treba unositi prirodan broj n i : a. ispisivati kvadrate svih prirodnih brojeva do n; b. zbrajati sve prirodne brojeve do n; c. ispisivati rastav broja n na proste faktore.

Page 97: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

97

8

Elementi grafičkog korisničkog sučelja

� O grafičkom korisničkom sučelju � Prozor i njegovi dijelovi � Okviri za tekst i gumbi

Page 98: Java i objektno orijentirano programiranje

98

O grafičkom korisničkom sučelju Posljednji program koji smo napisali pokretali smo iz komandne linije operativnog sustava DOS. Parametre smo programu prosljeñivali tako da smo ih napisali neposredno iza imena programa. Današnji programi se najčešće ne pokreću iz komandne linije, a način komunikacije čovjeka s programom je pomoću mnoštva različitih elemenata (gumbi, okviri za tekst, padajuće liste, izbornici,...).

U ovom poglavlju ćemo naučiti kako kreirati program koji će s korisnikom komunicirati preko grafičkog korisničkog sučelja. Osnovni element svakog takvog programa bit će prozor. Na njega ćemo doslovno lijepiti različite elemente, kao što su: okviri za tekst, gumbi, izbornici, labele, gumbi za odabir,... Svaki od tih elemenata, pa i sam prozor su u stvari klase. I pojedini element ćemo dodavati tako da napravimo instancu odgovarajuće klase te mu definiramo neka svojstva. Kao što znamo, na neke radnje unutar takvog korisničkog sučelja se dogañaju neke akcije. Npr. klikom na gumb 7 u programu kalkulator će se na displayu kalkulatora pojaviti broj 7. Općenito se takva reakcija zove dogañaj i svaki dogañaj unutar programa treba isprogramirati. Točno trebamo reći koji će biti odgovor na neku radnju.

Page 99: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

99

Prozor i njegovi dijelovi Već smo rekli da su prozor i općenito svi elementi grafičkog korisničkog sučelja u stvari klase. Te klase nisu inicijalno uključene u Javi, već ih moramo posebno pozvati. Klase za definiranje elemenata grafičkog korisničkog sučelja smještene su u paketu koji se naziva javax.swing. Općenito ćemo paket u klasu uključiti naredbom:

import ime_paketa.*;

Dakle, paket koji sadrži klase za generiranje elemenata grafičkog korisničkog sučelja pozvat ćemo naredbom: import javax.swing.*;

znak * na kraju znači da uključujemo sve pakete koji se nalaze u paketu javax.swing. Klasa koja će u Javi kreirati prozor je JFrame . Kao i svaka druga klasa i ova ima svoja svojstva i metode. Sama po sebi se nameće potreba da prozoru definiramo veličinu (širinu i visinu), naslov,... Pa upravo su te metode i definirane nad klasom JFrame . Klasa JFrame ima dva konstruktora: JFrame () – kreira prozor bez ikakvih elemenata JFrame (String s) – kreira prozor u čijoj će naslovnoj traci biti pisati string koji smo proslijedili kao parametar. Najčešće metode koje ćemo mi koristiti nad prozorom su: public void setSize (int s, int v) – definira širinu i visinu prozora public void setTitle (String s) – definira naslov prozora public void setVisible (boolean b) – postavlja prozor u programu. Ukoliko je vrijednost varijable b postavljena na true, prozor će biti vidljiv. public void setDefaultCloseOperation (int n) – definira akciju koja se dogaña klikom

na gumb close ( ). Mi ćemo uvijek kao parametar ove metode pisati svojstvo EXIT_ON_CLOSE klase JFrame. public Container getContentPane () – vraća središnji dio prozora (Container), na koji ćemo dodavati elemente grafičkog korisničkog sučelja (gumbe,...). Primjer 8 – 1: Napišimo program koji će na ekranu crtati prozor u čijoj će naslovnoj traci pisati "Jedan običan prozor", dok će mu širina biti 400 a visina 300 piksela. Rješenje: Budući da trebamo napisati program koji će crtati prozor na ekranu, u konstruktoru ćemo napraviti prozor, definirati mu sve elemente i postaviti ga vidljivim, a onda ćemo u metodi main kreirati instancu klasu koja će (zbog definicije konstruktora) iscrtati prozor na ekranu. import javax.swing.*; public class Prozor

Page 100: Java i objektno orijentirano programiranje

100

{ private JFrame p = new JFrame (); public Prozor() { p. setTitle ("Jedan obi čan prozor"); p. setSize (400, 300); p. setDefaultCloseOperation (p. EXIT_ON_CLOSE); p. setVisible ( true ); } public static void main ( String[] s) { Prozor pr = new Prozor (); } }

Pokretanjem metode main na ekranu će se pojaviti prozor kao na slici:

Prozor isto tako možemo kreirati i tako da kreiramo klasu koja nasljeñuje klasu JFrame . U tom slučaju nećemo morati kreirati instancu klase JFrame , što će nam omogućiti direktno pozivanje svojstava i metoda klase JFrame . U tom slučaju će rješenje prošlog primjera imati sljedeći oblik: import javax.swing.*; public class Prozor extends JFrame { public Prozor() { setTitle ("Jedan obi čan prozor"); setSize (400, 300); setDefaultCloseOperation ( EXIT_ON_CLOSE); setVisible ( true ); } public static void main ( String[] s) { Prozor pr = new Prozor (); } }

Mi ćemo u daljnjim primjerima uglavnom kreirati prozore nasljeñivanjem klase JFrame .

Page 101: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

101

Okviri za tekst i gumbi U prošlom primjeru smo naučili kako kreirati jedan običan prozor. Nadalje ćemo prozorima dodavati dodatne komponente. Već smo rekli da su elementi grafičkog korisničkog sučelja u stvari klase. Okviri za tekst Okvir za tekst kreiramo klasom JTextField . Instancu klase JTextField najčešće ćemo kreirati koristeći konstruktor bez parametara, a sva potrebna svojstva definirat ćemo koristeći metode. Neke od najčešće korištenih metoda u za rad s okvirom za tekst su: public void setSize (int s, int v) – definira veličinu okvira za tekst public void setLocation (int x, int y) – definira mjesto, unutar Containera, na kojem će se nalaziti okvir za tekst (koordinate gornjeg lijevog vrha okvira za tekst) public void setText (String s) – postavlja tekst u okvir za tekst public String getText () – vraća tekst koji je upisan u okvir za tekst public void setEditable (boolean b) – ukoliko je b postavljen na true tekst unutar okvira za tekst će se moči mijenjati. Ukoliko je b postavljen na false sadržaj okvira za tekst neće biti moguće mijenjati. Gornja klasa omogućavala nam je kreiranje okvira za unos teksta. Osim što se može unositi tekst se isto tako može i ispisivati na prozoru. Na prozoru ćemo tekst ispisivati unutar posebnih elemenata grafičkog korisničkog sučelja, tzv. labela. Klasa koja će nam kreirati takve labele je JLabel. Instancu klase JLabel ćemo isto tako najčešće kreirati gez konstruktora. Neke od metoda ove klase su: public void setSize (int s, int v) – definira veličinu labele public void setLocation (int x, int y) – definira mjesto, unutar Containera, na kojem će se nalaziti labela (koordinate gornjeg lijevog vrha okvira za tekst) public void setText (String s) – postavlja tekst u labelu Gumbi Gumb ćemo kreirati klasom JButton . Slično kao i kod okvira za tekst, instancu klase JButton ćemo uglavnom kreirati koristeći konstruktor bez parametara, a dodatna svojstva ćemo definirati pomoću metoda. Metode koje ćemo najčešće koristiti s gumbima su: public void setSize (int s, int v) – definira veličinu gumba public void setLocation (int x, int y) – definira mjesto, unutar Containera, na kojem će se nalaziti gumb (koordinate gornjeg lijevog vrha gumba) public void setText (String s) – postavlja tekst na gumb public void setEnabled (boolean b) – ukoliko je vrijednost varijable b true gumb će biti aktivan, inače gumb neće biti aktivan.

Page 102: Java i objektno orijentirano programiranje

102

Elemente kao što su gumbi ili okviri za tekst ne možemo dodavati direktno na prozor koji smo kreirali u prethodnom primjeru. Komponente ćemo dodavati na jedan poseban dio prozora koji nazivamo Container. Container je opet jedna posebna klasa. Slično kao i klasa JFrame , i ova klasa se nalazi u jednom posebnom paketu: java.awt . Slično kao i kod paketa javax.swing , ovaj paket ćemo učitavati naredbom: import java.awt.*;

Instanci klase Container ćemo pridružiti središnji dio prozora metodom getContentPane () .

Prije nego što počnemo dodavati elemente na Container moramo definirati izgled Containera. Izgled Containera ćemo definirati metodom setLayout (LayoutManager m) koja je definirana u klasi Container. Ovdje se nećemo upuštati u objašnjavanje LayoutManagera . U osnovi se radi o obliku Contaniera. Npr. područje Containera može biti tablica i elemente jednostavno redom dodajemo u ćelije tablice. Prvi element dodajemo u prvu ćeliju prvog reda, sljedeći u drugu ćeliju prvog retka,... posljednji element dodajemo u posljednju (desnu) ćeliju posljednjeg retka tablice. Područje Containera koje će imati oblik tablice od 3 retka i 4 stupca definirat ćemo na sljedeći način: c.setLayout (new GridLayout (3, 4)) , pri čemu je c instanca klase Container.

prozor

Container

Page 103: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

103

Mi ćemo ponekad elemente stavljati na odreñene koordinate Contaienera, jer će nam tako biti lakše. U tom ćemo slučaju područje Containera definirati na sljedeći način: c.setLayout (null);

Ovime smo u stvari rekli da je naše područje prazna ploča i za svaki element ćemo reći na koje koordinate te ploče dolazi.

I na kraju ćemo još samo naučiti kako gotovi element dodati na Container. To ćemo napraviti metodom add klase Container. Opći oblik klase add je:

public void add (Object o);

Primjer 8 – 2: Napišimo program koji će na ekranu nacrtati prozor. Prozor treba imati dva okvira za tekst, jedan ispod drugoga, ispod njih treba imati gumb na kojem piše Zbroji te ispod gumba još jedan okvir za tekst.

Page 104: Java i objektno orijentirano programiranje

104

Rješenje: import javax.swing.*; import java.awt.*; public class Zbrajanje extends JFrame { private final int sirina = 220; private final int visina = 200; private Container c; private JTextField t1, t2, t3; private JButton b; public Zbrajanje() { setTitle ("Zbrajanje"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null ); //prvi okvir za tekst t1 = new JTextField (); t1. setSize (200, 25); t1. setLocation (5, 5); c. add (t1); //drugi okvir za tekst t2 = new JTextField (); t2. setSize (200, 25); t2. setLocation (5, 45); c. add (t2); //gumb b = new JButton (); b. setText ("Zbroji"); b. setSize (200, 25); b. setLocation (5, 85); c. add (b);

//tre ći okvir za tekst t3 = new JTextField (); t3. setSize (200, 25); t3. setLocation (5, 125); c. add (t3); setVisible ( true ); } public static void main ( String[] s) { Zbrajanje z = new Zbrajanje (); } } Pokretanjem metode main , na ekranu će se pojaviti sljedeći prozor:

Page 105: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

105

Page 106: Java i objektno orijentirano programiranje

106

Zadaci za vježbu 1. Što je grafičko korisnikčko sućelje? 2. Koji paket moramo uključiti u program da bismo mogli raditi s prozorima? 3. Koja klasa omogućava crtanje prozora na ekranu? 4. Što je container? 5. Koja klasa omogućava kreiranje gumba na prozoru? 6. Koja klasa omogućava kreiranje okvira za tekst na prozoru? 7. Definiraj prozor koji će oko sredine imati jedan gumb na kojem će pisati OK. 8. Definiraj prozor koji će imati sljedeći oblik (nije potrebno voditi računa oboji teksta na

gumbima):

Page 107: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

107

9

Dogañaji

� Dogañaji

Page 108: Java i objektno orijentirano programiranje

108

Dogañaji U primjeru iz prethodnog poglavlja smo kreirali jedno korisničko sučelje, u čije okvire za tekst možemo unositi tekst, brojeve ili bilo što drugo. Nekako smo navikli da se klikom na gumb dogodi neka očekivana akcija. Ovdje bi nekako bilo za očekivati da se klikom na gumb Zbroji zbroje brojevi koji pišu u prvom i drugom okviru za tekst te da se rješenje upiše u posljednji okvir za tekst. Meñutim klikom na gumb Zbroji ne dogaña se ništa. Zašto? Pa vrlo jednostavno nismo rekli što se treba dogoditi kada kliknemo na gumb. Općenito, klikom na gumb kreira se jedan dogañaj. Taj dogañaj šalje poruku drugom objektu, koji ćemo nazvati listener. Listener raspolaže sa svim podacima o dogañaju (npr. zna koji je gumb pritisnut ako ih je više,...). Kada primi poruku o dogañaju listener izvršava neku radnju, tj. pokreće odgovarajuću metodu koju smo mu definirali. Java ima nekoliko različitih klasa za praćenje različitih tipova dogañaja. Mi ćemo se u ovom trenutku fokusirati na dogañaje koji su povezani sa sučeljem. Takve dogañaje zvat ćemo akcije. Rad s dogañajima vezanim uz sučelje omogućava nam klasa ActionListener , koja sadrži samo zaglavlje metode actionPerformed . Tijelo metode actionPerformed ćemo definirati u vlastitoj klasi. Unutar tijela metode actionPerformed ćemo staviti kôd koji će se izvršiti kao reakcija na neki dogañaj. Općenito ćemo klase koje sadrže samo zaglavlja metoda zvati interface. Dakle, ActionListener je zapravo interface, čija bi definicija mogla imati sljedeći oblik: public interface ActionListener { public void actionPeroformed (ActionEvent e) } S obzirom da metoda actionPerformed nema tijela, dakle nije definirana u interfaceu, nije moguće kreirati instancu interfacea ActionListener , no kako ga trebamo u svojoj klasi, ipak ga trebamo nekako u nju uključiti. Općenito ćemo korištenje interfacea u klasi najaviti na sljedeći način:

public class ime_paketa implements ime_interfacea;

Za našu klasu Zbrajanje bi u tom slučaju zaglavlje imalo sljedeći oblik: public class Zbrajanje extends JFrame implements ActionListener

Budući da se interface nalazi u posebnom paketu java.awt.event , morat ćemo i taj paket uključiti u klasu u kojoj ćemo obrañivati dogañaje. Nadalje trebamo "registrirati" elemente na kojima želimo pratiti dogañaje. To ćemo napraviti izvršavanjem metode:

addActionListener (Object o)

nad odreñenim objektom. Kao što možemo primijetiti kao parametar metode addActionListener dolazi neki objekt. Radi se o tome da se može kreirati posebna klasa koja će obrañivati dogañaje i u tom slučaju se kao parametar navodi instanca te klase. Mi ćemo dogañaje uvijek obrañivati u klasi u kojoj će se dogañaj i dogoditi, stoga ćemo kao parametar uvijek pisati this . Dakle, naša metoda addActionListener uvijek će imati oblik:

Page 109: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

109

ime_objekta.addActionListener ( this )

Mi ćemo za sada samo pratiti dogañaje na gumbima, iako je moguće pratiti dogañaje i na ostalim elementima sučelja, no o tome ćemo govoriti nešto kasnije. Na kraju trebamo definirati metodu actionPerformed , unutar koje ćemo definirati akcije za sve dogañaje koje pratimo. Zaglavlje metode actionPerformed je:

actionPerformed (ActionEvent e)

Parametar e metode actionPerformed ima sve informacije o dogañajima, pa izmeñu ostaloga zna i nad kojim elementom je dogañaj izvršen. Metoda koja će nam vratiti ime objekta nad kojim je izvršen dogañaj je getSource () i pozvat ćemo ju nad objektom tipa ActionEvent . Ponovimo još jednom. Za obrañivanje dogañaja trebamo napraviti sljedeće korake:

1. uključiti paket java.awt.event 2. implementirati interface ActionListener u svojoj klasi. To ćemo napraviti tako da u

zaglavlju klase dodamo još implements ActionListener . Npr. public cl ass Zbrajanje extends JFrame implements ActionListener

3. registrirati listener na elementu grafičkog korisničkog sučelja metodom addActionListener (Objekt o) . Npr. b. addActionListener ( this ). this u ovom slučaju znači da je listener implementiran u klasi u kojoj se upravo nalazimo, i svi naši primjeri će izgledati tako.

4. definirati metodu actionPerformed , koja će sadržavati kôd koji će se izvršiti kao reakcija na neki dogañaj.

Primjer 9 – 1: Izmijenimo Primjer 8 – 2, tako da se klikom na gumb Zbroji u treći okvir za tekst upiše zbroj brojeva koji su upisani u prva dva okvira za tekst. Rješenje: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Zbrajanje extends JFrame implements ActionListener { private final int sirina = 220; private final int visina = 200; private Container c; private JTextField t1, t2, t3; private JButton b; public Zbrajanje() { setTitle ("Zbrajanje"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null ); t1 = ne w JTextField (); t1. setSize (200, 25);

Page 110: Java i objektno orijentirano programiranje

110

t1. setLocation (5, 5); c. add (t1); t2 = new JTextField (); t2. setSize (200, 25); t2. setLocation (5, 45); c. add (t2); b = new JButton (); b. setText ("Zbroji"); b. setSize (200, 25); b. setLocation (5, 85); //najavljujemo pra ćenje doga ñaja nad gumbom b b. addActionListener ( this ); c. add (b); t3 = new JTextField (); t3. setSize (200, 25); t3. setLocation (5, 125); c. add (t3); setVisible ( true ); } //metoda koja uzima sadržaj prvog i drugog okvira z a tekst //te ih zbraja i zbroj postavlja u tre ći okvir za tekst public void zbroji () { int a = Integer . parseInt (t1. getText ()); int b = Integer . parseInt (t2. getText ()); int c = a + b; t3. setText ("" + c); } //definicija metode actionPerformed na bilo koji do gañaj //koji se prati će se izvršiti metoda zbroji () public void actionPerformed ( ActionEvent e) { zbroji (); } public static void main ( String[] s) { Zbrajanje z = new Zbrajanje (); } } Primijetimo da smo u prošlom primjeru pratili samo jedan dogañaj i to onaj nad gumbom b, stoga smo rekli da se na bilo koji dogañaj izvrši metoda zbroji (). Meñutim često ćemo unutar programa morati pratiti više dogañaja i u tom slučaju uglavnom nećemo uvijek izvršavati istu metodu, stoga ćemo morati provjeriti nad kojim elementom je dogañaj izvršen i ovisno o elementu ćemo izvršiti odgovarajuću metodu. Naziv objekta nad kojim je izvršena akcija dobit ćemo metodom getSource () koju pozivamo nad objektom tipa ActionEvent . Dakle, naša metoda actionPerformed iz prethodnog primjera mogla bi imati i sljedeći oblik: public void actionPerformed ( ActionEvent e) {

Page 111: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

111

if (e. getSource () == b) zbroji ();

}

Page 112: Java i objektno orijentirano programiranje

112

Zadaci za vježbu 1. Što sve moramo napraviti kako bismo mogli pratiti dogañaje na nekom elementu prozora? 2. Što je interface? 3. Napiši program koji će na ekranu crtati prozor kao na slici. Klikom na gumb Mijenjaj se

iznos duljine u centimetrima treba pretvoriti u iznos duljine u inchima (1 inch = 2.54 cm).

4. Napiši program koji će crtati prozor kao na slici. Klikom na gumb Kodiraj se tekst iz gornjeg

okvira za tekst treba kodirati i tako kodiran prepisati u donji okvir za tekst. Tekst ćemo kodirati tako da svaki znak zamijenimo znakom čiji je ASCII kôd za jedan veći od ASCII kôda odgovarajućeg znaka. Klikom na gumb Dekodiraj se tekst iz donjeg okvira za tekst treba dekodirati i tako dekodiran prepisati u gornji okvir za tekst.

5. Napiši program koji će crtati prozor kao na slici. Klikom na gumb OK gumb se treba

pomaknuti u slučajnom smjeru za 10 pixela. Napomena: pri pomicanju gumba treba voditi računa da niti jedan dio gumba ne izañe izvan okvira prozora.

Page 113: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

113

6. Napiši program koji će crtati ekran i na njemu jedan gumb. Kada se program učita na gumbu treba pisati tekst Broj: 0. Svakim klikom na gumb tekst na gumbu se treba izmijeniti i to tako da se izmijeni broj pokraj teksta Broj (nakon prvog klika na gumbu treba pisati Broj: 1, nakon drugog Broj: 2,...)

7. Napiši program koji će na ekranu crtati prozor i dva gumba (Gumb 1 i Gumb 2). Na početku

će biti aktivan samo prvi gumb (Gumb 1), klikom na prvi gumb on postaje neaktivan a aktivan postaje drugi gumb. Klikom na drugi gumb on postaje neaktivan a aktivan postaje ponovo prvi gumb,...

Page 114: Java i objektno orijentirano programiranje

114

10

Iznimke

� Što je iznimka? � Hvatanje iznimki u Javi � Procesiranje iznimki

Page 115: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

115

Što je iznimka? Napisali smo program provjerili ga za neke svoje podatke i sve radi kako treba, testiramo program ponovo, kad gle, sada ne radi, izbacuje grešku. U čemu je problem? Razloga zašto je program maloprije radio a sada više ne radi je puno. Neki od češćih su:

− program čita podatke iz datoteke, koju smo u meñuvremenu izbrisali ili preimenovali; − umjesto broja smo unijeli znak; − podaci su takvi da se u nekom trenutku pojavljuje dijeljenje s nulom; − ...

Sve gore navedene situacije u stvari nisu greške, već specifične situacije za koje naš program ne radi ispravno tzv. iznimke. Kako takvih iznimnih situacija može biti jako puno i teško ih je sve predvidjeti, Java nudi mogućnost automatskog pračenja iznimaka. Jednostavno ćemo u kodu doati do znanja da je neki dio programa problematičan i da bi se u njemu mogla pojaviti iznimka. Ukoliko se iznimka ne pojavi, nikome ništa, program će se izvršiti kako smo i htjeli i to je u stvari očekivano ponašanje. Meñutim, ako se iznimka pojavi, program neće stati s radom, kao inače, već ćmo mi reči što treba napraviti u takvoj situaciji. Najčešće će to biti poruka korisniku da se je pojavila greška, pokušaj ispravljanja greške predviñanjem onoga što je korisnik programa htio napraviti,...

Hvatanje iznimki u Javi U programu možemo specificirati da pratimo samo odreñenu vrstu iznimki, npr. pratimo samo iznimke koje mogu uslijediti zbog unosa pogrešnog tipa podatka, iznimke vezane uz pristup fileovima, iznimke vezane uz formate brojeva,... Dio koda koji bi mogao prouzročiti iznimku u programu stavljamo u blok try . Nakon try bloka slijedi catch blok, kojih može biti više. U bloku catch specificiramo vrstu iznimke koju pratimo. Iza posljednjeg catch bloka opcionalno dolazi blok finally . Unutar bloka finally stavljamo dio programa koji se izvršava uvijek, bez obzira je li došlo do greške ili nije. Finally blok je opcionalan, meñutim ako nismo stavili niti jedan catch blok, nakon try moramo staviti finally blok. try { //naredbe koje bi mogle prouzrokovati iznimke } catch ( VrstaIznimke1 iz1) {

/* dio koda koji se izvršava ako se je pojavila iznimk a tipa VrstaIznimke1 */

} ... finally { /*

dio programa koji se uvijek izvršava, bez obzira je li došlo do iznimke ili ne */

}

Page 116: Java i objektno orijentirano programiranje

116

Ukoliko se u nekoj od naredbi unutar bloka try pojavi iznimka prelazi se na prvi catch blok, ukoliko taj catch blok "nadležan" za pračenje iznimke koja se je pojavila u bloku try izvršava se kod unutar tog catch bloka, inače se prijelazi na sljedeći catch blok,... Na kraju se uvijek (bez obzira je lise iznimka pojavila ili ne) prelazi na finally blok, ukoliko on postoji. Ukoliko iza bloka try ne postoji blok catch , tada se odmah prelazi na blok finally , koji u tom slučaju morapostojati. Već smo rekli da postoji nekoliko vrsta iznimki koje možemo pratiti i tada naziv te iznimke navodimo kod catch bloka. Vrste iznimki definirane su posebnim klasama. Osnovna klasa koja nam omogućava pračenje svih iznimaka u programu je klasa Exception. Sve ostale klase za pračenje iznimki nasljeñuju klasu Exception. Kao i svaka druga klasa, Exception, pa onda i sve druge klase za pračenje iznimaka imaju svoje metode. Najčešće korištene metode su: Metoda Opis getMessage () vraća opis iznimke toString () vraća vrstu iznimke, odnosno naziv klase koja je stvorila

iznimku printStackTrace () koristi se kod nasljeñivanja klasa a koristi se kada se želi

pratiti u kojim su se klasama i metodama greške pojavljivale

Tablica 10 – 1 Metode klase Exception Kao što smo već rekli, osim genralne klase Exception, koja prati sve iznimke koji se mogu pojaviti, postoji i niz drugih klasa za pračenje odreñenog tipa iznimki, a koje nasljeñuju klasu Exception. Neke od klasa za pračenje iznimaka dane su u sljedećoj tablici: Klasa iznimaka Opis ArithmeticException Aritmetičke greške kao dijeljenje s 0,... FileNotFoundException Rad s fileom koji ne postoji StringIndexOutOfBoundsException Indeks u stringu ne postoji NumberFormatException Nedozvoljeni format broja Tablica 10 – 2 Najčešće klase za pračenje iznimaka Korištenje klasa za automatsko pračenje iznimaka uvelike olakšava posao programera. U programima je bitno voditi računa da pratite pravu vrstu iznimki, kako neke vrste iznimki ne bi prošle neprimjećene, što bi u tom slučaju prouzročilo prekid u radu programa. Hvatanje apsolutno svih iznimaka korištenjem klase Exception je moguće ali nije baš preporučljivo. Primjer 10 – 1: Napišimo program koji će na ekranu nacrtati prozor. Prozor treba imati dva okvira za tekst, jedan ispod drugoga, ispod njih treba imati gumb na kojem piše Zbroji te ispod gumba još jedan okvir za tekst. Klikom na gumb Zbroji u treći okvir za tekst upiše zbroj brojeva koji su upisani u prva dva okvira za tekst. U slučaju da nešto od unesenog nije broj, u treći okvir za tekst treba ispisati odgovarajuću poruku. Rješenje: import javax.swing.*; import java.awt.*;

Page 117: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

117

import java.awt.event.*; public class Zbrajanje extends JFrame implements ActionListener { private final int sirina = 220; private final int visina = 200; private Container c; private JTextField t1, t2, t3; private JButton b; public Zbrajanje() { setTitle ("Zbrajanje"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null ); t1 = new JTextField (); t1. setSize (200, 25); t1. setLocation (5, 5); c. add (t1); t2 = new JTextField (); t2. setSize (200, 25); t2. setLocation (5, 45); c. add (t2); b = new JButton (); b. setText ("Zbroji"); b. setSize (200, 25); b. setLocation (5, 85); b. addActionListener ( this ); c. add (b); t3 = new JTextField (); t3. setSize (200, 25); t3. setLocation (5, 125); c. add (t3); setVisible ( true ); } public void zbroji () { try { int a = Integer . parseInt (t1. getText ()); int b = Integer . parseInt (t2. getText ()); int c = a + b; t3. setText ("" + c); } catch ( NumberFormatException e) { t3. setText ("Pogrešan format broja"); } } public void actionPerformed ( ActionEvent e) { zbroji ();

Page 118: Java i objektno orijentirano programiranje

118

} public static void main ( String[] s) { Zbrajanje z = new Zbrajanje (); } }

Procesiranje iznimki Kako se u stvari prate iznimke u programu? Kada se unutar try bloka neke metode dogodi iznimka, neki dio metode se ne može korektno izvršiti, kontrola programa se preusmjeri na catch blok. Promotrimo to na prethodnom primjeru. Metoda zbroji () imala je sljedeći oblik: public void zbroji () {

try { int a = Integer . parseInt (t1. getText ()); int b = Integer . parseInt (t2. getText ()); int c = a + b; t3. setText ("" + c); } catch ( NumberFormatException e) { t3. setText ("Pogrešan format broja"); }

} Ukoliko korisnik u okvir za tekst t1 unese vrijednost koja nije cijeli broj. Naredba: Integer . parseInt (t1. getText ()); neće se moči uspješno izvršiti. te će se preskočiti sve druge naredbe unutar try bloka i izvršavanje programa će se nastaviti u catch bloku, tj. izvršit će se naredba: t3. setText ("Pogrešan format broja"); Što je u stvari u pozadini toga. Priča ide otprilike ovako. Programer koji je programirao metodu parseInt () klase Integer , pretpostavio je da bi se često moglo dogoditi da parametar ove metode ne bude string koji se sastoji samo od znamenaka. U tom će se slučaju dogoditi nekoliko stvari:

− kreirati će se objekt iz neke od klasa za rad s iznimkama (u ovom slučaju je to specijalno klasa NubmerFormatException );

− izvršavanje metode (u našem slučaju zbroji () ) na tom mjestu prestaje te se traži mjesto za nastavak izvršavanja. To mjesto je blok catch .

Postavlja se pitanje, a možemo li mi, poput programera koji je programirao metodu parseInt () , kod svojih metoda na ovakav način preusmjeravati izvršavanje programa i vraćati poruke o greškama? Naravno da možemo i to na sljedeći način: Pretpostavimo da imamo metodu inicijali () , čiji je parametar tipa string, koji predstavlja ime i prezime neke osobe, odvojene jednim razmakom, a metoda vraća inicijale te osobe (prvo slovo imena i prvo slovo prezimena) Metoda inicijali () , unutar svoje klase bi mogla izgledati ovako: public class Inicijali

Page 119: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

119

{ public static String inicijali ( String ime) {

int n = ime. indexOf (" "); return ime. substring (0, 1) + ". " + ime. substring (n + 1, n + 2) +

"."; } } Budući da je metoda inicjali () static, može se pozivati bez da se kreira objekt klase Inicijali , pa stoga klasa Inicijali ne mora imati konstruktor. Napišimo sada odgovarajući program i testirajmo ovu metodu: Primjer 10 – 2: Napišimo program koji će crtati korisničko sučelje kao na slici. Klikom na gum Inicijali, u drugi okvir za tekst trebaju se ispisati inicijali osobe čije je ime i prezime uneseno u prvi tekstualni okvir.

Rješenje: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class TestInicijali extends JFrame implements ActionListener { private Container c; private JButton b1; private JTextField t1, t2; public TestInicijali() { setTitle ("Inicijali"); setSize (300, 120); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( new GridLayout (3, 1)); t1 = new JTextField (); c. add (t1); b1 = new JButton (); b1. setText ("Inicijali"); b1. addActionListener (this); c. add (b1); t2 = new JTextField (); c. add (t2);

Page 120: Java i objektno orijentirano programiranje

120

setVisible (true); } public void actionPerformed ( ActionEvent e) { t2. setText (Inicijali.inicijali (t1. getText ())); } public static void main ( String [] s) { TestInicijali ti = new TestInicijali (); } } Pokrenemo li program i upišemo npr. u prvi okvir za tekst Ivan Marković, program će raditi dobro, no meñutim upišemo li samo Ivan, program neće raditi dobro, a ako upišemo Ivan i na kraju stavimo još jedan razmak, potpuno će se srušiti. To rušenje programa nam se ne sviña. Greška je u tome što se mi u svojom metodi inicijali () na jednom mjestu referenciramo na prvi znak iza razmaka, no što ako razmak uopće ne postoji? Što ako nema znaka nakon prvog razmaka? To su izuzetne situacije i u njima bi program trebao javiti grešku, pa ispravimo svoju metodu inicijali () tako da radi korektno: public class Inicijali { public static String inicijali ( String ime) throws Exception {

int n = ime. indexOf (" "); if (n == -1 || n == ime. length () - 1) throw new Exception ("Podaci nisu potpuni"); else return ime. substring (0, 1) + ". " + ime. substring (n + 1, n +

2) + "."; } } Kao što možemo primijetiti dodali smo u metodi provjeravanje uvjeta. Ukoliko nema razmaka ili je jedini razmak na posljendjem mjestu, izvršavanje metode koja poziva metodu inicijali () će se prekinuti, kreirat će se objekt Exception te će se izvršavanje metode nastaviti u bloku catch . String koji prosljeñujemo konstruktoru klase Exception u stvari će biti tekst poruke koju će objekt tipa exception vratiti metodom getMessage () , odnosno tekst prvog reda koji vraća metoda printStackTrace () . Primijetimo da smo izmijenili i zaglavlje metode inicijali () , u nastavku smo dodali throws Exception , što u osnovi znači da metoda sve iznimke prosljeñuje klasi Exception . Umjesto Exception mogla se je ovdje nači i neka druga klasa nakoju bi prosljeñivali izvršavanje programa u slučaju greške. Nakon što smo ovako izmijenili metodu inicijali, moramo izmijeniti i metodu actionPerformed () koja poziva metodu inicijali () . Naime, u metodi actionPerformed () dio koda u kojem se nalazi poziv metode inicijali trebamo staviti u try blok. Tako izmijenjena metoda actionPerformed () sada ima oblik: public void actionPerformed ( ActionEvent e) {

try { t2. setText (Inicijali.inicijali (t1. getText ()));

Page 121: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

121

} catch ( Exception e1) { t2. setText (e1. getMessage ()); }

} Pokrenemo li sada program i u prvi okvir za tekst upišemo samo Ivan i razmak, program se ovaj puta neće srušiti, već će u drugom okviru za tekst pisati poruka: Podaci nisu potpuni

Page 122: Java i objektno orijentirano programiranje

122

Zadaci za vježbu 1. Objasni iznimke. 2. Navedi neke primjere koji mogu izazvati iznimku. 3. Kako procesiramo iznimke u Javi? 4. Navedi neke klase iznimaka u Javi. 5. Napiši program koji će crtati prozor kao na slici. Klikom na gumb Novi broj treba generirati

i na labelu ispisati slučajan broj iz zadanog intervala.

6. Napiši program koji će crtati prozor kao na slici. Klikom na gumb Računaj na labelu se treba

ispisati nova cijena koja se dobije uvećavanjem početne cijene za zadani postotak.

7. Napiši program koji će crtati prozor kao na slici. Klikom na gumb Računaj u okvir za tekst

se treba ispisati iznos anuiteta kredita za upisani iznos kredita, kamatnu stopu te broj mjeseci. Iznos anuiteta se računa prema sljedećoj formuli:

1

)1(

−−=

n

n

r

rCra , pri čemu je:

12001

pr += , p – godišnja kamatna stopa, C – iznos kredita i n

– broj mjeseci otplate.

Page 123: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

123

8. Napiši program koji će crtati prozor kao na slici. Klikom na gumb Mijenjaj boja teksta

Tekst se treba promijeniti. Novu boja teksta će biti boja čije se RGB komponente unose u postavljene okvire za tekst.

9. Napiši program koji će crtati prozor kao na slici. U lijevom gornjem dijelu prozora ispisuje se

zadatak. Zadatak se sastoji od dva broja i jedne od operacija (+, - ili *). Unosom broja u okvir za tekst i klikom na gumb Dalje treba provjeriti ispravnost rješenja i ovisno o točnom odgovoru izmijeniti broj točnih i broj ukupnih bodova (točno/ukupno) i generirati novi zadatak. Klikom na gumb Kraj treba završiti rad s programom.

Page 124: Java i objektno orijentirano programiranje

124

11

Složeniji elementi grafičkog korisničkog

sučelja

� Kvadratići za odabir opcija � Kružići za odabir opcija � Područja za tekst � Trake za pomicanje � Padajuće liste � Izbornici

Page 125: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

125

U 6. poglavlju smo se upoznali s osnovnim elementima korisničkog sučelja (gumbi, Labele i okviri za tekst), osim navedenih, u programima ćesto susrećemo i niz drugih elemenata korisničkog sućelja, a o najčešćima ćemo govoriti u ovom poglavlju. S obzirom da smo se već susretali s elementima grafičkog korisničkog sućelja, ovdje se nećemo puno zadržavati na pojedinom elementu.

Kvadratići za odabir opcija Kvadratiće za odabir opcija koristimo kada u programu trebamo odabratu jednu, više ili niti jednu od ponuñenih opcija. Nakon što pojedinu opciju odaberemo pojavi se kvačica u kvadratiću ispred nje.

Slika 11 – 1: Primjer kvadratića za odabir opcija

Kvadratić za odabir kreirat ćemo koristeći klasu JCheckBox . Najčešće metode koje ćemo koristiti pri radu s kvadratićima za odabir opcija su: public void setSize (int s, int v) – definira veličinu kvadratića i podrućja za tekst koje se ispisuje pokraj kvadratića. Kvadratić je uvijek iste veličine, bez obzira na definiranu veličinu. public void setLocation (int x, int y) – definira poziciju kvadratića za odabir na Containeru. public void setText (String s) – definira tekst koji će se pojaviti pokraju kvadratića za tekst public String getText () – vraća tekst koji je upisan pokraj kvadratića za odabir public void setEnabled (boolean b) – ukoliko je b postavljen na true kvadratić će biti aktivan i moći će se označiti (odznačiti), inače će biti neaktivan i nećemo nad njim napraviti nikakvu radnju. public void setSelected (boolean b) – ukoliko je b true kvadratić će biti označen, inače neće biti označen. Inicijalno kvadratić neće biti označen. public void addActionListener (Object o) – dodaje listener na kvadratiću za odabir. Primjer 11 – 1: Dio programa koji će na ekranu iscrtati gumbe kao na slici 11 – 1. Rješenje: ...

private JCheckBox nog, kos, ruk, atl; ...

nog = new JCheckBox (); nog. setText ("Nogomet"); nog. setSize (80, 25); nog. setLocation (10, 10); c. add (nog);

Page 126: Java i objektno orijentirano programiranje

126

kos = new JCheckBox (); kos. setText ("Košarka"); kos. setSize (80, 25); kos. setLocation (10, 40); c. add (kos);

ruk = new JCheckBox (); ruk. setText ("Rukomet"); ruk. setSize (80, 25); ruk. setLocation (10, 70); ruk. setEnabled ( false ); c. add (ruk);

atl = new JCheckBox (); atl. setText ("Atletika"); atl. setSize (80, 25); atl. setLocation (10, 100); atl. setSelected ( true ); c. add (atl);

...

Kružići za odabir opcija Osim kvadratića o kojima smo upravo govorili za odabir možemo koristiti i kružiće. Kružiće ćemo u pravilu koristiti u slučajevima kada ćemo trebati od ponuñenih opcija odabrati točno jednu.

Slika 11 – 2: Primjer kružića za odabir opcija

Kružiće za odabir kreirat ćemo koristeći klasu JRadioButton . Najčešće metode koje ćemo koristiti pri radu s kružićima za odabir su: public void setSize (int s, int v) – definira veličinu kružića i podrućja za tekst koje se ispisuje pokraj njega. Kružić je uvijek iste veličine, bez obzira na definiranu veličinu. public void setLocation (int x, int y) – definira poziciju kružića na Containeru. public void setText (String s) – definira tekst koji će se ispisati pokraj kružića za odabir. public String getText () – vraća tekst koji je upisan pokraj kružića za odabir public void setEnabled (boolean b) – ukoliko je b postavljen na true kružić će biti aktivan i moći će se označiti (odznačiti), inače će biti neaktivan i nećemo nad njim napraviti nikakvu radnju. public void setSelected (boolean b) – ukoliko je b true kružić će biti označen, inače neće biti označen. Inicijalno kružić neće biti označen. public void addActionListener (Object o) – dodaje listener na kružić za odabir. Primjer 11 – 2: Dio programa koji će na ekranu iscrtati gumbe kao na slici 11 – 2. Rješenje: ...

Page 127: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

127

private JRadioButton m, z; ...

m = new JRadioButton (); m.setText ("Muški"); m.setSize (80, 25); m.setLocation (10, 10); m.setSelected ( true ); c. add (m);

z = new JRadioButton (); z. setText ("Ženski"); z. setSize (80, 25); z. setLocation (10, 40); c. add (z);

...

Pokusamo li u gornjem primjeru označiti samo Ženski spol, neće nam bać poći za rukom, što god napraviti bit će označen i Muški spol. Najčešće to neće biti ono što želimo. Najčešće ćemo htjeti označiti samo jedan od gumbova. Kako to ne bismo morali programirati možemo koristiti jedan poseban element kojim ćemo grupirati gumbe i na taj način omogućiti označavanje samo jednog od gumba. Radi se o elementu koji neće biti vidljiv na samom prozoru, a kreirat ćemo ga koristeći klasu ButtonGroup . Jedina metoda klase ButtonGroup koju ćemo koristiti je: public void add (Object o) – dodaje gumb na grupu gumba, pri ćemu je o kružić ili pravokutnik za odabir. Primjer 11 – 3: Izmijenimo prethodni primjer tako da gumbe grupiramo te na taj način omogućimo da u svakom trenutku može biti označen samo jedan gumb. Rješenje: ...

private JRadioButton m, z; private ButtonGroup b;

... m = new JRadioButton (); m.setText ("Muški"); m.setSize (80, 25); m.setLocation (10, 10); m.setSelected ( true ); c. add (m);

z = new JRadioButton (); z. setText ("Ženski"); z. setSize (80, 25); z. setLocation (10, 40); c. add (z); b = new ButtonGroup (); b. add (m); b. add (z);

...

Page 128: Java i objektno orijentirano programiranje

128

Područja za tekst Do sada smo se upoznali s okvirom za tekst. Za razliku od okvira za tekst, koji ćemo koristiti za unos manje količine teksta (ime, prezime, naslov,...), za unos veće količine teksta koristit ćemo tzv podrućja za tekst.

Slika 11 – 3: Primjer podrućja za tekst

Podrućje za tekst kreirat ćemo pomoću klase JTextArea . Najčešće metode koje ćemo koristiti pri radu s klasom JTextArea su: public void setSize (int s, int v) – definira veličinu područja za tekst. public void setLocation (int x, int y) – definira poziciju područja za tekst na Containeru. public void setText (String s) – definira tekst koji će biti upisan u području za tekst. public String getText () – vraća tekst koji je upisan u područje za tekst. public void setEditable (boolean b) – ukoliko je b postavljen na true u područje za tekst će se moći unositi tekst te ga mijenjati, inače će područje za tekst biti neaktivno i nećemo na njemu moći ništanapraviti. public void addActionListener (Object o) – dodaje listener na područje za tekst.

Page 129: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

129

Trake za pomicanje Napravimo li područje za tekst na način na koji smo to naučili u prethodnom primjeru malo ćemo se iznenaditi. Naviknuli smo da kada se jednom područje za tekst popuni, pojavljuju se trake za pomicanje teksta gore – dolje odnosno lijevo – desno. Ovdje ih medutim nema. Da bi se trake za pomicanje teksta pojavile oko područja za tekst, moramo ih eksplicitno postaviti. Kao i za bilo koji drugi element grafičkog korisničkog sučelja i za njih postoji posebna klasa koja ih generira. Klasa koja će generirati trake za pomak je JScrollPane ( objekt o) , pri čemu je o objekt oko kojega postavljamo trake za pomicanje. Najčešće metode koje ćemo koristiti pri radu s klasom JScrollPane su: public void setSize (int s, int v) – definira veličinu traka za pomicanje. public void setLocation (int x, int y) – definira poziciju područja za tekst na Containeru. Primjer 11 – 4: Kreirajmo područje za tekst oko kojega će se nalaziti trake za pomak. Rješenje: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class poglavlje11 extends JFrame {

private final int sirina = 220; private final int visina = 200; private Container c; private JScrollPane p; private JTextArea ta;

public poglavlje11() {

setTitle ("Editor"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE);

c = getContentPane (); c. setLayout ( new GridLayout (1, 1));

ta = new JTextArea ();

p = new JScrollPane (ta);

c. add (p);

setVisible (true); }

public static void main (String[] s) { poglavlje11 z = new poglavlje11 (); }

}

Page 130: Java i objektno orijentirano programiranje

130

Primjetimo da kada oko nekog elementa dodajemo trake za pomicanje, onda taj element ne trebamo posebno dodavatai na Container, već ga dodajemo automatski s trakama za pomicanje.

Padajuće liste Padajuće liste ćemo koristiti kada trebamo odabrati jednu od opcija. Opcije se pojavljuju klikom na gumb s desne strane padajuće liste.

Slika 11 – 4: Primjer padajuće liste Padajuću listu na ekranu generirat će klasa JOptionPane. Opcije padajuće liste moguće je dodati automatski pri kreiranju instance klase JOptionPane. Odnosno, jedan od konstruktora klase JOptionPane ima prametar tipa Object[ ], a koji predstavlja opcije koje će se inicijalno pojaviti nakon kreiranja instance klase JOptionPane. Mi ćemo najčešće u padajuću listu dodavati tekst kao opcije pa će umjesto Object [ ] pisati String [ ]. Isto tako klasa JOptionPane ima jos i niz drugih metoda. Neke od njih su: public void setSize (int s, int v) – definira veličinu padajuće liste. public void setLocation (int x, int y) – definira poziciju padajuće liste na Containeru. public void setSelectedIndex (int n) – opcija s rednim brojem n će biti inicijalno označena. public void setSelectedItem (Object o) – opcija s će biti inicijalno označena public int getSelectedIndex () – vraća redni broj označene opcije. public object getSelectedItem () – vraća označenu opciju. public void setEnabled (boolean b) – ukoliko je b postavljen na true padajuća lista će biti aktivna, inače će biti neaktivan i nećemo nad njom moži napraviti nikakvu radnju. public void addItem (object o) – dodaje opciju o na padajuću listu. public void addActionListener (Object o) – dodaje listener na padajuću listu. Primjer 11 – 5: Dio programa koji će kreirati padajuću listu čije će stavke biti nazivi prvih 5 mjeseci u godini. Rješenje: ... private JComboBox cb ; private String[] mjeseci = {"Sije čanj", "Velja ča", "Ožujak", "Travanj", "Svibanj"}; ... cb = new JComboBox (mjeseci); cb. setLocation (10, 150);

Page 131: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

131

cb. setSize (100, 25); cb. setSelectedIndex (3); cb. addActionListener ( this ); cb. addItem ("..."); c. add (cb); ...

Izbornici Izbornike možemo vidjeti u gotovo svim desktop aplikacijama. Pogodni su jer zauzimaju vrlo malo prostora pri vrhu prozora te na taj način povećavaju područje radne površine programa. Za kreiranje izbornika koristit ćemo nekoliko klasa:

− JMenuBar – za kreiranje izborničke trake, koja se nalazi pri vrhu prozora − JMenu – za kreiranje glavnih izbornika na izborničkoj traci (File, Edit,...) − JMenuItem – za krieranje podstavki unutar glavnih izbornika (npr. unutar izbornika File

najčešće se nalazi podstavke Save, Open,...) Izborničku traku stavljamo direktno na prozor (JFrame) i za to koristimo metodu setJMenuBar klase JFrame. Konstruktor klase JMenu ima jedan parametar i to je tekst koji će se ispisati na glavnom izborniku. Glavne izbornike na izborničku traku dodajemo metodom add klase JMenuBar. Podstavke unutar glavnog izbornika kreirat ćemo kreirajući instancu klase JMenuItem. Jedan od konstruktota klase JMenuItem kao parametar ima string koji u stvari predstavlja tekst koji će biti ispisan na podstavci. Podstavku ćemo na glavni izbornik dodati metodom add klase JMenu. Obično se odabirom neke stavke unuta izbornika dogodi neka akcija, stoga ćemo nad stavkaka unutar izbornika pozivati metode addActionListener , na način kao što smo to radili nad drugim elementima. Glavni izbornici i stavke unutar glavnih izbornika bit će poslagani onim redosljedom kako ih dodajemo odgovarajućim add metodama. Primjer 11 – 6: Unutar prozora kreirajmo izborničku traku koja će sadržavati dva glavna izbornika: Dokument i Ureñivanje. Unutar izbornika Dokument trebaju se nalaziti stavke: Novi, Spremi, Otvori i Kraj; unutar izbornika Ureñivanje trebaju se nalaziti stavke: Označi sve, Izreži, Kopiraj i Zalijepi.

Rješenje: ... mb = new JMenuBar (); setJMenuBar (mb); dokument = new JMenu ("Dokument"); mb.add (dokument); uredivanje = new JMenu ("Ure ñivanje");

Page 132: Java i objektno orijentirano programiranje

132

mb.add (uredivanje); novi = new JMenuItem ("Novi"); dokument. add (novi); spremi = new JMenuItem ("Spremi"); dokument. add (spremi); otvori = new JMenuItem ("Otvori"); dokument. add (otvori); kraj = new JMenuItem ("Kraj"); dokument. add (kraj); oznaci = new JMenuItem ("Oznaci sve"); uredivanje. add (oznaci); kopiraj = new JMenuItem ("Kopiraj"); uredivanje. add (kopiraj); izrezi = new JMenuItem ("Izrezi"); uredivanje. add (izrezi); zalijepi = new JMenuItem ("Zalijepi"); uredivanje. add (zalijepi); ...

Page 133: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

133

Page 134: Java i objektno orijentirano programiranje

134

12

Unos i ispis podataka

� Streamovi � Standardni ulaz i izlaz � Tekstualne datoteke

Page 135: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

135

Streamovi Jedna od osnovnih pretpostavki programa je da na osnvu ulaznih podataka u konačnom broju koraka daju ispravne izlazne rezultate. Unositi podatke u program te prikazivati rezultate moguće je na različite načine. Mi smo u početku podatke unosili prosljeñivanjem vrijednosti parametara metodama kroz BlueJ razvojno okruženje. U posljednjem smo poglavlju naučili kako kreirati grafičko korisničko sučelje u Javi, te smo programima vrijednosti prosljeñivali kroz elemente grafičkog korisničkog sučelja (najčešće okvire za tekst). Rezultate obrade smo isto tako prikazivali kroz elemente BlueJ razvojnog okruženja ili na nekom elementu grafičkog korisničkog sučelja. U praksi je unos podataka i prikaz rezultata obrade preko elemenata grafičkog korisničkog sučelja uistinu vrlo čest. Ne tako davno, dok još nisu postojali moderni operativni sustavi s grafičkim korisničkim sučeljima programi su se pokretali iz tzv. komandnog prompta. Na isti su se način prosljeñivali i ulazni podaci takvim programima (slika 12 – 1). Rezultati su se takoñer ispisivali u komandoj liniji. Takve programe možemo pisati i danas i zovemo ih konzolnim programima.

Slika 12 – 1: Program s tekstualnim korisničkim sučeljem

Meñutim isto tako se nerijetko podaci, koji su predmet obrade uzimaju iz prethodno definiranih dokumenata ili tablica baza podataka. Rezultati obrade se isto tako mogu pohranjivati u datoteke ili baze podataka i kao takvi mogu poslužiti kao ulazni podaci za neke druge programe,... Podatke je isto tako moguće dobivati iz nekog specijalnog mjernog ureñaja (termometar,...) s drugih računala koristeči računalne mreže,... U nastavku čemo se baviti konzolnim programima koji s podacima manipuliraju pomoću komandnog prompta, odnosno programima koji podatke unose iz datoteka ili rezultate obrade spremaju u datoteke. Nešto kasnije ćemo dati i primjere kako razmjenjivati podatke s drugim računalima putem računalne mreže te kako komunicirati s bazama podataka. Za unos odnosno ispis podataka najčešće se koriste streamovi. Stream predstavlja bilo koji izvor s kojeg možemo uzimati ili na koji možemo stavljati podatke. U javi postoje dva osnovna tipa streamova streama:

− bajtovni stream − znakovni stream

Page 136: Java i objektno orijentirano programiranje

136

Bajtovni streamovi Bajtovni streamovi nam omogučavaju jednostavan unos odnosno ispis bajtova. Rad s bajtovnim streamovima omogučavaju nam dvije osnove klase:

− InputStream – za unos bajtova − OutputStream – za ispis bajtova

Klasa InputStream i sve klase koje ju nasljeñuju ima metodu read () koja učitava sljedeći bajt s ulaza. S obzirom da read () uzima bajt s ulaza, ova metoda vraća tip podataka integer. Isto tako klasa OutputStream i sve klase koje ju nasljeñuju ima metodu write () za ispis jednog bajta. Znakovni streamovi Znakovne streamove koristimo za unos i ispis znakova. Za rad s znakovnim streamovima definirane su dvije klase:

− Reader − Writer

Osim ovih dviju osnovnih klasa definirano je još i niz drugih klasa koje ih nasljeñuje. Klasa Reader i sve klase koje ju nasljeñuju imaju metodu read () za unos jednog znaka. Isto tako klasa Writer i sve klase koje ju nasljeñuju imaju metodu write () za ispis jednog znaka. Sve navedene klase za rad sa streamovima nalaze se u paketu java.io .*, te se moraju uključiti u progam naredbom import .

Standardni ulaz i izlaz Svi programi u Javi inicijalno imaju ukljčen paket System. Unutar tog paketa izmeñu ostaloga nalaze se tri stream varijable koje su nam trenutno bitne. Radi se o svojstvima: in, out, err. Sva tri svojstva definirana su kao public i static, što znači da im možemo pristupati direktno bez kreiranja objekta tipa System. System.in se odnosi na standardni ulaz koji je u principu tipkovnica. System.out je standardni izlazni stream, inicijalno je to konzola (komandna linija). System.err je standardni stream za rad s greškama, inicijalno je to i ovdje konzola. System.in je tipa InputStream, dok su System.out i System.err tipa PrintStream. Kao što možemo primijetiti radi se o bajtovnim streamovima koji se najčešće koriste za unos podataka s konzole i ispis na konzolu. Učitavati podatke bajt po bajt nas neće previše usrečiti. U tom trenutku u pomoć dolazi klasa BufferedReader. Pojednostavljeno rečeno, klasa BufferedReader mogučava unošenje čitavih linija teksta s ekrana, što će nam uvalike olakšati unos podataka. Konstruktor klase BufferedReader je oblika BufferedReader (Reader r). Kao što znamo, naš System.in je tipa InputStream, a ne Reader, meñutim i za to se je netko pobrinuo. System.in ćemo transformirati u Reader koristeći InputStreamReader. Pojednostavljeno rečeno, želimo li kreirati objekt koji će nam omogučiti čitanje linija teksta sa standardnog ulaza, to ćemo napraviti na sljedeći način:

Page 137: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

137

BufferedReader br = new BufferedReader ( new InputStreamReader ( System . in ))

Izvršavanjem navedenog dijela koda bit će kreiran objekt br koji će biti znakovni stream, a omogučit će nam unos podataka sa standardnog ulaza. Za unos jednog reda teksta sa standardnog ulaza koristit ćemo metodu readLine () klase BufferedReader. Ispis podataka na standardni izlaz znatno je jednostavniji. Ispis nam omogućavaju metode: public void print ( String s ) – ispisuje string s na standardni izlaz i točku umetanja (kursor) ostavlja u istom redu, tako da sljedeći ispis započinje neposredno iza ispisanog stringa public void println ( String s ) – ispisuje string s na standardni izlaz i točku umetanja (kursor) premješta u novi red, tako da sljedeći ispis započinje u novom redu. Primjer 12 – 1: Napišimo konzolni program koji će unositi dva broja sa standardnog ulaza i ispisivati njihov zbroj na standardni izlaz.

Rješenje: import java . io .*; public class Zbroj {

public static void main ( String [] s) { try { BufferedReader br = new BufferedReader ( new

InputStreamReader ( System . in )); String tmp; System . out . print ("Unesi prvi broj: "); tmp = br. readLine (); int a = Integer . parseInt (tmp); System . out . print ("Unesi drugi broj: "); tmp = br. readLine (); int b = Integer . parseInt (tmp); int c = a + b; System . out . println ("Zbroj brojeva " + a + " i " + b + " je " + c); } catch ( Exception e) { System . out . println (e. getMessage ()); } } }

Dani program ćemo izvršiti na sljedeći način:

− pokrenut ćemo komandni prompt, najlakše ćemo to napraviti tako da kliknemo na gumb Start, te odaberemo Run. U okvir koji se pojavi upišemo cmd te kliknemo na gumb OK, otvorit će se komandni prompt, kao na slici 12 – 2.

Page 138: Java i objektno orijentirano programiranje

138

Slika 12 – 2: Komandni prompt

− premjestimo se na disk i u mapu gdje nam se nalazi klasa Zbroj, npr, ako se nalazi u D:\Java pisat ćemo: >d: >cd Java

− upisat ćemo: >java Zbroj

Napomena: Ovdje je bitno voditi računa o velikim i malim slovima kod imena klase. Ako se npr. klasa zove Zbroj , a mi smo upisali npr. java zbroj , doči će do greške.

− unosit ćemo podatke kako se od nas traži

Slika 12 – 3: Izvršavanje programa Zbroj iz komandnog prompta

Page 139: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

139

Tekstualne datoteke U nastavku ćemo naučiti kako rezultate obrade, odnosno podatke općenito spremiti u datoteke te ih naknadno pročitati i s njima raditi. Za čitanje i pisanje podataka u datoteke postoji nekoliko klasa, mi ćemo koristiti sljedeće:

− FileReader – za učitavanje podataka iz datoteke − FileWriter – za spremanje podataka u datoteku.

Čitanje podataka iz datoteka Kao što smo već rekli za čitanje podataka iz tekstualnih datoteka koristit ćemo klasu FileReader . Prilikom kreiranja instance klase FileReader kao parametar konstruktora možemo proslijediti puni naziv datoteke iz koje ćemo čitati podatke (uključujući i put do datoteke). U tom slučaju će kreiranje instance klase FileReader imati sljedeći oblik:

FileReader fin = new FileReader ("naziv_datoteke")

npr. ako je datoteka spremljena na disku D pod nazivom podaci.txt, tada će konstruktor imati oblik: FileReader fin = new FileReader ( "d:\\podaci.txt" );

Napomena: Primijetimo da smo kod naziva datoteke koristili \\ a ne \ koji inače koristimo za označavanje puta do neke mape. Razlog tome jest činjenica da se znak \ koristi za označavanje posebnih znakova (vidi poglavlje 2.). Da bismo mogli čitati podatke iz neke datoteke ta datoteka uistinu mora postojati na definiranoj lokaciji. Ukoliko datoteka ne postoji pojavit će se odgovarajuća greška. Kako bismo izbjegli pojavljivanje grešaka dio programa koji čita podatke iz datoteke uvijek ćemo staviti u try/catch blok. FileReader je znakovni stream, te ćemo stoga za čitanje jednog znaka koristit metodu read () . Svaki puta kada se pozove, metoda read () iz datoteke pročita sljedeći znak i vraća njegovu odgovarajuću cjelobrojnu vrijednost (kôd). Kôd znaka ćemo konvertirati u znak tako da napravimo konverziju cjelobrojnog tipa (int ) u znakovni (char ), odnosno da napravimo cast tipova. Primjer 12 – 2: Napišimo program koji će kreirati prozor s jednim okvirom za tekst. Učitavanjem programa se u okvir za tekst treba prepisati tekst iz tekstualne datoteke tekst.txt. Rješenje: import javax.swing.*; import java.awt.*; import java.io.*; public class Prijepis extends JFrame { private final int sirina = 220;

Page 140: Java i objektno orijentirano programiranje

140

private final int visina = 100; private Container c; private JTextField t; public Prijepis() { setTitle ("Prijepis"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null ); String s = ""; int i; try { FileReader fin = new FileReader ("d:\\tekst.txt"); do { i = fin. read (); s = s + ( char ) i; } while (i != -1); } catch ( Exception e) { s = ("Dokument ne postoji"); } t = new JTextField (); t. setSize (200, 25); t. setLocation (5, 20); t. setText (s); c. add (t); setVisible ( true ); } public static void main ( String [] s) { Prijepis p = new Prijepis (); } } Ukoliko smo u tekstualni dokument text.txt upisali sljedeći sadržaj:

pokretanjem programa ćemo na ekranu dobiti sljedeće:

Page 141: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

141

Čitanje teksta iz ulazne datoteke znak po znak nije nešto što će nas učiniti sretnim, puno više bi nas usrećila mogućnost čitanja riječi po riječi ili čitavog retka iz datoteke. U tu svrhu ćemo i ovdje koristiti klasu BufferedReader i njenu metodu readLine () , koja vraća string koji sadrži učitani redak iz datoteke. Slično kao kod standardnog unosa, konstruktoru klase BufferedReader proslijedit ćemo parametar koji je tipa FileReader a predstavlja dokument iz kojeg ćemo čitati podatke. Primjer 12 – 3: Izmijenimo prethodni primjer (12 – 2) tako da pročita cijeli redak te pročitani string zapiše u odgovarajući okvir za tekst. Rješenje: import javax.swing.*; import java.awt.*; import java.io.*; public class Prijepis extends JFrame { private final int sirina = 220; private final int visina = 100; private Container c; private JTextField t; public Prijepis() { setTitle ("Prijepis"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null ); String s = ""; try { FileReader fin = new FileReader ("d:\\tekst.txt"); BufferedReader redak = new BufferedReader (fin); s = redak. readLine (); } catch ( Exception e) { s = ("Dokument ne postoji"); } t = new JTextField (); t. setSize (200, 25); t. setLocation (5, 20); t. setText (s); c. add (t); setVisible ( true ); } public static void main ( String [] s) {

Page 142: Java i objektno orijentirano programiranje

142

Prijepis p = new Prijepis (); } } Napomena: Budući da objekt fin, koji je instanca klase FileReader koristimo samo kao parametar konstruktora klase BufferedReader , ovdje smo, kao što smo to radili kod standardnog unosa, mogli izostaviti njegovo kreiranje. Stoga smo dio programa: FileReader fin = new FileReader ("d:\\tekst.txt"); BufferedReader redak = new BufferedReader (fin);

mogli zamijeniti sa: BufferedReader redak = new BufferedReader ( new FileReader ("d:\\tekst.txt" ));

Spremanje podataka u datoteke Za spremanje podataka u tekstualne dokumente koristit ćemo klasu FileWriter . Slično kao i kod učitavanja podataka i ovdje ćemo koristiti još jednu pomoćnu klasu PrintWriter . Za upis podataka u tekstualne datoteke, slično kao i za upsis na standardni izlaz, koristit ćemo metode print ( String s) i println ( String s) . Jedan od konstruktora klase PrintWriter ima parametar tipa FileWriter , koji predstavlja dokument u koji upisujemo podatke. Za razliku od čitanja dokumenata gdje je neophodno morao postojati dokument iz kojeg čitamo podatke, prilikom pisanja podataka dokument ne mora nužno postojati i u tom će se slučaju kreirati automatski, tj. kreirat ćemo ga kreiranjem instance klase FileWriter . Da bismo podatke koje smo upisali u dokument uistinu i spremili u taj dokument moramo pozvati metodu close () nad objektom tipa PrintWriter . Primjer 12 – 4: Izmijenimo prethodni primjer (12 – 3) tako da mu dodamo još jedan gumb Spremi klikom na koji će se tekst iz tekstualnog okvira spremiti u tekstualni dokument. Rješenje: import javax.swing.*; import java.awt.*; import java.io.*; import java.awt.event.*; public class Prijepis extends JFrame implements ActionListener { private final int sirina = 220; private final int visina = 150; private Container c; private JTextField t; private JButton b; public Prijepis() { setTitle ("Prijepis"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE);

Page 143: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

143

c = getContentPane (); c. setLayout ( null ); String s = ""; try { FileReader fin = new FileReader ("d:\\tekst.txt"); BufferedReader redak = new BufferedReader (fin); s = redak. readLine (); } catch ( Exception e) { s = ("Dokument ne postoji"); } t = new JTextField (); t. setSize (200, 25); t. setLocation (5, 20); t. setText (s); c. add (t);

b = new JButton (); b. setText ("Spremi"); b. setSize (200, 25); b. setLocation (5, 50); b. addActionListener ( this ); c. add (b); setVisible ( true ); } public void actionPerformed ( ActionEvent e) { if (e. getSource () == b) spremi (); } public void spremi () { try { FileWriter fout= new FileWriter ("d:\\tekst.txt"); PrintWriter pw = new PrintWriter (fout); pw. print (t.getText ()); pw. close (); } catch ( Exception e) { t. setText ("Ne mogu spremiti dokument"); } } public static void main ( String [] s) { Prijepis p = new Prijepis (); } } Napomena: Slično kao i kod upisivanja podataka u dokument, sljedeći dio koda: FileWriter fout = new FileWriter ("d:\\tekst.txt");

Page 144: Java i objektno orijentirano programiranje

144

PrintWriter pw = new PrintWriter (fout);

mogli smo zamijeniti sa: PrintWriter pw = new PrintWriter ( new FileWriter ("d:\\tekst.txt" ));

Page 145: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

145

13

Dijaloški prozori

� Dijaloški prozori za otvaranje/spremanje dokumenata

� Poruke, potvrde i jednostavan unos � Klasa Color i odabir boja � Klasa Font

Page 146: Java i objektno orijentirano programiranje

146

Dijaloške prozore svakodnevno susrećemo u radu s računalom. Npr. želimo li spremiti neki dokument u Wordu otvorit će nam se dijaloški prozor:

Slika 13 – 1: Prozor za spremanje dokumenata u OS Windows

Nadalje, želimo li npr. izaći iz Worda, a da prije toga nismo spremili napisani dokument otvorit će nam se dijaloški prozor:

Slika 13 – 2: Dijaloški prozor MS Worda

Dijaloški prozori su u stvari već gotovi prozori za neke često korištene radnje (spremanje dokumenata, otvaranje dokumenata, ispisivanje kratkih poruka,...).

Page 147: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

147

Dijaloški prozori za otvaranje/spremanje dokumenata Dijaloške prozore za otvaranje i spremanje dokumenata kreirat ćemo posebnom klasom JFileChooser . Metode klase JFileChooser , koje ćemo najviše koristiti su: public int showOpenDialog (Component c) – otvara dijaloški prozor za otvaranje dokumenta. Parametar c odnosi se na matičnu komponentu dijaloškog prozora i mi ćemo tu uvijek pisati this. Vrijednost koju vraća ova metoda je neka od cjelobrojnih konstanti klase JFileChooser : - JFileChooser .CANCEL_OPTION – ako je pritisnut gumb Cancel - JFileChooser .APPROVE_OPTION – ako je pritisnut gumb OK - JFileChooser .ERROR_OPTION – ako je došlo do greške public int showSaveDialog (Component c) – otvara dijaloški prozor za spremanje dokumenta. public File getSelectedFile () – vraća odabrani dokument. File je posebna klasa u Javi. Dvije metode klase File koje ćemo najčešće koristiti su: public String getName () – vraća naziv dokumenta public String getPath () – vraća puno ime dokumenta uključujući i put do dokumenta. Primjer 13 – 1: Napišimo program koji će kreirati prozor s tri okvira za tekst i dva gumba. U okvire za tekst će se unositi ime, prezime te starost osobe, dok će na gumbima pisati Spremi i Otvori. Klikom na gumb Spremi treba se otvoriti dijaloški prozor u kojem će se odabrati ime dokumenta pod kojim će se spremiti podaci, a klikom na gumb Save dijaloškog prozora podaci će se spremiti u odabrani dokument (svaki podatak u svoj red). Klikom na gumb Otvori treba se otvoriti dijaloški prozor za odabir dokumenta, a odabirom dokumenta će se podaci iz prva tri njegova reda upisati u odgovarajuće okvire za tekst na prozoru. Rješenje: import javax.swing.*; import java.awt.*; import java.io.*; import java.awt.event.*; public class SOPodaci extends JFrame implements ActionListener { private final int sirina = 280; private final int visina = 210; private Container c; private JTextField t1, t2, t3; private JLabel l1, l2, l3; private JButton b1, b2; public SOPodaci() { setTitle ("Podaci"); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null );

Page 148: Java i objektno orijentirano programiranje

148

l1 = new JLabel (); l1. setText ("Ime"); l1. setSize (100, 25); l1. setLocation (5, 5); c. add (l1); t1 = new JTextField (); t1. setSize (150, 25); t1. setLocation (110, 5); c. add (t1); l2 = new JLabel (); l2. setText ("Prezime"); l2. setSize (100, 25); l2. setLocation (5, 40); c. add (l2); t2 = new JTextField (); t2. setSize (150, 25); t2. setLocation (110, 40); c. add (t2); l3 = new JLabel (); l3. setText ("Starost"); l3. setSize (100, 25); l3. setLocation (5, 75); c. add (l3); t3 = new JTextField (); t3. setSize (150, 25); t3. setLocation (110, 75); c. add (t3); b1 = new JButton (); b1. setText ("Otvori"); b1. setLocation (5, 120); b1. setSize (125, 25); b1. addActionListener ( this ); c. add (b1); b2 = new JButton (); b2. setText ("Spremi"); b2. setLocation (135, 120); b2. setSize (125, 25); b2. addActionListener ( this ); c. add (b2); setVisible ( true ); } public void actionPerformed ( ActionEvent e) { if (e. getSource () == b1) otvori (); else spremi (); } public void spremi () {

Page 149: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

149

try { JFileChooser fc = new JFileChooser (); if (fc. showSaveDialog ( this ) == JFileChooser . APPROVE_OPTION) { String fname =fc. getSelectedFile (). getPath (); FileWriter fout = new FileWriter (fname); PrintWriter pw = new PrintWriter (fout); pw. println (t1. getText ()); pw. println (t2. getText ()); pw. println (t3. getText ()); pw. close (); } } catch ( Exception e) { } } public void otvori () { try { JFileChooser fc = new JFileChooser (); if (fc. showOpenDialog ( this ) == JFileChooser . APPROVE_OPTION) { String fname = fc. getSelectedFile (). getPath (); FileReader fin = new FileReader (fname); BufferedReader redak = new BufferedReader (fin); t1. setText (redak. readLine ()); t2. setText (redak. readLine ()); t3. setText (redak. readLine ()); } } catch ( Exception e) { } } public static void main ( String [] s) { SOPodaci p = new SOPodaci (); } }

Poruke, potvrde i jednostavan unos Kreiranje dijaloških prozora koji će korisniku omogućiti unos vrijednosti, ispisati poruke upozorenja,... omogućit će nam metode klase JOptionPane . Klasa JOptionPane ima ukupno četiri metode za prikaz dijaloških prozora:

− showMessageDialog − showConfirmDialog − showInputDialog − showOptionDialog

Sve navedene metode su static metode, što znači da ćemo ih pozivati na razini klase JOptionPane.

Page 150: Java i objektno orijentirano programiranje

150

Navedene metode dolaze s nekoliko opcionalnih parametara:

− roditeljska komponenta – naziv prozora koji iz kojeg se otvara dijaloški prozor, mi ćemo najčešće kao ovaj parametar koristiti this;

− poruka – tekst poruke koja će biti ispisana na prozoru; − naslov – tekst koji će se ispisati na naslovnoj traci prozora; − opcije – jedna od sljedečih kombinacije gumba:

o DEFAULT_OPTION o YES_NO_OPTION o YES_NO_CANCEL_OPTION o OK_CANCEL_OPTION

− sličica poruke – jedna od sljedećih sličica:

o - QUESTION_MESSAGE

o - INFORMATION_MESSAGE

o - WARNING_MESSAGE

o - ERROR_MESSGE − niz objekata – najčešće se radi o stringovima koji su u stvari tekstovi na gumbima kod

nekih vrsta dijaloških prozora; − označeni objekt – jedan od objekata, iz prijašnjih parametara, koji će biti inicijalno označen.

Nazivi parametara opcija i sličica prozora su u stvari cjelobrojne konstante klase JOptionPane. Kao i same metode, ove parametre ćemo pozivati direktno iz klase, dakle ispred imena parametra pisat ćemo JOptionPane. Metoda showMessageDialog ShowMessageDialog metodu koristit ćemo kada za kreiranje najjednostavnijeg oblika dijaloškog prozora, u slučajevima kada korisniku želimo prikazati prozor s jednostavnom porukom (obavijest, upozorenje, poruka o grešci,...). Na prozoru se uvijek nalazi samo jedan gumb i to je gumb OK. Metodu možemo pozvati na više najčina, najčešće korišteni su: void showMessageDialog (Component roditeljska_komponenta, Object poruka ); ili void showMessageDialog (Component roditeljska_komponenta, Object poruka, String naslov, int opcije, int sli čica_poruke ); Kao što je i za pretpostaviti u prvom ćemo slučaju dobiti prozor kojem ćemo specificirati samo poruku, dok će sličica i naslov biti inicijalni. Naslov će u tom slučaju biti Message, dok će sličica

poruke biti . Npr. izvršavanjem metode:

Page 151: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

151

JOptionPane . showMessageDialog ( this , "Ja sam dijaloski prozor"); na ekranu će biti prikazan sljedeći prozor:

Primijetimo da smo isti prozor na ekranu mogli dobiti i na sljedeći način: JOptionPane . showMessageDialog ( this , "Ja sam dijaloski prozor", "Message", JOptionPane .INFORMATION_MESSAGE); Metoda showConfirmDialog Metodu showConfirmDialog koristimo u slučajevima kada ćelimo da korisnik potvrdi ili poništi neku akciju. Npr. kod brisanja dokumenta u operativnom sustavu Windows pojavit će se sljedeći gumb:

Slika 13 – 3: Dijaloški prozor Confirm

Ovdje se radi o tzv. Confirm prozoru. Ukoliko korisnik klikne na gumb Yes dokument će biti izbrisan, inače, ukoliko klikne na gumb No dijaloški prozor će se zatvoriti a dokument neće biti izbrisan. Kao i metoda showMessageDialog i showConfirmDialog može dolaziti s različitim brojem parametara, najčešće varijante poziva ove metode su: int showConfirmDialog (Component roditeljska_komponenta, Object poruka ); ili int showMessageDialog (Component roditeljska_komponenta, Object poruka, String naslov, int opcije ); ili

Page 152: Java i objektno orijentirano programiranje

152

int showMessageDialog (Component roditeljska_komponenta, Object poruka, String naslov, int opcije, int sli čica_poruke );

Inicijalni naslov ovog dijaloškog prozora je: Select an option; inicijalna sličica poruke je: , dok će, ako drugačije nije odreñeno na prozoru biti tri gumba: Yes, No i Cancel. Budući da ovaj dijaloški prozor nudi korisniku da odabere jednu od opcija, klikom na odgovarajući gumb, razumno je postaviti si pitanje: a kako ćemo znati na koji je gumb korisnik kliknuo? U tu svrhu metoda showMessageDialog vraća cjelobrojnu vrijednost koja je u stvari oznaka gumba na koji je korisnik kliknuo. Već smo prije rekli da je svaka kombinacija gumba koja se može pojaviti na prozoru (YES_NO_OPTION,...) u stvari cjelobrojna konstanta. Isto tako postoje cjelobrojne konstante za gumbe:

OK OK_OPTION 0 Yes YES_OPTION 0 No NO_OPTION 1

Cancel CANCEL_OPTION 2 Tablica 13 – 1: Gumbi i odgovarajuće konstante

To znači da ćemo metodu showConfirmDialog u programima pozivati npr. na sljedeći način: int n = JOptionPane .showConfirmDialog ( this , "Jeste li sigurni?"); if (n == JOptionPane .YES_OPTION) //kod ako je pritisnut gumb OK else if (n == JOptionPane .NO_OPTION) //kod ako je pritisnut gumb NO else //kod ako je pritisnut gumb Cancel

Metoda showInputDialog Metodu showInputDialog koristit ćemo kada od korisnika tražimo unos neke jednostavne vrijednosti. Za razliku od svih dosadašnjih dijaloških prozora, ovaj prozor ima još i okvir za unos teksta.

Slika 13 – 4: Dijaloški prozor input

Page 153: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

153

Kao i sve prijašnje, metoda showInputDialog je preopterećene (overloadana) te dolazi u više varijanti, najčešće su: String showInputDialog (Component roditeljska_komponenta, Object poruka ); String showInputDialog (Component roditeljska_komponenta, Object poruka, String naslov, int sli čica_poruke ); String showInputDialog (Component roditeljska_komponenta, Object poruka, String tekst ); pri čemu je tekst inicijalna poruka koja će se pojaviti u okviru za tekst Hm, a što je s tekstom koji smo unijeli u okvir za tekst? Imalo bi smisla nekako doći do njega. U tu svrhu metoda showInputDialog vraća string i taj string je u stvari tekst koji je unesen u okvir za tekst. Stoga ćemo ovu metodu najčešće koristiti na sljedeći način: String poruka = JOptionPane.showInputDialog ( this , "Unesite broj svog teku ćeg ra čuna:"); Metoda showOptionDialog Ova metoda programeru omogućava prilagoñavanje izgleda prozora. Tako je moguće na gumbe dodati vlastiti tekst, izmijeniti sličicu prozora,... Jedina varijanta poziva ove metode je: int showOptionDialog (Component roditeljska_komponenta, Object poruka, String naslov, int opcije, int sli čica_poruke, ImageIcon proizvoljna_sli čica, Object[] proizvoljne_opcije, Object inicijalna_opcija ); Prvih šest parametara su standardni parametri i susreli smo ih kod prethodnih vrsta dijaloških prozora, dok preostala 3 redom predstavljaju: • proizvoljna sličica – ukoliko nam niti jedna od postojećih sličica poruke

(QUESTION_MESSAGE, ERROR_MESSAGE, INFORMATION_MESSAGE, WARNING_MESSAGE) ne odgovara, možemo kao sličicu poruke postaviti neku svoju proizvoljnu sličicu. Slčica je u stvari objekt tipa ImageIcon . Jedan od konstruktora klase ImageIcon ima parametar ime slike, koju želimo dodijeliti objetku. Ime slike obuhvaća čitav put do slike, npr. D:\Java\slika.jpg;

• proizvoljne opcije – na ovaj način je moguće definirati vlastiti tekst na gumbima. Proizvoljne opcije su u stvari niz objakata, koji su u stvari stringovi koji predstavljaju tekstove koji će biti ispisani na gumbima i to onim redom kako su poslagani u nizu. Gumbova će na dijaloškom prozoru biti onoliko koliko ima proizvoljnih opcija;

• inicijalna opcija – predstavlja proizvoljnu opciju koja će biti inicijalno označena. Metoda showOptionDialog vraća redni broj gumba na kojeg je korisnik kliknuo.

Page 154: Java i objektno orijentirano programiranje

154

Npr. izvršavanjem sljedećeg dijela koda: String [] tmp = {"Da", "Ne", "Ne znam"}; ImageIcon ic = new ImageIcon ("bluej-icon.gif"); int n = JOptionPane . showOptionDialog ( this , "Jeste li sigurni?", "Dijaloški prozor", JOptionPane .YES_NO_OPTION, JOptionPane .ERROR_MESSAGE, ic, tmp, tmp[1]);

rezultirat će sljedećim dijaloškim prozorom:

Slika 13 – 5: Prilagoñeni dijaloški prozor

Kao što možemo primijetiti tekstovi na gumbima su definirani u nizu tmp koji ima tri elementa: stringove Da, Ne i Ne znam. Sličicu poruke smo definirali u objektu ic , koji je instanca klase ImageIcon . Sličica se nalazi u direktoriju u kojem se nalazi i aplikacija, stoga pri njenom kreiranju nije potrebno navoditi put do nje. Posljednji parametar metode showOptionDialog je tmp[1] , što znači da će inicijalno biti označen drugi gumb (gumb na kojem piše Ne). Klikne li korisnik na gumb Da metoda će vratiti 0, klikom na Ne vratit će 1, dok će klikom na Ne znam metoda vratiti 2. Klikne li korisnik na gumb Close (u gornjem desnom vrhu prozora), metoda će vratiti -1.

Klasa Color i odabir boja Svaka boju na ekranu moguće je dobiti kombinacijom triju osnovnih boja: crvene, zelene i plave. Miješanjem odreñenih količina ovih triju boja možemo dobiti milijune različitih nijansi boja. Količina svake od ovih triju boja je cijeli broj izmeñu 0 i 255. Za sada ćemo predstavljati boju kao trojku brojeva (r, g, b), pri ćemu je: r – količina crvene boje; g – količina zelene boje; dok je b – količina plave boje. U tom slučaju će npr. (255, 0, 0) biti crvena boja (maksimalno crvene, ništa zelene, ništa plave), (255, 255, 0) – žuta boja (kombinacija crvene i zelene), (0, 0, 0) – crna boja, (255, 255, 255) – bijela boja,... Za rad s bojama Java posjeduje klasu Color . Jedan od konstruktora klase Color je oblika: public Color (int r , int g, int b) – kreira instancu boje s količinom crvene boje r, zelene g i količinom plave boje b. Primjerice, sljedećom naredbom:

Page 155: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

155

Color col = new Color (0, 0, 255);

bit će kreiran objekt col koji će prestavljati plavu boju. Na ovaj način kreiran objekt (instanca) boje može se dodati večini elemenata grafičkog korisničkog sućelja (gumbima, labelama, okviru,...) kao pozadinska boja ili kao boja teksta, u tu svrhu večina elemenata grafičkog korisničkog sučelja ima sljedeće dvije metode: void setForeground (Color c) – definira boju teksta na elementu void setBackground (Color c) – definira boju pozadine elementa Osim na ovaj način, neke je boje moguće definirati i implicitno, navoñenjem imena boje. U stvari se radi o static konstantama definiranim u klasi Color . Definiranjem boje na ovaj način nije potrebno kreirati instancu klase Color već je boju moguće definirati s Color .konstanta , pri ćemu je konstanta jedna od sljedećih konstanti:

Color . black (0, 0, 0) Color . blue (0, 0, 255) Color .green (0, 255, 0) Color .cyan (0, 255, 255) Color .darkGray (64, 64, 64) Color .gray (128, 128, 128) Color .lightGray (192, 192, 192) Color .red (255, 0, 0) Color .magenta (255, 0, 255) Color .pink (255, 175, 175) Color .orange (255, 200, 0) Color .yellow (255, 255, 0) Color .white (255, 255, 255)

Tablica 13 – 2: Predefinirane konstante za neke boje Želimo li npr. zadati da je boja teksta na gumbu crvena, to možemo napraviti na sljedeći način: ... private JButton b; ... Color col = new Color (255, 0, 0); b. setForeground (col); ...

ili ... private JButton b; ... b. setForeground ( Color . red ); ... Kombinacijom količina crvene, zelene i plave boje, uistinu je moguće dobiti milijune boja, no na ovja način dobiti baš onu boju koju želimo, nije niti malo jednostavno. U tu svrhu postoji dijaloški prozor za odabir boja. Klasa koja omogućava kreiranje ovakvog dijaloškog prozora je JColorChooser . U osnovi nam treba samo jedna metoda ove klase, metoda showDialog ,.

Page 156: Java i objektno orijentirano programiranje

156

showDialog je static metoda klase JColorChooser , što znači da se poziva na razini klase. Metoda showDialog će kreirati dijaloški prozor za odabir boja i vratit će objekt tipa Color , koji predstavlja odabranu boju. Opći oblik metode showDialog je sljedeći: void showDialog (Component roditeljska_komponenta, Object naslov, Color inicijalna_boja ) ; Primjerice, izvršavanjem dijela programa: Color c = JColorChooser . showDialog ( this , "Odaberite boju", new Color (0, 0, 0));

na ekranu će se pojaviti dijaloški prozor:

Slika 13 – 6: Dijaloški prozor za odabir boja

Kao što možemo primijetiti: u naslovnoj traci prozora je tekst "Odaberite boju", koji smo definirali kao drugi parametar metode showDialog , dok je inicijalno odabrana crna boja, što je definirano trećim parametrom (new Color (0, 0, 0) ), koji u stvari predstavlja crnu boju.

Klasa Font Upravo smo naučili kako raditi s bojama, kako definirati boju teksta i pozadine na elementima GUI-a,... Razumno je zapitati se: kako definirati oblik ili veličinu znakova na nekom elementu? Naravno, programeri Jave su se pobrinuli i za to. Postoji posebna klasa Font kojom je moguće definirati veličinu, stil i oblik znakova. Konstruktor klase Font je sljedećeg oblika:

Page 157: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

157

public Font (String oblik, int stil, int veli čina ); oblik je neki od naziva fontova: Arial, Courier , Garamond,... stil znakova može biti bold, italic, plain ili kombinacija bold + italic. Za stilove su definirane posebne cjelobrojne konstante u klasi Font :

• BOLD • ITALIC • NORMAL

Navedene konstante su static, što znači da ih možemo pozivati na razini klase. Želimo li da nam znakovi budu podebljani i nakošeni, pisat ćemo: Font . BOLD + Font . ITALIC . veli čina je prirodan broj koji predstavlja veličinu znakova u pixelima. Npr. font čija će veličina biti 20, stil bold a oblik znakova Arial definirat ćemo na sljedeći način: Font f = new Font ("Arial", Font . BOLD, 20);

Font nad nekim elementom GUI-a definirat ćemo metodom setFont . public void setFont (Font f );

Page 158: Java i objektno orijentirano programiranje

158

1. Napiši program koji će na ekranu crtati prozor kao na slici. Na početku program treba "zamisliti" slučajan prirodan broj do 100. Unosom broja u okvir za tekst i klikom na gumb OK treba se pojaviti dijaloški prozor s porukom da je traženi broj veći ili manji od unesenog, odnosno s porukom u kojem je pokušaju broj pogoñen.

2. Napiši program koji će na ekranu iscrtavati prozor koji će se sastojati od dva gumba (“O

programu” i “Izmijeni podatke”) te jedne labele:

a) Prilikom učitavanja programa se u labelu treba ispisati tekst: Ovo je x. pokretanje programa, pri čemu je x broj koji se učitava iz tekstualnog dokumenta (brojac.txt) i prilikom svakog pokretanja programa se povećava za 1.

b) Klikom na gumb O programu u dijaloškom prozoru

se trebaju ispisati podaci o autoru programa te verziji, a koji se nalaze u dokumentu podaci.txt. Ukoliko dokument ne postoji treba ispisati odgovarajuću grešku u dijaloškom prozoru.

c) Klikom na gumb Izmijeni podatke trebaju se otvoriti dva dijaloška okvira za unos teksta

(Autor i Verzija) te ukoliko su u dijaloške okvire uneseni podaci oni se trebaju spremiti u dokument podaci.txt. Ukoliko podaci nisu uneseni treba ispisati poruku o greški.

Page 159: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

159

14

Klasa Graphics

� Metode klase Graphics � Crtanje grafova funkcija

Page 160: Java i objektno orijentirano programiranje

160

Crtanje jednostavnih grafičkih elemenata, kao što su linije, elipse, pravokutnici,... omogućit će nam metode klase Graph . Klasa Graph sadržana je u paketu java.awt.* . Sve što ćemo na prozoru crtati crtat ćemo u jednoj posebnoj metodi čije je zaglavlje oblika:

public void paint ( Graphics g)

Kao što možemo primijetiti ova metoda ima kao parametar objekt g tipa Graphics , koji možemo zamisliti kao pozadinu na kojoj ćemo crtati. Nad objektom tipa Graphics ćemo pozivati odgovarajuće metode za crtanje te ćemo na taj način dobivati željene slike. Metodu paint () nije potrebno eksplicitno pozivati nigdje u programu. Program sam prilikom pokretanja traži postoji li metoda paint () , te ukoliko postoji izvršava ju. Prostor za crtanje zauzima cijelu površinu ekrana. Prostor za crtanje sastoji se od mnoštva pixela (točkica). Svaki pixel ima svoje koordinate. Pixel koji se nalazi u gornjem lijevom vrhu prozora ima koordinate (0, 0), dok pixel u donjem desnom kutu ima koordinate (sirina_prozora – 1, visina_prozora - 1). Na prozoru na kojem crtamo moguće je imati i sve ostale elemente grafičkog korisničkog sučelja. Jedini problem je što ne možemo odijeliti prozor na dio za elemente grafičkog sučelja i na dio za crtanje. Stoga nam se može dogoditi da npr. linije prelaze preko gumba,... Stoga je najbolje, ukoliko je izvedivo, na prozoru na kojem crtamo ne koristiti ostale elemente grafičkog korisničkog sučelja. Svaki dogañaj na prozoru (resize, minimize,...) uzrokovat će ponovno izvršavanje metode paint () . Isto tako je metodu paint () moguće pozvati i u svakom drugom trenutku, npr. kao odgovor na neki dogañaj na nekom od elemenata grafičkog korisničkog sučelja, ako ih ipak imamo na prozoru. U tom slučaju ćemo metodu paint () pozvati naredbom repaint () . Napomena: repaint () nikada nećemo pozivati u samoj metodi paint () . To bi u stvari značilo da u metodi pozivamo samu metodu i tu bi ušli u beskonačno pozivanje.

Page 161: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

161

Metode klase Graphics Najčešće metode za crtanje su:

public void drawLine ( int x1 , int y1 , int x2 , int y2 )

Ova metoda crta liniju od točke (x1, y1) do (x2, y2) ekrana.

public void drawRect ( int x , int y, int s, int v )

Crta pravokutnik čiji je gornji lijevi vrh u točki ekrana s koordinatama (x, y) dok mu je širina s a visina v.

Slika 14 – 1: Pravokutnik nacrtan metodom drawLine (x, y, s, v)

public void drawOval ( int x , int y, int s, int v )

Crta elipsu unutar nevidljivog pravokutnika kojem je gornji lijevi vrh u točki s koordinatama (x, y), dok mu je širina s a visina v.

Slika 14 – 2: Metoda drawOval ()

public void drawArc ( int x , int y, int s, int v, int pk, int zk )

Crta dio luka elipse s početnim kutom pk do kuta zk.

(x, y) s

v

(x, y) s

v

Page 162: Java i objektno orijentirano programiranje

162

Slika 14 – 3: Metoda drawArc ()

public void drawPolygon ( int[] x , int[] y, int n)

Crta poligon čiji su vrhovi točke s koordinatama (x[0], y[0]), (x[1], y[1]),... (x[n - 1], y [n - 1]) , pri čemu je n broj vrhova poligona.

Slika 14 – 4: Metoda drawPolygon ()

Navedene metode, osim drawLine () crtaju samo rub odgovarajućeg lika. Analogno njima postoje metode koje crtaju odgovarajuće likove ispunjene bojom: public void fillRect (int x, int y, int s, int v ) – crta ispunjeni pravokutnik public void fillOval (int x, int y, int s, int v ) – crta ispunjenu elipsu public void fillArc (int x, int y, int s, int v, int pk, int zk ) – crta ispunjeni dio elipse public void fillPolygon (int[] x, int[] y, int n ) – crta ispunjeni poligon Rekli smo kako crtati likove te kako crtati ispunjene likove, bilo bi zgodno znati kako definirati boju takvih likova. Boju bilo kojeg lika koji ćemo crtati definirat ćemo neposredno prije crtanja lika metodom:

public void setColor ( Color b)

Postoji još jedna metoda klase Graphics , koju do sada nismo spomenuli, a koju ćemo često koristiti u svojim programima. Radi se o metodi:

public void drawString (String s, int x, int y )

Kao što je i za pretpostaviti, ova će metoda "crtati" string s na grafičkom ekranu. Možemo zamisliti da je string zapisan unutar nevidljivog pravokutnika i u tom slučaju gornji lijevi vrh tog pravokutnika ima koordinate (x, y).

(x[0], y[0])

(x[1], y[1])

(x[2], y[2]) (x[3], y[3])

Page 163: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

163

Slika 14 – 5: Metoda drawString () Tekstu koji na ovaj način ispisujemo, slično kao i tekstu koji ispisujemo na ostalim elementima grafičkog korisničkog sučelja moguće je definirati oblik, veličinu,... metodom setFont (Font f) . Primjer 14 – 1: Napišimo program koji će na ekranu nacrtati olimpijske krugove.

Rješenje: Na prvi pogled bismo se mogli zapitati: Kakav je problem ovo nacrtati? Uistinu kada bismo htjeli napraviti 5 kružnica u odgovarajućim bojama, na odgovarajućim mjestima, uistinu ne bi bilo nikakvih problema. Meñutim želimo li uistinu napraviti sliku što više nalik na gornju susrest ćemo se s nekoliko problema: − kao što možemo primijetiti ne radi se o kružnicama već o tzv. kružnim vijencima (prstenima); − kružni vijenci se meñusobno isprepliću; − ... Kako napraviti kružni vijenac u nekoj boji? Znamo da klasa Graphics nema niti jednu metodu kojom bismo to eksplicitno napravili. Dakle trebamo smisliti neki drugi način. Pa vrlo jednostavno: želimo li npr. napraviti crveni kružni vijenac, jednostavno ćemo nacrtati crveni krug, a zatim ćemo napraviti njemu koncentričan bijeli krug nešto manjeg radijusa. To bi bilo sasvim uredu, meñutim imajmo na umu da se naći krugovi isprepliću i da ćemo na taj način bijelim krugom obrisati i dio nekog drugog kruga. Dakle, ova ideja nam nije dobra. Drugi, ispravniji način bio bi sljedeći: kružnicu možemo dobiti i kao pravilni n-terokut gdje je n dovoljno velik. Već ako stavimo da je n npr. 230, dobiveni 230-kut će biti potpuno nalik na kružnicu. Zašto n-terokut? Pa stoga što znamo da klasa Graph ima metodu fillPoly () koja crta ispunjeni n-terokut. Mi bismo dakle htjeli napraviti n-terokut koji će u stvari izgledati kao kružni vijenac.

Ovo je neki tekst (x, y)

Page 164: Java i objektno orijentirano programiranje

164

Da bismo nacrtali ovakav n-terokut, metodom fillPoly () trebaju nam koordinate vrhova n.terokuta, a za to će nam trebati malo matematike:

Dakle, ako je (xs, ys) "središte" n-terokuta, tada ćemo vrhove dobivati tako da mijenjamo veličinu kuta α, te će točka (x, y) koja je vrh n-terokuta u tom slučaju imati koordinate: x = xs + r * cos (α) y = ys – r * sin (α) Sada samo u stanju nacrtati n-terokut, meñutim, zaboravili smo na još jedan problem, a to je činjenica da se kružni vijenci preklapaju. Upravo zbog toga nećemo moči sliku napraviti pomoću čitavih kružnih vijenaca. Stoga ćemo napisati metodu koja će pomoću n-terokuta crtati samo dio kružnog vijenca.

(xs, ys)

(x, y)

α

r

r * cos (α)

r * sin (α)

Page 165: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

165

Metoda koja će crtati dio kružnog vijenca, sa središtem u točki (xs, ys), radijusom veće kružnice r1, te radijusom manje kružnice r2 od kuta pk do kuta zk je: public void drawVijenac ( Graphics g, int xs, int ys, int r1, int r2, int pk, int zk) {

int [] x = new int [500]; int [] y = new int [500]; int i = 0, k = pk; //koordinate vrhova "ve ćeg" n-terokuta while (k <= zk) { x [i] = ( int ) (xs + Math.cos (k / 180.0 * Math.PI) * r1); y [i] = ( int ) (ys - Math.sin (k / 180.0 * Math.PI) * r1); i++; k += 2; } //koordinate vrhova "manjeg" n-terokuta k-=2; while (k >= pk) { x [i] = ( int ) (xs + Math . cos (k / 180.0 * Math . PI ) * r2); y [i] = ( int ) (ys - Math . sin (k / 180.0 * Math . PI ) * r2); i++; k -= 2; } g. fillPolygon (x, y, i);

} Nakon što smo napisali ovu metodu, samo crtanje tražene slike bit će jednostavno: import java.awt.*; import javax.swing.*; public class Olympic extends JFrame { public Olympic() { setTitle ("Olimpijski krugovi"); setSize (550, 350); setDefaultCloseOperation (EXIT_ON_CLOSE); setBackground ( Color . white ); setVisible ( true ); } public void drawVijenac ( Graphics g, int xs, int ys, int r1, int r2, int pk, int zk) { int [] x = new int [500]; int [] y = new int [500]; int i = 0, k = pk; while (k <= zk)

Page 166: Java i objektno orijentirano programiranje

166

{ x [i] = ( int ) (xs + Math . cos (k / 180.0 * Math . PI ) * r1); y [i] = ( int ) (ys - Math . sin (k / 180.0 * Math . PI ) * r1); i++; k += 2; } k-=2; while (k >= pk) { x [i] = ( int ) (xs + Math . cos (k / 180.0 * Math . PI ) * r2); y [i] = ( int ) (ys - Math . sin (k / 180.0 * Math . PI ) * r2); i++; k -= 2; } g. fillPolygon (x, y, i); } public void paint ( Graphics g) { g. setColor ( Color . blue ); drawVijenac (g, 150, 150, 52, 44, 0, 360); g. setColor ( Color . yellow ); drawVijenac (g, 205, 200, 52, 44, 0, 360); g. setColor ( Color . blue ); drawVijenac (g, 150, 150, 52, 44, -20, 20); g. setColor ( Color . black ); drawVijenac (g, 260, 150, 52, 44, 0, 360); g. setColor ( Color . yellow ); drawVijenac (g, 205, 200, 52, 44, 70, 90); g. setColor ( Color . green ); drawVijenac (g, 315, 200, 52, 44, 0, 360); g. setColor ( Color . black ); drawVijenac (g, 260, 150, 52, 44, -20, 20); g. setColor ( Color . red ); drawVijenac (g, 370, 150, 52, 44, 0, 360); g. setColor ( Color . green ); drawVijenac (g, 315, 200, 52, 44, 70, 90); } public static void main (String[] s) { Olympic ol = new Olympic (); } }

Napomena: Primijetimo da je metoda drawVijenac () kao parametar izmeñu ostaloga imala i objekt tipa Graphics . Naime, radi se o činjenici objekt g, instanca klase Graphics postoji samo u metodi paint () . Da bismo mu mogli pristupiti iz neke druge metode, moramo ga toj metodi proslijediti kao parametar. Jeste li znali: Olimpijski krugove kao simbol olimpijskih igara kreirao je Baron Pierre de Coubertin 1913 godine. Pet krugova simboliziraju pet kontinenata na modernim olimpijskim igrama: Azija, Europa, Oceanija, Sjeverna Amerika i Južna Amerika. Zastava svake zemlje, s nekog od kontinenata, ima najmanje jednu od boja olimpijskih krugova. Boje krugova idući od lijeva na desno su: plava, žuta, crna, zelena i crvena.

Page 167: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

167

Crtanje grafova funkcija Sa grafom funkcije po prvi se puta susrećemo već u matematici viših razreda osnovne škole. U nastavku ćemo naučiti kako crtati grafove funkcija u Javi. Kao što znamo, graf funkcije f u pravokutnom koordinatnom sustavu je skup točaka (x, f (x)), pri čemu je x bilo koja točka domene, dok je f (x) vrijednost funkcije f u točki x. Promotrimo to sa aspekta programiranja. Mi bismo mogli graf funkcije prikazivati u jednom prozoru. Središte toga prozora bilo bi ishodište koordinatnog sustava. Nadalje nam trebaju koordinatne osi, što mogu biti dvije dužine paralelne s rubovima prozora te nam treba jedinična duljina, za koju možemo uzeti da je npr. 20 pixela. Kao što smo rekli graf funkcije f je skup točaka (x, f (x)) pravokutnog koordinatnog sustava. Dakle, da bismo u našem koordinatnom sustavu na prozoru, nacrtali graf funkcije, uzimat ćemo neke točke iz domene funkcije (točke s x osi) i za odgovarajuću točku domene računat ćemo vrijednost funkcije te ćemo na prozoru nacrtati točku. U rečenom treba uočiti nekoliko bitnih činjenica:

− nema smisla uzimati bilo koje točke domene (točke s x osi), treba uzimati samo one koje su vidljive na ekranu;

− što uzmemo više točaka domene (s vidljivog dijela ekrana) to će graf funkcije biti precizniji;

− rekli smo da je ishodište koordinatnog sustava, točka s koordinatama (0, 0) središte ekrana, a s druge strane znamo da se točka prozora s koordinatama (0, 0) nalazi u gornjem lijevom kutu. Kako ćemo mi za crtanje koristiti metode klase Graphics, koje raspoznaju samo koordinate ekrana, a ne nikakvog našeg nacrtanog koordinatnog sustava, morat ćemo preračunavati koordinate. Isto tako bitno je voditi računa da je jedinična duljina na prozoru 1 pixel, a mi smo za jediničnu duljinu uzeli 20 pixela.

Razmotrimo malo posljednji problem te nañimo način na koji ćemo pretvarati koordinate našeg nacrtanog koordinatnog sustava u koordinatni sustav prozora. Radi ilustracije, zamislimo da prozor ima širinu i visinu 100 pixela. Želimo li koordinatni sustav na sredini ekrana, to znači da će ishodište tog sustava u stvari biti točka prozora s koordinatama (50, 50).

Page 168: Java i objektno orijentirano programiranje

168

Uzmimo npr. točku (1, 0) u nacrtanom koordinatnom sustavu, zanimaju nas koordinate te točke u koordinatnom sustavu prozora. Znamo da koordinate ishodišta koordinatnog sustava na prozoru imaju koordinate (50, 50), znači pomaknemo li se za jednu jediničnu dužinu, nacrtanog koordinatnog sustava, u stvari se pomičemo za 20 pixela. Dakle točka (1, 0) nacrtanog koordinatnog sustava će u koordinatnom sustavu prozora imati koordinate (70, 0). Lako se da zaključiti da će općenito točka s koordinatama (x, 0), našeg zamišljenog koordinatnog sustava u koordinatnom sustavu prozora imati koordinate (50 + x * 20). Nadalje, primijetimo da će npr. y koordinata točke (0, 1) nacrtanog koordinatnog sustava u koordinatnom sustavu prozora biti 50 – 20 pixela što iznosi 30. Dakle točka (0, 1) zamišljenog koordinatnog sustava će u koordinatnom sustavu prozora imati koordinate (0, 30), odnosno općenito će točka s koordinatama (0, y) u nacrtanom koordinatnom sustavu, imati koordinate (0, 50 – y * 20) u koordinatnom sustavu prozora. Općenito, neka je središte nacrtanog koordinatnog sustava točka s koordinatama (xs, ys) u koordinatnom sustavu prozora. Neka je jedinična dužina nacrtanog koordinatnog sustava 20 pixela, te neka je u njemu zadana točka s koordinatama (x, y). Točka (x, y) će u koordinatnom sustavu prozora u tom slučaju imati koordinate (xp, yp), pri čemu je:

xp = xs + 20 * x yp = ys – 20 * y

Primjer 14 – 2: Napišimo program koji će unositi parametre a, b i c funkcije f (x) = a sin (bx + c) , te će crtati graf funkcije u koordinatnom sustavu čije će središte biti oko sredine ekrana veličine 640x480 pixela.

(0, 0)

(0, 0)

Page 169: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

169

Rješenje: import javax.swing.*; import java.awt.*; public class GrafF extends JFrame {

private final int SIRINA = 640, VISINA = 480; private int a, b, c; public GrafF() { try { a = Integer . parseInt ( JOptionPane . showInputDialog (this,

"Parametar a")); } catch ( Exception e) { a = 1; } try { b = Integer . parseInt ( JOptionPane . showInputDialog (this, "Parametar b")); } catch ( Exception e) { b = 1; } try { c = Integer . parseInt ( JOptionPane . showInputDialog (this,

Page 170: Java i objektno orijentirano programiranje

170

"Parametar c")); } catch ( Exception e) { c = 0; } setTitle ("Graf funkcije f (x) = " + a + " sin (" + b + " x + " + c + ")"); setSize (SIRINA, VISINA); setDefaultCloseOperation (EXIT_ON_CLOSE); setBackground ( Color . white ); setVisible ( true ); }

private void xos ( Graphics g) { g. setColor ( Color . blue ); g. drawLine (0, VISINA / 2, SIRINA, VISINA / 2); for ( int i = 1; i < SIRINA / 20; i++) g. drawLine (i * 20, VISINA / 2 - 2, i * 20, VISINA / 2 + 2); }

private void yos ( Graphics g) { g. setColor ( Color . blue ); g. drawLine (SIRINA / 2, 0, SIRINA / 2, VISINA); for ( int i = 1; i < VISINA / 20; i++) g. drawLine (SIRINA / 2 - 2, i * 20, SIRINA / 2 + 2, i * 20); }

public void crtaj ( Graphics g) { double x = - SIRINA / 40.0, xs = SIRINA / 2.0, ys = VISIN A / 2.0, y; int xp, yp; g. setColor ( Color . red ); while (x < SIRINA / 40) { y = a * Math . sin (b * x + c); xp = ( int )(xs + 20 * x); yp = ( int )(ys - 20 * y); g. drawOval (xp, yp, 1, 1); x += 0.05; } }

public void paint ( Graphics g) { xos (g); yos (g); crtaj (g); }

public static void main (String[] s) { GrafF gF = new GrafF (); }

}

Page 171: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

171

Primijetimo da nam se graf funkcije sastoji os gustih točkica. Želimo li da nam graf bude gladak, da nema razmaka izmeñu točkica, točkice možemo spojiti linijama, i tom će slučaju metoda crtaj () imati sljedeći oblik: public void crtaj ( Graphics g) {

double x = - SIRINA / 40.0, xs = SIRINA / 2.0, ys = VISIN A / 2.0, y; int xp, yp, xt, yt; y = a * Math . sin (b * x + c); xt = ( int )(xs + 20 * x); yt = ( int )(ys - 20 * y); g. setColor ( Color . red ); while (x < SIRINA / 40) { y = a * Math . sin (b * x + c); xp = ( int )(xs + 20 * x); yp = ( int )(ys - 20 * y); g. drawLine (xt, yt, xp, yp); xt = xp; yt = yp; x += 0.05; }

}

Page 172: Java i objektno orijentirano programiranje

172

15 Java appleti

� Primjer appleta � Integriranje appleta u web stranicu � Prosljeñivanje parametara appletu iz web

browsera

Page 173: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

173

Do sada smo se upoznali s dva tipa programa u Javi: � konzolni programi, koje smo pokretali iz komandnog prompta, a vrijednosti smo

im prosljeñivali preko standardnog ulaza ili iz datoteke � programi s korisničkim sučeljem, kod kojih smo vrijednosti unosili preko

elemenata grafičkog korisničkog sučelja ili iz fileova. Na samo početku smo rekli da osim programa u Javi možemo raditi i applete. Radi se o posebnoj vrsti programa koja je integrirana u web stranicu i izvršava se unutar web browsera.

Primjer appleta Za razliku od programa s grafičkim korisničkim sučeljem, koje smo kreirali nasljeñujući klasu JFrame , kod appleta ćemo nasljeñivati klasu JApplet . Obje klase nalaze se u istom paketu javax.swing . Prisjetimo se, kod programa smo uvijek imali konstruktor i metodu main () . Kod appleta je stvar nešto drugačija, nema konstruktora i nema metode main () . Ali zato će uvijek biti jedna od metoda: public void init () – poziva se iz web browsera ili applet viewera svaki puta kada se applet učita ili ponovno učita. Ova metoda na neki način zamjenjuje konstruktor, koji smo imali kod programa. Unutar nje je poželjno inicijalizirati svojstva appleta,... public void paint ( Graphics g ) – za crtanje na appletu (analogno metodi paint () kod programa) osim navedenih metoda unutar appleta postoji i još niz drugih metoda, najčešće korištene su: public void start () – poziva se iz web browsera ili applet viewera, neposredno nakon pozivanja metode init () , kada se kod appleta počinje izvršavati, te kada se stranica s appletom ponovo posjeti (bez da se gasi browser) public void stop () – poziva se iz browsera ili applet viewera svaki puta kada se prekida izvršavanje appleta (zatvaranje web stranice na kojoj se applet nalazi). public void destroy () – poziva se iz browsera ili applet viewera neposredno nakon metode stop () . public void showStatus () – prikazuje poruku na statusnoj traci. Primjer 15 – 1: Napišimo jednostavan applet koji će ispisivati poruku "Ja sam Java applet, a tko si ti?".

Rješenje: import javax.swing.*; import java.awt.*; public class Poruka extends JApplet { public void paint ( Graphics g) { setBackground ( Color . yellow ); g. setFont ( new Font ("Garamond", Font . BOLD, 24)); g. setColor ( Color . blue ); g. drawString ("Ja sam Java applet, a tko si ti?", 20, 50); } }

Page 174: Java i objektno orijentirano programiranje

174

Ovako kreirani applet možemo pokrenuti na nekoliko načina. BlueJ razvojno okruženje nam omogućava izvršavanje appleta na dva načina: � pokretanje u appletvieweru � pokretanje u web browseru Na samom početku ćemo primijetiti da je već sličica appleta drugačija nego sličica programa.

Klikom desnog gumba miša na sličicu appleta otvorit će nam se izbornik, kod kojeg ćemo odabrati Run applet.:

Pokretanje appleta otvorit će nam se novi prozor u kojem ćemo moči definirati veličinu appleta, način na koji želimo pokrenuti applet, te dodati još neke parametre appletu, o kojima ćemo govoriti nešto kasnije.

Page 175: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

175

Ovaj puta ćemo applet pokrenuti iz appletviewera, posebnog programa za pregledavanje appleta, definirat ćemo mu veličinu, te kliknuti na gumb OK i u posebnom prozoru će nam se otvoriti applet:

Integriranje appleta u web stranicu Kao što znamo, web stranica je multimedijalni dokument koji se nalazi negdje na Internetu. Izmeñu ostaloga web stranice mogu sadržavati i applete. U pozadini svake web stranice nalazi se HTML (Hypertext Markup Language). HTML je u stvari jezik za pisanje web stranica, sastoji se od tzv. tagova odnosno opisnika, pomoću kojih dizajniramo izgled stranice te stavljamo elemente na stranicu. Svaka stranica ima sljedeći oblik: <html> <head> ... </head> <body> ... </body> </head>

Kao što možemo primijetiti, web stranica se sastoji od zaglavlja (head) i tijela (body) stranice. Unutar zaglavlja stranice nalazi se najčešće naslov stranice (onaj koji se vidi u naslovnoj traci web browsera), neke skripte,... dok se unutar tijela stranice nalazi sve ono što vidimo u browseru, pa ćemo onda unutar tijela staviti sam applet. Applet koji stavljamo na neku web stranicu mora biti kompajliran te moramo imati dokument s nastavkom .class. Tag za postavljanje appleta na stranicu je <applet> i ima sljedeću sintaksu: <applet code = "ImeKlase.class" width = "sirina" height = "visina" > </applet >

Pri čemu je ImeKlase.class naziv klase koja generira applet, dok su sirina i visina vrijednosti za širinu i visinu appleta na web stranici.

Page 176: Java i objektno orijentirano programiranje

176

Bitno je napomenuti da se sama klasa koja generira applet i web stranica trebaju nalaziti u istoj mapi, inače kod code treba navesti čitav put do filea u kojem se nalazi klasa. Primjer 15 – 2: Kreirajmo web stranicu u koju ćemo uključiti applet napravljen u prethodnom primjeru.

Rješenje: <html > <head > < title >Stranica s Java appletom </title> </head> <body> Ispod ovog teksta nalazi se Java applet <br> <applet code = "Poruka.class" height = "200" width = "450"> </applet> </body> </html>

Ovaj kod možemo napisati u bilo kojem text procesoru (Notepad,...) spremimo ga npr. pod imenom stranica.html u mapu u kojoj se nalazi file s klasom Poruka.class. Tako kreiranu stranicu otvorimo s nekim web browserom i ukoliko je sve u redu u njemu ćemo dobiti sadržaj kao na sljedećoj slici:

Ovdje ima nekoliko HTML tagova koje nismo objasnili. Ukratko tagom <title> unutar zaglavlja definiramo naslov stranice (tekst koji se nalazi u naslovnoj traci preglednika). Tagom <br> naglašavamo da na tom mjestu želimo preči u novi red na stranici. Tekst neposredno prije taga <br> je običan tekst koji se ispisuje na stranici.

Page 177: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

177

BlueJ razvojno okruženje nam nudi mogućnost automatskog kreiranja web stranice. Pomoću BlueJa ćemo stranicu kreirati na sljedeći način:

1. Kliknemo desnim gumbom miša na sličicu appleta za koji želimo da se nalazi na Web stranici.

2. Odaberemo Run Applet.

3. U prozoru koji se pojavi odaberemo opciju Run Applet in web browser, te upišemo širinu i visinu appleta unutar web stranice.

4. Kliknemo na gumb OK. Otvorit će nam se web browser u kojem će se otvoriti stranica s appletom koji smo postavili unutar nje.

Page 178: Java i objektno orijentirano programiranje

178

Stranica će biti kreirana u mapi u kojoj se nalazi i klasa koju smo pokretali kroz web browser. Kod ovako generirane stranice možemo pogledati tako da u izborniku View browsera odaberemo Source, i on u našem slučaju izgleda ovako: <html> <!-- This file automatically generated by BlueJ Jav a Development --> <!-- Environment. It is regenerated automatically each time the --> <!-- applet is run. Any manual changes made to fil e will be lost --> <!-- when the applet is next run inside BlueJ. Sav e into a --> <!-- directory outside of the package directory if you want to --> <!-- preserve this file. --> <head>

<title> Poruka Applet </title> </head> <body>

<h1>Poruka Applet </h1> <hr> <applet code ="Poruka.class" width =450 height =200 codebase ="." archive ="" alt ="Your browser understands the &lt;APPLET&gt; tag b ut isn't running the applet, for some reason." >

Page 179: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

179

Your browser is ignoring the &lt;APPLET&gt; tag! </applet> <hr>

</body> </html>

Napomena: Primijetimo da smo kod programa s grafičkim korisničkim sučeljem uvijek koristili metode: setTitle () , setSize() , setDefaultCloseOperation() , setVisible () ,... kod appleta takvih metoda nema. Naime, nema smisla appletu dodavati naslov jer se nalazi unutar Web stranice kojoj se definira naslov. Veličina koju applet zauzima unutar prozora web preglednika, takoñer je definirana na razini HTML-a, unutar taga <applet> . Applet pokrećemo neposredno s pokretanjem stranice, pa stoga nije potrebna metoda main () , koja se u stvari pokreće kada želimo pokrenuti neki Java program. Isto tako zatvaranjem stranice na kojoj se applet nalazi automatski se prekida i izvršavanje appleta.

Prosljeñivanje parametara appletu iz web browsera Kada smo govorili o pokretanju appleta iz BlueJ sučelja rekli smo da je appletima preko parametara moguće proslijediti neke vrijednosti. U nastavku ćemo govoriti nešto više o tome. Moglo bi se npr. dogoditi da je applet iz našeg primjera postane jako poželjan i svi ga požele imati na svojim web stranicama. Meñutim, ne sviña se svima npr. tekst koji applet ispisuje ili možda ne vole svi žutu boju. Kako ne bismo morali svaki puta iznova raditi novi applet s drugim tekstom ili drugom bojom,... bilo bi zgodno kada bismo npr. boju ili tekst mogli definirati negdje izvan appleta. To uistinu i možemo napraviti i to preko parametara u HTML-u. Vrijednosti parametara ćemo u klasi koja generira applet pokupiti metodom:

String getParemater (String ime )

Unutar HTML-a ćemo parametre definirati tagom:

<param name = "ime" value = "vrijednost">

koji se nalazi unutar taga <applet> . Prije nego što počnemo rješavati sljedeći primjer, upoznat ćemo se s još jednom klasom koju ćemo u njemu koristiti. Radi se o klasi Date za rad s datumima i vremenom. Klasa Date ima nekoliko konstruktora, od kojih se najčešće korite sljedeći: public Date () – kreira objekt tipa Date , pri čemu će datum i vrijeme biti inicijalizirani na trenutni datum i vrijeme public Date (int g, int m, int d) – kreira objekt tipa Date , pri čemu će vrijednost godine biti postavljena na g, mjeseca na m a dana na d. Godine se počinju računati od 1900, pa ako npr. želimo godinu 2005, vrijednost parametra g ćemo postaviti na 105. Mjeseci su definirani od 0-11. Pa ako želimo mjesec na npr. lipanj, vrijednost parametra d treba biti 5. public Date (int g, int m, int d, int h, int min , int sec ) – kreira objekt tipa Date pri čemu će vrijednosti svojstava biti postavljene na proslijeñene vrijednosti, a godina i datum se definiraju kao kod prošlog konstruktora.

Page 180: Java i objektno orijentirano programiranje

180

public Date (long ms) – kreira objekt tipa Date , pri čemu će datum i vrijeme biti postavljeni tako da predstavljaju datum koji dolazi ms sekundi nakon 1. siječnja 1900 00:00:00. Osim navedenih konstruktora često ćemo koristiti i neke od sljedećih metoda: public int getYear () – vraća redni broj godine kao redni broj nakon 1900 public int getMonth () – vraća redni broj mjeseca, počevši od 0 public int getDate () – vraća dan u mjesecu public int getDay () – vraća redni broj dana u tjednu public int getHours () – vraća sate public int getMinutes () – vraća minute public int getSeconds () – vraća sekunde public long getTime () – vraća vrijeme u milisekundama od 1. siječnja 1900 00:00:00 public void setYear () – postavlja godinu public void setMonth () – postavlja mjesec public void setDate () – postavlja dan u mjesecu public void setDay () – postavlja redni broj dana u tjednu public void setHours () – postavlja sate public void setMinutes () – postavlja minute public void setSeconds () – postavlja sekunde public boolean equals (Date d1) – vraća true ako su datumi jednaki public boolean after (Date d1) – vraća true ako je datum nakon specificiranog datuma d1 public boolean before (Date d1) – vraća true ako je datum prije specificiranog datuma d1 Klasa Date nalazi se u posebnom paketu java.util , koji ćemo morati uključiti u svoj program svaki puta kada ćemo raditi s datumima. Primjer 15 – 3: Kreirajmo Java applet koji će unositi dan, mjesec i godinu roñenja neke osobe, te će na osnovu tih podataka računati bioritam osobe za razdoblje od broja dana koji će se zadati kao parametar kroz web stranicu. Bioritam se sastoji od 3 krivulje. Sve tri krivulje su periodičke, u trenutku roñenja su sve tri na 0. Krivulje su redom: Fizički aspekt – period je 23 dana Emotivni aspekt – period je 28 dana Intelektualni aspekt – period je 33 dana

Rješenje: Applet: import java.awt.*; import javax.swing.*; import java.util.*; import java.awt.event.*; public class Bioritam extends JApplet implements ActionListener { private Date dr, d = new Date (); private Container c; private JButton b; private JComboBox c1, c2, c3; private boolean initialized = false ; private int broj_dana, k; public void init()

Page 181: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

181

{ //uzimanje vrijednosti parametra s web stranice broj_dana = Integer . parseInt ( getParameter ("broj_dana")); k = 600 / broj_dana; c = getContentPane (); c. setLayout (null); c1 = new JComboBox (); c1. setSize (50, 25); c1. setLocation (10, 10); for ( int i = 1; i <= 31; i++) c1. addItem ("" + i); c. add (c1); String [] mj = {"Sije čanj", "Velja ča", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan ", "Listopad", "Studeni", "Prosinac"}; c2 = new JComboBox (mj); c2. setSize (150, 25); c2. setLocation (70, 10); c. add (c2); c3 = new JComboBox (); c3. setSize (70, 25); c3. setLocation (230, 10); for ( int i = 1900; i <= 2005; i++) c3. addItem ("" + i); c. add (c3); b = new JButton ("OK"); b. setSize (80, 25); b. setLocation (320, 10); b. addActionListener ( this ); c. add (b); } public void paint( Graphics g) { super . paint (g); g. setColor (Color.white); g. fillRect (0, 100, 600, 520); if (initialized) { //starost osobe u danima kao razlika izme ñu dva datuma u

//milisekundama, pa poslije pretvorena u dane long start = ( long )((d. getTime () - dr. getTime ()) / (24 * 60 *

60 * 1000)); //crtanje krivulja crtaj (g, 28, Color . red , start); crtaj (g, 33, Color . blue , start); crtaj (g, 23, Color . green , start); koordinatni (g); } }

//metoda crta graf za odre ñeni aspekt na osnovu perioda ciklusa te //starosti osobe u danima. //Budu ći da se radi o periodi čkom grafu, crtat ćemo ga kao sinusoidu //s periodom b i to na intervalu od ( start – broj_dana / 2 ) //do ( start + broj_dana / 2 ), pri čemu je start starost osobe u

Page 182: Java i objektno orijentirano programiranje

182

//danima, na današnji datum, dok je broj_dana vrijednost parametra, //proslije ñenog s web stranice a odnosi se na broj dana za koj i //želimo raditi bioritam.

public void crtaj ( Graphics g, int b, Color c, long start) { double x = start - broj_dana / 2, y; int xt = ( int )(k * (x - start) + 300), yt = ( int )(300 - 20 * 10 *

Math . sin (2.0/b * Math . PI * x)), xx, yy; g. setColor (c); while (x < start + broj_dana / 2) { y = Math . sin (2.0/b * Math . PI * x); xx = ( int )(k * (x - start) + 300); yy = ( int )(300 - 20 * 10 * y); g. drawLine (xt, yt, xx, yy); xt = xx; yt = yy; x += 0.01; } if (b == 23) g. drawString ("Fizi čki ciklus", 10, 515); else if (b == 28) g. drawString ("Emotivni ciklus", 210, 515); else g. drawString ("Intelektualni ciklus", 410, 515); } //metoda crta koordinatni sustav ovisno o vremensko m intervalu za //koji se bioritam radi. public void koordinatni ( Graphics g) { g. setColor ( Color . blue ); g. drawLine (0, 300, 600, 300); g. drawLine (300, 100, 300, 500); Date tmp; int dan, danas = d. getDate (); String s; for ( int i = -broj_dana / 2; i <= broj_dana / 2; i++) { g. drawLine (300 + i * k, 298, 300 + i * k, 302); tmp = new Date (d. getTime () + i * 24 * 60 * 60 * 1000); if (tmp. getDate () < 10) s = "0" + tmp. getDate (); else s = "" + tmp. getDate (); if (tmp. getMonth () + 1 < 10) s = s + ".0" + (tmp. getMonth () + 1); else s = s + "." + (tmp. getMonth () + 1); if (i % 2 == 0) g. drawString (s, 285 + i * k, 315); } } public void actionPerformed ( ActionEvent e) { initialized = true ; dr = new Date (c3. getSelectedIndex (), c2. getSelectedIndex (),

c1. getSelectedIndex () + 1); repaint ();

Page 183: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

183

} }

Web stranica: <html> <head> <title> Bioritam </title> </head> <body> Unesite svoj datum ro ñenja te kliknite na gumb OK. <hr> <applet code ="Bioritam.class" width ="600" height ="520"> <param name = "broj_dana" value = "20"> </applet> </body> </html>

Page 184: Java i objektno orijentirano programiranje

184

16

Osnove mrežne komunikacije u Javi

� O računalnim mrežama � Mrežna komunikacija u Javi � Komunikacija putem socketa � Višenitnost

Page 185: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

185

Jedno od velikih područja upotrebe Jave je izrada mrežnih aplikacija, raznih servera,... U ovom ćemo se poglavlju, na stvarnom primjeru upoznati s osnovnim pojmovima vezanim uz mrežnu komunikaciju. Cilj nam je napraviti program koji će omogućiti komunikaciju korisnika na udaljenim računalima, tzv. chat.

O računalnim mrežama Mrežu čine dva ili više ureñaja koja su meñusobno spojena i mogu razmjenjivati podatke. Najčešći načini spajanja danas su kablovi odnosno wireles. Cilj mreže je prijenos podataka izmeñu ureñaja unutar mreže tzv. čvorova. Čvorovi mogu biti računala, neki drugi tipovi hardwarea npr. printer ili neki mrežni ureñaji zaduženi za pojedine segmente unutar komunikacije. Kako bi podaci stizali na ispravno odredište treba postojati pravilan način označavanja čvorova komunikacije. Svaki čvor unutar mreže ima svoju adresu. Baš isto kao što ako na razglednicu napišemo ispravnu adresu primatelja, bez obzira iz kojeg dijela svijeta ju slali ona će doći na odredište. Slična je situacija i u svijetu računala. Postoje stroga pravila komuniciranja tzv. protokoli. Svaki ureñaj spojen na računalnu mrežu ima svoju jedinstvenu adresu. Ta adresa je fiksna i u principu ju nije moguće mijenjati. Sam Internet, globalna računalna mreža, funkcionira na sličnom principu. Komunikacija putem Interneta temelji se na IP adresama. IP adresa se sastoji od 32 bita (4 puta po 8 bitova) i oblika je:

bbb.bbb.bbb.bbb pri čemu je bbb neki nenegativan cijeli broj izmeñu 0 i 255. Primjer IP adrese je: 195.29.220.4. Spajanjem na Internet svako računalo dobije svoju jedinstvenu IP adresu i na taj način može komunicirati s ostalim računalima na Internetu. Kako je pamćenje ovakvih IP adresa komplicirano postoje i tzv. simboličke IP adrese koje su lakše za pamćenje. Takva simbolička IP adresa poznata je još i kao host name. Tako npr. računalo čija je IP adresa 195.29.220.4 ima host name shk.skolskaknjiga.hr. Vezivanje IP adrese s host nameom omogućava nam tzv. DNS (Domain Name Server). Računala spojena na Internet komuniciraju putem jednog od dva protokola:

� TCP – Transmission Control Protocol � UDP – User Datagram Protocol

Grafički bi to izgledalo ovako:

Fizički sloj (driveri,...)

Mrežni sloj (IP,...)

Prijenos podataka (TCP, UDP...)

Aplikacijski sloj (FTP, Telnet, HTTP,...)

Page 186: Java i objektno orijentirano programiranje

186

Zahvaljujući specijalnom Javinom paketu – java.net pišući svoje mrežne aplikacije nećemo se trebati zamarati TCP-em, UDP-om, IP-em,... već ćemo ih pisati na aplikacijskom sloju i koristiti sve njegove blagodati. Programiranje mrežnih programa na aplikacijskom nivou čini mrežno programiranje poprilično jednostavnim. U nastavku ćemo se ukratko osvrnuti na najvažnije pojmove vezane uz mrežu koje ćemo susretati u ovom poglavlju:

� TCP � UDP � portovi

TCP protokol Kada dva računala žele meñusobno komunicirati pouzdano, oni će uspostaviti vezu te meñusobno slati i primati podatke putem uspostavljene veze. Ovaj način komunikacije možemo usporediti s slanjem preporučenog pisama. Naime šaljemo li preporučeno pismo tada osoba kojoj pismo šaljemo svojim potpisom potvrñuje da je pismo primila. Ukoliko pismo nije primljeno ono se vrača pošiljatelju. Isto tako TCP nam osigurava da sve što jedno računalo pošalje drugo će sigurno primiti i obrnuto, inače će biti poslana poruka o grešci. TCP omogućava sigurnu komunikaciju za aplikacije koje to zahtijevaju. HTTP (protokol za prijenos Web stranica), FTP (protokol za prijenos datoteka), i Telnet (protokol za udaljeni rad na računalu) zahtijevaju upravo takvu, pouzdanu komunikaciju. Informacija jesu li podaci stigli na odredište ključna je za ove protokole. Ukoliko ne bi bilo tako primili bismo Web stranicu na kojoj bi nedostajali elementi, skinuli bismo nepotpun dokument,... UDP protokol Za razliku od TCP protokola koji zahtjeva pouzdanu komunikaciju, UDP je protokol za komunikaciju koji ne garantira da će podaci stići na odredište. Ovaj protokol možemo usporediti s klasičnom poštom. Naime, pošaljemo li obično pismo, nitko nam ne garantira da će ga osoba kojoj je poslano primiti. UDP šalje neovisne pakete podataka tzv. datagrame s jednog računala na drugo. Većina mrežnih aplikacija zahtijevaju pouzdanu komunikaciju, meñutim postoje i aplikacije kod kojih to nije bitno. Portovi Već smo rekli da jednom kada se računalo spoji na Internet ono dobiva jedinstvenu IP adresu pomoću koje komunicira s ostalim računalima na Internetu. Svi podaci koje dobiva s Interneta dolaze tom vezom. Meñutim računalo može istovremeno primati podatke za različite aplikacije (downloadati dokument putem FTP-a, učitavati Web stranicu,...). Postavlja se pitanje kako ono zna kojoj aplikaciji treba proslijediti koji podatak? Odgovor leži u portovima. Podaci koji putuju Internetom osim što sadrže IP adresu odredišta sadrže i port na odredištu na koji se trebaju isporučiti.

Page 187: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

187

Na računalu postoji 65536 portova koji su numerirani brojevima od 0 do 65535. Portovi od 0 do 1023 su rezervirani za posebne servise. Tako npr. HTTP koristi port 80, FTP koristi portove 20 i 21, Telnet koristi port 23,... Tablica servisa, protokola te pripadnih portova dana je u dodatku. Mrežne aplikacije koje ćemo mi kreirati takoñer će komunicirati putem portova, rezervirane portove nećemo smjeti koristiti za komunikaciju u svojim aplikacijama. Internet se temelji na tzv. klijent-server koncepciji. To znači da na Internetu postoje dva osnovna tipa računala:

� klijenti � serveri (poslužitelji)

Klijent je računalo koje serveru šalje zahtjeve i od njega dobiva tražene podatke. Poslužitelj je računalo koje sadrži podatke i u stanju je posluživati više računala podacima koje oni od njega traže.

IP adresa port podatak

paket

port 1

program 1

port 2

program 2

port n

program n

...

RAČUNALO (TCP/UDP)

Page 188: Java i objektno orijentirano programiranje

188

Mrežna komunikacija u Javi Već smo rekli da nam mrežnu komunikaciju u Javi omogućava paket java.net . Paket java.net sadrži klase za TCP i UDP komunikaciju. Najčešće korištene klase za TCP komunikaciju su:

� InetAdress � URL � URLConnection � Socket � ServerSocket

Dok su za UDP komunikaciju najčešće korištene klase:

� DatagramPacket � DatagramSocket � MulticastSocket

Klasa InetAddress Klasa InetAddress predstavlja Internet adresu. Najčešće korištene metode ove klase su: static InetAddress getByName (String s) – vraća objekt tipa InetAdress na osnovu imena hosta s static InetAdress getByAddress (byte[] a) – vraća objekt tipa InetAddres koji je kreiran na osnovu niza a koji predstavlja IP adresu public String getHostAddress () – vraća IP adresu objekta nad kojim se poziva public String getHostName () – vraća host name objekta nad kojim se poziva

Primjer 16 – 1: Napišimo konzolnu aplikaciju koja će biti pozivana s jednim parametrom, Web adresom neke Web stranice. Aplikacija treba ispisivati IP adresu i host name računala na kojem se Web stranica nalazi. Rješenje: import java.net.*; public class IP { public static void main (String[] s) { try { InetAddress address = InetAddress . getByName (s[0]); System . out . println (address.getHostName()); System . out . println (address.getHostAddress()); } catch ( Exception e) { System . out . println ( "Ne mogu pronaci " + s[0]); } } }

Napomena: Pri izvršavanju programa trebate biti spojeni na Internet.

Page 189: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

189

Klasa URL URL (Uniform Resource Locator) je jedinstvena adresa bilo kojeg dokumenta na Internetu. URL je tekst koji npr. upisujemo u Address bar Web preglednika kako bi učitali neku stranicu. Primjer URL-a je:

http :// s5.pro-futura.com : 8080 / readmail.html

URL se u osnovi sastoji od nekoliko dijelova:

� protokol – neki od Internet protokola, najčešće http, https, ftp,... � host name – naziv računala na kojem je smješten sadržaj � port – broj porta na koji se spajamo (najčešće se ne navodi) � ime dokumenta – put do dokumenta na serveru � reference – mjesto unutar dokumenta na koje će se premjestiti fokus prilikom

učitavanja dokumenta Javina klasa URL sadrži metode koje nam omogućuju pristup dokumentima na Internetu. Klasa URL ima nekoliko konstruktora, neki od njih su: URL (String s) – kreira objekt tipa URL pri čemu je s neki URL URL (String protokol, String host, int port, String file) – kreira objekt URL s zadanim parametrima URL (String protokol, String host, String file) – kreira objekt URL s zadanim svojstvima Neke od metoda definirane nad klasom URL su: String getFile () – vraća file URL-a String getHost () – vraća host name URL-a int getPort () – vraća port URL-a. Ako port nije specificiran vraća -1 String getProtocol () – vraća protokol InputStream openStream () – otvara konekciju prema danom URL-u i vraća InputStream koji će omogućiti čitanje podataka s URL-a URLConnection openConnection () – vraća objekt tipa URLConnection koji predstavlja konekciju prema URL-u. Primjer 16 – 2: Napišimo program s grafičkim sučeljem koji će unositi URL neke Web stranice i ispisivati sadržaj te stranice u posebnom području za tekst.

Page 190: Java i objektno orijentirano programiranje

190

Rješenje: import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.*; import java.io.*; public class WebBrowser extends JFrame implements ActionListener { private final int sirina = 400; private final int visina = 300; private Container c; private JTextArea ta; private JTextField t; private JScrollPane sp; private JButton b; public WebBrowser () { setTitle ( "Web browser" ); setSize (sirina, visina); setDefaultCloseOperation (EXIT_ON_CLOSE); c = getContentPane (); c. setLayout ( null ); t = new JTextField (); t. setSize (200, 30); t. setLocation (10, 10); c. add (t); b = new JButton (); b. setSize (135, 30); b. setText ( "OK" ); b. setLocation (220, 10); b. addActionListener (this); c. add (b); ta = new JTextArea (); sp = new JScrollPane (ta);

Page 191: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

191

sp. setLocation (10, 50); sp. setSize (350, 200); c. add (sp); setVisible ( true ); } public void actionPerformed ( ActionEvent e) { try { URL url = new URL(t. getText ()); BufferedReader br = new BufferedReader ( new InputStreamReader

(url. openStream ())); String inputLine , tmp = ""; while ((inputLine = br. readLine ()) != null ) tmp = tmp + "\n" + inputLine; ta. setText (tmp); br. close (); } catch ( Exception e1) { System . out . println (e1. getMessage ()); } } public static void main ( String [] s) { WebBrowser z = new WebBrowser (); } } Klasa URLConnection Klasa URLConnection omogućava komunikaciju izmeñu programa i URL-a. Metode ove klase omogućavaju čitanje i pisanje na resurs s danim URL-om. Konstruktor ove klase je oblika: URLConnection (URL s) – kreira konekciju za objekt s tipa URL Nekoliko češće upotrebljavanih metoda klase URLConnection su: InputStream getInputStream () – vraća InputStream za čitanje s otvorene konekcije OutputStream getOutputStream () – vraća OutputStream za pisanje na otvorenu URL konekciju

Page 192: Java i objektno orijentirano programiranje

192

Komunikacija putem socketa Klase URL i URLConnection su gotove klase koje omogućavaju komunikaciju sa serverom. U nastavku nam je cilj naučiti kreirati aplikacije koje će komunicirati na nižoj razini. Naučit ćemo kako komunicirati na sloju samog prijenosa podataka, na razini TCP odnosno UTP protokola. TCP omogućava tzv. point-to-point komunikaciju izmeñu klijenta i servera. Za komunikaciju putem TCP-a serverske i klijentske aplikacije koriste poseban komunikacijski kanal kojim prolaze podaci. Klijent je u stvari računalo na kojem se izvršava klijentska aplikacija dok s druge strane imamo server tj. računalo na kojem se izvršava serverska aplikacija. Kanal izmeñu servera i klijenta je dvosmjeran što znači da njime putuju podaci od klijenta prema serveru i od servera prema klijentu. Krajeve takvog kanala nazivamo socketi. Na komunikacijski kanal možemo gledati kao na hodnik koji povezuje dvije prostorije, dok bi socketi u tom slučaju bila vrata na svakom od krajeva hodnika. Dakle, kada se uspostavi komunikacijski kanal izmeñu dva računala na svakom kraju tog kanala otvara se po jedan socket. S jedne strane imamo server koji je samostalna aplikacija na nekom računalu. Server ima socket na nekom portu i čeka da klijent pošalje zahtjev za početkom komunikacije. S druge strane klijent kreira svoj socket, on zna IP adresu računala na kojem se nalazi server te zna port na kojem je server. Kada klijent kreira socket serveru se šalje zahtjev za uspostavom veze. Kada primi zahtjev od klijenta server kreira novi socket, na novom portu, za komunikaciju s klijentom, te je na taj način omogućena komunikacija s više klijenata istovremeno. Nakon što je komunikacijski kanal otvoren moguće je prenositi podatke izmeñu servera i klijenta. Za početak nam je želja kreirati jednostavnu aplikaciju koja će raditi na sljedećem principu:

� klijent učita liniju teksta sa standardnog ulaza te ju ispiše na socketu. � server sa socketa pročita tekst koji je klijent posao, sva slova poruke pretvori u

velika te takvu, izmijenjenu poruku ispiše na socket � klijent pročita poruku sa socketa te ju ispiše ponovo na standardni izlaz

Shematski prikaz opisanih radnji mogao bi izgledati ovako:

Page 193: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

193

Da bismo ovo bili u stanju isprogramirati moramo znati nešto o socketima u Javi. Kako pročitati podatke sa socketa? Kako pisati na socket?... Javina klasa java.net sadrži klasu Socket koja implementira jedan kraj komunikacijskog kanala. Isto tako java.net sadrži i klasu ServerSocket koja implementira socket koji će koristiti server za čekanje i prihvaćanje konekcije od strane klijenta. Klasa Socket ima nekoliko konstruktora najčešći su: Socket (String host, int port) – kreira socket sa specificiranim hostom i portom Socket (InetAddress adress, int port) – kreira socket sa specificiranom adresom i portom Najčešće metode definirane nad klasom Socket su: public void close () – zatvara konekciju public InetAddress getInetAddress () – vraća adresu s kojom je klijent spojen public InputStream getInputStream () – kreirao objekt tipa InputStream koji će nam omogućavati čitanje podataka sa socketa public InetAddress getLocalAddress () – vraća lokalnu adresu računala na kojem je socket public int getLocalPort () – vraća lokalni port na kojemu je socket

server

kreira socket na nekom portu

kreira novi socket za komunikaciju s klijentom

čita poruku s socketa

sva slova u poruci mijenja odgovarajućim velikim

slovima

piše poruku na socket

zatvara socket

klijent

kreira novi socket za komunikaciju sa

serverom

učitava poruku sa standardnog ulaza

piše poruku na socket

čita poruku sa socketa

ispisuje poruku na standardni izlaz

zatvara socket

čeka zahtjev klijenta

Page 194: Java i objektno orijentirano programiranje

194

public OutputStream getOutputStream () – kreira objekt tipa OutputStream koji će nam omogućavati pisanje podataka na socket Najčešći konstruktor klase ServerSocket je: ServerSocket (int port) – kreira objekt tipa ServerSocket na specificiranom portu Najčešće korištene metode ove klase su: public Socket accept () – očekuje zahtjev klijenta i kreira novi socket public void close () – zatvara socket public InetAddress getLocalAddress () – vraća lokalnu adresu računala na kojem je socket public int getLocalPort () – vraća port na kojemu je socket čeka Sada imamo sve spremno za rješavanje problema koji smo si postavili. Primjer 16 – 3: Kreirajmo server aplikaciju na portu 2000 koja će od klijenta uzimati poruku te sva slova poruke pretvoriti u velika. Tako dobivenu poruku treba ispisati na socket. Potrebno je kreirati i klijent aplikaciju koja će se spajati sa serverom na port 2000, učitavat će poruku sa standardnog ulaza, pisati ju na socket te sa socketa uzeti poruku koju je vratio server i ispisati ju na standardni izlaz. Rješenje: Klasa za serversku aplikaciju import java.net.*; import java.io.*; public class Server { private ServerSocket ss; private int port; private Socket s; public Server( int port) { this .port = port; try { //otvaranje socketa na serveru na portu port koji će čekati //zahtjev klijenta za otvaranje komunikacijskog k anala

ss = new ServerSocket (port); System . out . println ( "Socket kreiran" ); // čeka se zahtjev klijenta za spajanje na server s = ss. accept (); //zaprimljen zahtjev klijenta i otvoren je komunika cijski kanal //na serveru je kreiran novi socket System . out . println ( "Klijent spojen" ); //objekt za čitanje podataka sa socketa s InputStream in = s. getInputStream (); //objekt za pisanje podataka na socket s

Page 195: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

195

OutputStream out = s. getOutputStream (); // čitanje podataka sa socketa – re čenica koju je na socket //zapisao klijent BufferedReader br = new BufferedReader ( new InputStreamReader

(in)); String tmp = br. readLine (); System . out . println ( "Primio sam poruku od klijenta: " + tmp); //pretvaranje svih slova u velika

tmp = tmp. toUpperCase (); System . out . println ( "Saljem poruku klijentu: " + tmp); //pisanje na socket PrintStream ps = new PrintStream (out); ps. println (tmp); //zatvaranje konekcije s. close (); } catch ( Exception e) { System . out . println ( "Greska" ); } } public static void main (String[] s) { Server sr = new Server (2000); } } Klasa za klijentsku aplikaciju import java.net.*; import java.io.*; public class Klijent { private int port; private String host; private Socket s; public Klijent( String host, int port) { try { this .host = host; this .port = port;

//otvaranje socketa prema serveru na portu 2000 s = new Socket (host, port); // Čitanje podataka sa standardnog ulaza BufferedReader br = new BufferedReader ( new InputStreamReader

( System .in)); System . out . println ( "Unesi poruku: " ); String tmp = br. readLine (); //pisanje poruke na socket

OutputStream out = s. getOutputStream (); PrintStream ps = new PrintStream (out);

Page 196: Java i objektno orijentirano programiranje

196

ps. println (tmp); // čitanje poruke sa socketa InputStream in = s. getInputStream ();

BufferedReader bs = new BufferedReader ( new InputStreamReader (in));

String tmp2 = bs. readLine (); //ispis poruke na standardni output (ekran) System . out . println (tmp2); } catch ( Exception e) { System . out . println ( "Greska" ); } } public static void main ( String [] s) { //server na koji se spajamo u ovom se slu čaju zove predrag

Klijent k = new Klijent ( "localhost" , 2000); } } Napomena: Program ćemo testirati tako da na jednom računalo prvo pokrenemo klasu Server. Ukoliko imamo dva računala koja su umrežena na drugom računalu ćemo pokrenuti klasu Klijent (klase ćemo pokrenuti iz komandnog prompta). Ukoliko imamo samo jedno računalo, možemo obje klase pokrenuti na istom računalu. Ukoliko obje klase pokrećemo na istom računalu kao host name kod klijenta možemo koristiti localhost.

Page 197: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

197

Višekorisnički server U prethodnom primjeru smo kreirali klijent-server aplikaciju kod koje smo imali jedan server i samo jednog klijenta, koji su izmijenili samo jednu poruku i komunikacija se je prekinula. Na samom početku smo rekli da nam je cilj kreirati vlastiti chat. Kao što znamo na chat se može spojiti više korisnika (klijenata) koji meñusobno razgovaraju. Svaki klijent šalje poruku koju vide svi sudionici chata. Dakle, želimo li napraviti chat, moramo kreirati server koji će biti u stanju prihvatiti više klijenata i s njima komunicirati. Server bi trebao biti u stanju u svakom trenutku biti u stanju primiti novog klijenta i svi klijenti bi trebali biti meñusobno neovisni. Dakle, na serveru bi trebala postojati jedna petlja koja će neprestano čekati i prihvaćati nove konekcije. Dio servera koji će biti u stanju neprekidno prihvaćati nove konekcije mogao bi izgledati ovako: ss = new ServerSocket ( port ); System . out . println ( "Cekam klijente.... " ); while ( true ) {

Socket s = ss. accept (); //nakon što se klijent spoji na neki port s njim ne što napravim System . out . println ( "Klijent spojen na port " + s. getPort () );

}

Na ovaj smo način omogućili istovremeno spajanje više klijenata na server. Meñutim nakon što se klijent spoji na server, on ništa ne radi, samo se na serveru ispiše poruka da je klijent spojen i port na kojem je spojen. Primijetimo da se svi klijenti spajaju na socket s na serveru. Dakle kada se spoji novi klijent u principu gubimo svaki odnos sa starim klijentom. U stvari bi bilo idealno kada bi naš klijent mogao biti nešto kao recepcionar u nekom bogatom hotelu. Dakle, server bi trebao "prihvatiti" klijenta, "zapisati ga" i zatim ga "prepustiti pomoćnom osoblju" koje će mu "stajati na usluzi", te ponovno "čekati" novog klijenta... Dakle, rezimirajmo: naš server će prihvaćati klijente te ih prosljeñivati "nekom drugom" koji će dalje voditi računa o svakom klijentu. Nakon što proslijedi klijenta "nekome drugom" on će biti ponovo slobodan i čekati će nove klijente. Taj "netko drugi" će biti posebna klasa koja će prihvaćati klijenta i s njim nešto raditi. Klasa će evidentirati neke osnovne podatke o klijentu (ime, socket na koji je spojen,...) te će u sebi imati implementiranu komunikaciju klijenta sa serverom. Nakon što se klijent "ugasi" ova će klasa poslati poruku serveru da se klijent više nije spojen. Na ovaj smo način uistinu osigurali da server uistinu ne treba više voditi računa o klijentu, nakon što ga prihvati. Još nam je preostao samo jedan problem, kako to sve realizirati u Javi?

Page 198: Java i objektno orijentirano programiranje

198

Višenitnost Snaga Jave kao programskog jezika najviše dolazi do izražaja u mrežnim i tzv. višenitnim (multithreading) aplikacijama. U nastavku ćemo pokušati objasniti kakve su to višenitne aplikacije. Pokušajmo to objasniti na jednom jednostavnom primjeru: taksi služba unutar nekog grada raspolaže s nekoliko taksista koji stoje na raspolaganju. Na poziv klijenta koji treba prijevoz taksist doñe po njega te mu stoji na usluzi i vozi ga gdje god klijent želi, naravno uz odreñenu naknadu. Svi taksisti rade unutar jedne taksi službe ali svaki od njih razvozi klijente neovisno kada se za to pojavi potreba. Nerijetko se dogaña da više taksista razvozi klijente istovremeno. Slična je situacija i kod višenitnosti unutar programa. Dakle, imamo jedan program ali unutar kojega se istovremeno odvija više neovisnih procesa (niti, threads). Svaka nit vodi računa o izvršavanju odreñenog skupa naredbi. Višenitni programi imaju višestruke, autonomne aktivnosti koje se izvršavaju istovremeno. To je upravo ono što nam treba u našem chatu. Server može istovremeno komunicirati s više klijenata, meñutim klijenti su znatno sporiji od servera. Stoga će server glavninu vremena čekati da neki klijent nešto kaže. Ako imamo jednonitnu aplikaciju koja čeka da klijent 1 nešto kaže, u to vrijeme bi možda neki drugi klijenti možda već izmijenili nekoliko poruka, jer npr. klijent 1 sporo piše. Stoga ćemo kreirati višenitnu aplikaciju kod koje će postojati niti za svakog klijenta koji se spojina server. Višenitnost će nam omogućiti da klijenti šalju poruke serveru neovisno, a znamo da je server dovoljno brz i on će sve te poruke biti u stanju obrañivati. Za rad s nitima Java ima posebnu klasu Thread . Klasa Thread implementira interface Runnable koja ima jednu public metodu: run () , koja ništa ne vraća. Ukratko to znači da ćemo u klasi koja će u sebi koristiti klasu Thread trebati definirati metodu run sa zaglavljem: public void run (). Unutar tijela metode run definirat ćemo "ponašanje" klase. Tj. definirat ćemo što će se dogañati s konkretnom niti unutar nekog programa. Kao i svaka druga klasa i klasa Thread ima nekoliko konstruktora: Thread () – kreira novi objekt tipa Thread Thread (String name) – kreira novi objekt tipa Thread kojemu će biti dodijeljeno dano ime (name) Neke od metoda definirane unutar klase Thread su: static int activeCount () – vraća broj trenutno aktivnih niti void destroy () – uništava nit String getName () – vraća ime niti void start () – pokreće nit, tj. započinje izvršavanje metode run() Sada imamo sve spremno za kreiranje klase koja će brinuti o svakom klijentu. Klasa će kao svojstva imati ime serverske aplikacije koja je kreirala vezu s klijentom i koja je pokrenula nit programa. Osim toga znat će ime socketa preko kojega se odvija komunikacija te će imati informaciju o nekom simboličkom imenu klijenta koje mu je dodijelio server kako bi se znalo točno znalo koji klijent šalje informacije. Zadaća niti će biti da preuzme poruku sa ulaza te ju stavi na socket i kaže serveru da poruku pročita i pošalje ju svim klijentima koji su spojeni na chat. import java.io.*; import java.net.*;

Page 199: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

199

public class ChatServerNit extends Thread { private ChatServer server; private Socket socket; private String name; public ChatServerNit ( ChatServer server, Socket socket, String name ) { //podaci o serveru, socketu i simboli čko ime klijenta su svojstva //klase ChatServerNit this .server = server; this .socket = socket; this .name = name; //po četak "rada" niti start(); } //metoda run koja opisuje rad klijenta public void run() { try { BufferedReader din = new BufferedReader( new InputStreamReader

( socket. getInputStream ()));

//beskona čno ponavljaj while ( true )

{ //U čitaj poruku s ulaza String message = din. readLine (); //ispiši poruku na socket System . out . println (message ); //upozoravamo server da je klijent poslao poruku, t ako //da pozovemo odgovaraju ću metodu na serveru. server. sendToAll ( name + " > " + message ); } } catch ( Exception ie ) { System . out . println (ie. getMessage ()); } //nakon što se klijent "ugasi" javlja se poruka ser veru da //obriše klijenta server. removeConnection ( socket ); } }

Preostaje nam još izmijeniti server. Server će voditi evidenciju o svim klijentima spojenim na server i to pomoću posebnog niza socketa. Isto tako će za svaki socket imati posebni PrintStream koji će mu omogućiti da zna na koje sve sockete treba pisati poruke: import java.io.*; import java.net.*; public class ChatServer { private ServerSocket ss;

Page 200: Java i objektno orijentirano programiranje

200

//na server će se mo či spojiti maksimalno 100 klijanata private final int MAX = 100; //podaci o socketima pamtit će se unutar niza soc private Socket [] soc = new Socket [MAX]; //za svaki socket bit će kreiran poseban PrintStream private PrintStream [] ps = new PrintStream [MAX]; private int elements = 0, k = 1; public ChatServer( int port ) { try { ss = new ServerSocket ( port ); System . out . println ( "Cekam klijente.... " ); while ( true ) { //prihva ćanje klijenta i otvaranje novog socketa koji // će se spremiti u niz socketa te kreiranje //posebnog PrintStreama za svaki socket Socket s = ss. accept (); System . out . println ( "Klijent spojen na port " + s. getPort ()); PrintStream dout = new PrintStream (s. getOutputStream ()); soc [elements] = s; ps [elements++] = dout; //kreiranje niti za novog klijenta, imena klijenata bit će //redni brojevi njihovog spajanja na server sendToAll ( "Dobrodosao Klijent " + k); new ChatServerNit( this , s, "Klijent " + k++ ); } } catch ( Exception e) { System . out . println (e. getMessage ()); } } //metoda koja pristiglu poruku piše na sve sockete void sendToAll( String message ) { for ( int i = 0; i < elements; i++) { PrintStream dout = ps [i]; try { dout. println (message); } catch ( Exception e ) { System . out . println ( e. getMessage () ); } } } // briše klijenta koji je otišao s chata, tako da briš e odgovaraju će //elemente iz niza socketa i niza PrintStreamov a void removeConnection( Socket s ) { System . out . println ( "Brisem klijenta na portu " + s.getPort() ); int i = 0;

Page 201: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

201

while (!soc [i].equals (s)) i++; //sve elemente iza izbrisanog pomi če za jedno mjesto unatrag for ( int j = i; j < elements; j++) { soc [j] = soc [j + 1]; ps [j] = ps [j + 1]; } elements--;

System.out.println ( name + " je napustio chat" ); sendToAll ( name + " je napustio chat" );

} public static void main( String args[] ) { try { int port = Integer . parseInt ( args[0] ); ChatServer cs = new ChatServer( port ); } catch ( Exception e) { System . println (e. getMessage ()); } } }

Preostaje nam još kreirati klijenta. Klijent ćemo poput pravog chat klijenta implementirati kao Applet te ga staviti unutar neke Web stranice. Chat klijent treba voditi računa o dvije stvari:

� nakon što korisnik upiše poruku chat klijent ju treba zapisati na socket � neprekidno provjeravati ima li novih poruka na socketu te ukoliko ih ima ispisati

ih u svom prozoru Prvi problem: slanje upisane poruke na socket riješit ćemo prilično jednostavno. Korisnik chata će upisati poruku u poseban tekstualni okvir te će pritiskom na tipku [enter] zapisati na socket. To ćemo napraviti tako da ćemo kreirati Action Listener na tekstualnom okviru. Pritiskom tipke [enter] kreirat će se dogañaj koji će pokrenuti metodu sendMessage () , koja će poruku zapisati na socket. Metoda sendMessage () vrlo je jednostavna i ne predstavlja nikakvu novost, ona izgleda ovako: private void sendMessage( String message ) {

try { dout. println ( message ); tf. setText ( "" ); } catch ( Exception e ) { System . out . println ( e.getMessage() ); }

}

pri čemu je dout objekt tipa PrintStream .

Page 202: Java i objektno orijentirano programiranje

202

Naš chat klijent osim što piše podatke na socket te ih na taj način prosljeñuje serveru, on mora i provjeravati je li server upisao kakve podatke na socket, a ako ih je upisao treba ih pročitati i ispisati unutar sučelja chat klijenta. Slična kao i kod servera i ovdje ćemo morati kreirati posebnu nit koja će u pozadini izvršavati beskonačnu petlju koja će neprestano provjeravati ima li podataka na socketu te ih pročitati i ispisati u prozoru chat klijenta. To ćemo implementirati unutar metode run () . Prisjetimo se svaki puta kada koristimo klasu Thread , unutar svoje klase trebamo definirati metodu run () . Ta je metoda poprilično jednostavna i ima sljedeći oblik: public void run() {

try { while ( true ) { String message = din. readLine (); ta. append ( message + "\n" ); } } catch ( Exception e ) { System . out . println ( e. getMessage () ); }

} Dakle, cjelokupna implementacija chat klijenta bila bi: import java.applet.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; public class ChatClient extends Applet implements Runnable , ActionListener { private TextField tf = new TextField (); private TextArea ta = new TextArea (); private Socket socket; private PrintStream dout; private BufferedReader din; public void init() { ta. setEditable (false); String host = getParameter ( "host" ); int port = Integer . parseInt ( getParameter ( "port" ) ); setLayout ( new BorderLayout () ); add ( "Center" , ta); add ( "South" , tf); tf. addActionListener ( this ); try { Thread t = new Thread ( this ); socket = new Socket ( host, port ); din = new BufferedReader ( new InputStreamReader

(socket. getInputStream ())); dout = new PrintStream ( socket. getOutputStream () ); t. start (); }

Page 203: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

203

catch ( Exception e ) { System . out . println ( e. getMessage () ); } } public void actionPerformed ( ActionEvent e) { sendMessage (tf. getText ()); } private void sendMessage( String message ) { try { dout. println ( message ); tf. setText ( "" ); } catch ( Exception e ) { System . out . println ( e. getMessage () ); } } public void run() { try { while ( true ) { String message = din. readLine (); ta. append ( message + "\n" ); } } catch ( Exception e ) { System . out . println ( e. getMessage () ); } } }

Page 204: Java i objektno orijentirano programiranje

204

Zadaci za vježbu:

1. Što je protokol? 2. Što je IP adresa? 3. Koji su osnovni protokoli za komunikaciju putem Interneta i objasni svaki od njih. 4. Što je port? 5. Koliko portova postoji na računalu? 6. Koje portove je moguće koristiti u svojim aplikacijama? 7. Objasni klijent-server princip komunikacije. 8. Nabroji neke klase za mrežnu komunikaciju u Javi. 9. Kreirajte aplikaciju s grafičkim korisničkim sučeljem koja će omogućavati unos web

adrese te će klikom na gumb IP vraćati odgovarajuću IP adresu. 10. Što nam omogućavaju klase URL i URLConnection ? 11. Napišite applet koji će npr. s URL-a Hrvatske narodne banke (www.hnb.hr) uzimati tečaj

eura i dolara te ga ispisivati na Web stranici. 12. Što je socket? 13. Kreirajte mrežnu klijent-server aplikaciju koja će omogućiti komunikaciju izmeñu klijenta

i servera. Klijent učitava poruke sa standardnog ulaza i šalje ih serveru sve dok se s klijenta ne pošalje poruka KRAJ. Dakle aplikacija treba raditi sljedeće:

� klijent učitava poruku, � klijent šalje poruku serveru, � server preuzima poruku od klijenta, � server sva slova poruke pretvori u velika, � server pošalje poruku klijentu � klijent ispisuje poruku na izlaz � klijent učitava poruku sa standardnog ulaza � ... � Aplikaciju kreirajte s grafičkim korisničkim sučeljem.

14. Kreirajte mrežnu klijent-server aplikaciju koja će biti jednostavan Web server za tekstualne dokumente:

� klijentska aplikacija treba unositi ime dokumenta na serveru � klikom na gumb Učitaj sa servera se treba u poseban okvir učitati sadržaj

tekstualnog dokumenta sa servera, odnosno ukoliko dokument ne postoji treba ispisati odgovarajuću poruku

� server treba obraditi zahtjev klijenta i poslati sadržaj dokumenta klijentu � Aplikaciju kreirajte s grafičkim korisničkim sučeljem.

15. Objasni višenitnost (multithreading). 16. Izmijenite chat aplikaciju tako da:

a. Svaki korisnik može pri ulazu u chat unijeti svoje ime; b. Chat aplikacija treba kreirati tzv. log file, unutar tog log filea trebaju se nalaziti

čitava arhiva o chatu (tko je pristupio chatu, u koje vrijeme, što je pisao,...) 17. Kreirajte mrežnu aplikaciju koja će omogućiti slanje tekstualnih dokumenata s jednog

računala na drugo.

Page 205: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

205

17

Osnove baza podataka u Javi

� Što je baza podataka? � SQL (Structured Query Language) � Java i baze podataka � Još neki elementi grafičkog korisničkog sučelja

Page 206: Java i objektno orijentirano programiranje

206

U profesionalnom programerskom svijetu veliki dio programiranja svodi se na pisanje programa koje u svojoj pozadini imaju baze podataka. Cilj ovog poglavlja je naučiti raditi s bazama podataka te naučiti kako povezivati baze podataka s programima pisanim u Javi. O bazama podataka napisano je na stotine knjiga. Mi nećemo ulaziti u dubinu baza podataka, reći ćemo nekoliko osnovnih činjenice rada s bazama podataka koje će nam omogućiti izradu jednostavnog adresara ali i niza drugih, sličnih aplikacija. S bazama podataka ćemo se upoznati kreirajući jednostavan adresar. Adresar bi trebao biti program u kojem će se nalaziti podaci o osobama. Specifikacija programa U adresar će se spremati sljedeći podaci o osobi:

� ime � prezime � datum roñenja � telefon � mobitel � e-mail � adresa

Aplikacija treba imati sljedeće funkcionalnosti:

� dodavanje podataka o novim osobama � pretraživanje osoba prema svim kriterijima (ime, prezime, datum roñenja, telefon,

mobitel, e-mail, adresa) i to tako da omogućava pretraživanje s zamjenskim znakom *

� brisanje osoba iz adresara � izmjenu podataka o osobama u adresaru

Izvedba programa Program će biti napisan kao Java aplikacija. Podaci za program nalazit će se u Accessovoj bazi podataka, a pristupat će im se iz programa pomoću posebnih upita. Program će biti organiziran kroz dva različita sučelja:

� sučelje za unos podataka � sučelje za pretraživanje, brisanje i izmjenu podataka

Sučelja će biti implementirana kao tzv. jahači unutar jednog prozora, primjer takvog prozora s jahačima je:

Page 207: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

207

Slika 17-1 Prozor s tzv. jahačima (Font, Character Spacing, Text Effects)

U dijelu za unos nalazit će se tekstualna polja za unos: imena, prezimena, datuma roñenja, telefona, mobitela, e-maila, te područje za tekst za unos adrese. Na kraju će se nalaziti i jedan gumb Spremi. Klikom na gumb spremi će se u bazu podataka upisati podaci upisani u odgovarajuća pola za unos. Te će se ispisati odgovarajuća poruka ukoliko su podaci uspješno spremljeni u bazu, odnosno poruka o greški ako je došlo do greške prilikom spremanja podataka u bazu (krivi format datuma,...). Pretraživanje podataka biti će organizirano tako da će se neki od kriterija pretraživanja upisati u poseban okvir za tekst. Klikom na gumb Traži pretražit će se svi podaci u tablici. Ime i prezime svih osoba koje u nekom od svojih podataka (ime, prezime, telefon,...) imaju zadani kriterij bit će ispisani u posebnoj listi na ekranu. Klikom na odreñeni zapis u listi, podaci o odabranoj osobi bit će prikazani u odgovarajućim poljima te će se moči izmijeniti i spremiti izmjene. Isto tako će se klikom na osobu unutar popisa moći izbrisati ta osoba iz baze podataka.

Page 208: Java i objektno orijentirano programiranje

208

Što je baza podataka? Rekli smo da ćemo podatke o osobama čuvati unutar Accessove baze podataka. U nastavku ćemo reći nešto više o bazama podataka općenito te o kreiranju baze podataka u MS Accessu. Jednostavno rečeno, baza podataka je skup tablica u kojima su zapisani podaci. Svaka tablica sastoji se od stupaca, pri čemu svaki stupac ima svoje ime. Podaci su zapisani u redcima. Npr. tablica s popisom učenika neke škole, unutar neke baze podataka mogla bi izgledati ovako:

Ime Prezime Datum roñenja Spol Ines Marković 13.2.1987. M Ivana Bosanac 14.9.1988. Ž Iva Vekić 6.1.1977 Ž Matko Kuzmanić 13.9.1980 M

Kod tablica u bazi podataka dobro je uvijek imati stupac takav da podaci unutar njega jedinstveno odreñuju odreñeni redak. Pojednostavljeno rečeno. U našoj tablici trebao bi postojati stupac koji bi jedinstveno odreñivao svaki redak unutar tablice. U našoj tablici takvog stupca očito nema. Naime, ime definitivno nije takav stupac jer dvije osobe mogu imati isto ime. Slično je i s prezimenom, datumom roñenja te spolom. Takav stupac koji jedinstveno odreñuje podatke u retku zovemo primarni ključ (Primary key). U našoj bi tablici primarni ključ mogao biti npr. JMBG. Kao što znamo, ne može se dogoditi da dvije osobe imaju isti JMBG. Vrlo često se kao primarni ključ postavljaju brojevi koji se automatski povećavaju dodavanjem novog zapisa u tablicu. Pravi smisao primarnog ključa dobije se kada u bazi imamo više tablica čiji su podaci meñusobno povezani, no o tome ćemo govoriti nešto kasnije. Dakle, naša tablica s primarnim ključem, koji se automatski povećava dodavanjem novog zapisa, mogla bi izgledati ovako:

ID Ime Prezime Datum roñenja Spol 1 Ines Marković 13.2.1987. M 2 Ivana Bosanac 14.9.1988. Ž 3 Iva Vekić 6.1.1977 Ž 4 Matko Kuzmanić 13.9.1980 M

Danas postoji mnoštvo programa za rad s bazama podataka (MS SQL, Oracle, MySQL,...), nama najbliži, najjednostavniji i s daleko najmanjim brojem mogućnosti je MS Access. Radi se o programu koji dolazi u kompletu s MS Officeom. U nastavku ćemo naučiti kako u Accessu kreirati tablicu za naš Adresar. Primjer 17 – 1: Kreirajmo tablicu koja će sadržavati sve stupce potrebne za program Adresar. Rješenje: Pokrenimo MS Access. Ovdje ćemo raditi na MS Accessu XP, sve ostale verzije vrlo su slične.

Page 209: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

209

Slika 17-2. Prozor MS Accessa

U desnom dijelu prozora odaberemo Blank Database. Odaberemo mapu gdje želimo spremiti bazu te upišemo ime (adresar.mdb) i kliknemo na gumb Save.

Page 210: Java i objektno orijentirano programiranje

210

Slika 17-3. Glavni prozor za rad s bazom podataka

U prozoru koji se otvori, kliknemo na sličicu Tables u lijevom dijelu prozora, te odaberemo New u gornjem dijelu prozora.

Slika 17-4. Prozor za kreiranje tablice unutar baze podataka

Kliknemo na Design View te definirajmo stupce unutar tablice:

Slika 17-5. Definiranje stupaca tablice

U stupac Field name upisivat ćemo nazive stupaca. Dok ćemo pod Dana Type odabirati tip vrijednosti koje ćemo upisivati unutar stupaca. Najčešći tipovi vrijednosti je Text odnosno Number za unos teksta odnosno brojeva. Često se još koriste i Date za datum i vrijeme, te Autonumber koji označava da se vrijednost stupca automatski povećava za 1. Mi ćemo kreirati sljedeće stupce:

� ID – Autonumber � ime – Text, najviše 30 znakova

Page 211: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

211

� prezime – Text, najviše 30 znakova � datumR – Date/Time, Short Date � telefon – Text, najviše 30 znakova � mobitel – Text, najviše 30 znakova � e-mail – Text, najviše 30 znakova � adresa – Text, najviše 255 znakova

Nadalje ćemo definirati da je ID primarni ključ na tablici. To ćemo napraviti tako da kliknemo desnim gumbom miša na stupac ID te u izborniku koji se otvori odaberemo Primary Key.

Slika 17-6. Definiranje primarnog ključa

Na kraju kliknemo na gumb Save odnosno File →→→→ Save, upišemo ime tablice (adresar) te kliknemo na gumb OK.

Slika 17-7. Definirana tablica adresar

Page 212: Java i objektno orijentirano programiranje

212

SQL (Structured Query Language) U tako definiranu tablicu podatke možemo unositi, mijenjati, brisati,... direktno preko sučelja MS Accessa, no nas u stvari zanima nešto drugo. Naime, mi u svojoj aplikaciji nećemo otvarati MS Access i u njega upisivati podatke, mijenjati ih,... već bismo htjeli da to radi naša aplikacija. Manipulaciju podacima unutar baze podataka omogućuje nam SQL. SQL je skraćenica za Structured Query Language, a radi se o jeziku za manipulaciju podacima unutar tablica baze podataka. Četiri su osnovna tipa upita (Query):

� INSERT � SELECT � UPDATE � DELETE

Upit INSERT Upit INSERT koristit ćemo svaki put kada budemo dodavali podatke u tablicu. Opći oblik naredbe INSERT je:

INSERT INTO ime_tablice (st1, st2,... stn) VALUES (v1, v2,... vn)

pri čemu su st1, st2,... stn , nazivi stupaca, dok su v1, v2,... vn odgovarajuće vrijednosti. Sve upite ćemo u MS Accessu izvršavati u posebnom prozoru za upite. Za početak otvorimo bazu podataka adresar.mdb. Primjer 17 – 2: Dodajmo u tablicu adresar osobu sa sljedećim podacima: Ime: Ines Prezime: Marković Datum roñenja: 13. 2. 1987. Telefon: 01123456 Mobitel: 095123456 Adresa: V. avenija 23, 10000 Zageb. Rješenje: Pokrenimo Access te otvorimo tablicu adresar.mdb, koju smo kreirali u prošlom primjeru. U popisu s desne strane odaberemo sličicu Queries. U gornjem popisu odaberemo New a zatim Design View, te kliknemo na OK.

Page 213: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

213

Slika 17-8. Odabir načina kreiranja upita

U prozoru koji se pojavi kliknemo na Close.

Slika 17-9. Popis tablica za upit

U gornjem dijelu glavnom prozora kliknemo na sličicu SQL, te u izborniku koji se otvori odaberemo SQL View (View →→→→ SQL View).

Slika 17-10. Odabir sučelja za kreiranje upita

Odabirom ove opcije otvorit će se sljedeći prozor:

Page 214: Java i objektno orijentirano programiranje

214

Slika 17-11. Prozor za unos upita

U prozor koji se pojavio upisat ćemo sljedeći upit za dodavanje podataka: INSERT INTO adresar (ime, prezime, datumR, mobitel, telefon, a dresa) VALUES ('Ines', 'Markovi ć', '13.2.1987', '01123456', '095123456', 'V. avenija 23, 10000 Zagreb')

Kliknemo na gumb Execute ( ) i ukoliko je sve u redu, pojavit će se prozor s porukom:

Slika 17-12. Upit je uspješno izvršen

Otvorimo tablicu adresar i u njoj ćemo vidjeti redak s podacima koje smo upravo dodali: Napomena: Primijetimo da stupce u upitu nismo naveli onim redoslijedom kojim se nalaze u tablici, bitno je samo da redoslijed stupaca odgovara redoslijedu vrijednosti koje se žele dodati u odgovarajuće stupce tablice. Isto tako mogli smo primijetiti da jedan stupac u tablici postoji, ali ga nema u upitu, radi se o stupcu email. Pogledamo li u tablicu vidjet ćemo da u tom stupcu nema vrijednosti za osobu koju smo unijeli u tablicu, što je i za razumno. Kao što smo mogli primijetiti u primjeru, vrijednosti koje smo dodavali u tablicu pisali smo unutar jednostrukih navodnika, to je u principu uvijek tako osim kada se dodaju brojevi, koji se ne pišu unutar jednostrukih navodnika. Isto tako je moguće i datume pisati bez navodnika. Upit SELECT SELECT ćemo koristiti kada iz tablice budemo htjeli izdvojiti podatke prema nekom kriteriju. Opći oblik naredbe SELECT je:

SELECT st1, st2,... stn FROM ime_tablice WHERE uvjet1 AND/OR uvjet2 AND/OR... AND/OR uvjetm

pri čemu su st1, st2,... stn nazivi stupaca čije vrijednosti želimo da nam vrati upit, dok je uvjet1, ..., uvjetm uvjeti odgovarajući uvjeti koji su najčešće oblika:

Page 215: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

215

� ime_stupca [operator] vrijednost pri čemu je operator jedan od relacijskih operatora (=, <, >, <>).

� ime_stupca like vrijednost Ovakvim uvjetom najčešće se traže podaci koji "su slični" zadanoj vrijednosti. U tom se slučaju može koristiti zamjenski znak * koji zamjenjuje jedan ili više znakova. Moguće je pisati SELECT upite i bez uvjeta, u tom slučaju nećemo imati WHERE. Rezultat upita je jedna privremena tablica. Primjer 17 – 3: Ispišimo imena prezimena, brojeve mobitela te adrese svih osoba koje se zovu Ines i prezime započinje slovom M. Rješenje: SELECT ime, prezime, mobitel, adresa FROM adresar WHERE ime = 'Ines' AND prezime LIKE 'M*'

Napomena: Želimo li da nam upit vrati sve stupce umjesto nabrajanja svih ćemo jednostavno napisati *. Npr. SELECT * FROM adresar će nam ispisati sve podatke iz tablice adresar. Upit UPDATE UPDATE ćemo koristiti za ažuriranje (izmjenu) podataka u tablici. Opći oblik ove naredbe je:

UPDATE ime_tablice SET st1 = vr1, st2 = vr2,... stn = vrn WHERE uvjet1 AND/OR uvjet2 AND/OR... AND/OR uvjetm

Nakon izvršavanja ovog upita, svim zapisima koji zadovoljavaju zadane kriterije bit će, za stupac st1, postavljena vrijednost na vr1, stupac st2 će imati vrijednost vr2,... dok će stupac stn imati vrijednost vrn. Primjer 17 – 4: Izmijenimo podatke u tablici adresar tako da svim osobama koji u broju mobitela imaju broj 95 izbrišemo broj mobitela (postavimo ga na prazan string). Rješenje: UPDATE adresar SET mobitel = '' WHERE mobitel LIKE '*95*'

Page 216: Java i objektno orijentirano programiranje

216

Upit DELETE Kao što je i za pretpostaviti DELETE ćemo koristiti kada budemo htjeli brisati čitave zapise iz tablice. Opći oblik naredbe DELETE je:

UPDATE FROM ime_tablice WHERE uvjet1 AND/OR uvjet2 AND/OR... AND/OR uvjetm

Izvršavanjem ove naredbe iz tablice ime_tablice bit će izbrisani svi podaci koji zadovoljavaju postavljene uvjete. Primjer 17 – 5: Izbrišimo sve osobe iz tablice adresar. Rješenje: DELETE FROM adresar

Page 217: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

217

Java i baze podataka SQL o kojem smo upravo govorili je standardiziran za rad s različitim tipovima baza podataka (MS Access, MS SQL, ORACLE,...). U principu to znači da ćemo pomoću istog SQL upita dodavati podatke, u bazu kreiranu u Accessu ili MS SQL-u odnosno ORACLU i upravo u tome leži njegova snaga. Da bismo iz vlastitog programa mogli komunicirati s bazom podataka, prvo se moramo spojiti na bazu podataka. E to baš i nije tako jednostavno. Način spajanja ovisi o tipu baze podataka,... što uvelike komplicira stvari. Meñutim, nije baš sve tako crno, u pomoć nam dolazi JDBC. JDBC (Java Database Connectivity) omogućava nam jednostavnu komunikaciju s bazom podataka. Radi se o sučelju za komunikaciju s bazama podataka. Naša aplikacija treba samo poslati odgovarajuće parametre i JDBC će sam obaviti sve potrebne radnje kako bismo uspostavili komunikaciju s bazom podataka i pomoću SQL upita izvršavali odreñene manipulacije s podacima. Meñutim postoji jedan problem, JDBC ne radi sa svim tipovima baza podataka. Osim JDBC-a postoji još i tzv. ODBC (Open Database Connectivity) koje je u stanju spojiti se sa svim tipovima baza podataka. Na žalost, Java ne omogućava spajanje na bazu podataka pomoću ODBC-a, ali zato postoji spona koja je u stanju translatirati JDBC u ODBC. Radi se o svojevrsnom mostu izmeñu JDBC-a i ODBC-a tzv. JDBC-ODBC bridge. Uz puno preznojavanja, muke i priče konačno smo u stanju spojiti se s bilo kojom bazom podataka. Kako bismo se spojili s bazom podataka pomoću moramo unutar programa napraviti nekoliko predradnji. Prvo što moramo napraviti je reći da želimo komunicirati s ODBC-em preko JDBC-ODBC bridgea. To ćemo napraviti izvršavanjem naredbe: Class . forName ( "sun.jdbc.odbc.JdbcOdbcDriver" );

Ukoliko je ova naredba uspješno izvršena spremni smo za kreiranje veze prema bazi podataka, koja će nam omogućiti direktnu komunikaciju s bazom podataka, koja će uključivati izvršavanje SQL upita. Povezivanje s bazom podataka Povezivanje s bazom podataka omogućit će nam metode klase DriverManager . DriverManager je static klasa, a neke od njenih, češće upotrebljavanih metoda su: static Connection getConnection (String s) – na osnovu opisa veze prema bazi podataka (s), ova metoda uspostavlja vezu s bazom podataka te vraća objekt tipa Connection koji predstavlja konekciju static Connection getConnection (String s, String i me, String lozinka) – na osnovu opisa veze prema bazi podataka (s), korisničkog imena (ime) i lozinke (lozinka), ova metoda uspostavlja vezu s bazom podataka. te vraća objekt tipa Connection koji predstavlja konekciju Ukoliko se spajamo s Access bazom podatak, string s koji opisuje vezu prema bazi je sljedećeg oblika: jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)}; DBQ=ime.mdb

pri čemu je ime.mdb čitav put do Accessovog dokumenta u kojem je spremljena naša baza podataka.

Page 218: Java i objektno orijentirano programiranje

218

Klasa Connection sadrži sve potrebne informacije o otvorenoj vezi prema bazi podataka. Neke od metoda ove klase su: void close () – zatvara konekciju prema bazi Statement createStatement () – kreira objekt tipa Statement koji će nam omogućiti slanje SQL upita bazi boolean isClosed () – vraća true ako je veza prema bazi zatvorena, inače vraća false Za izvršavanje SQL upita na bazi podataka koristit ćemo metode klase Statement . Najvažnije metode ove klase su: boolean execute (String s) – izvršava upit (s) tipa INSERT, UPDATE, DELETE ResultSet executeQuery (String s) – izvršava upit (s) koji je tipa SELECT i rezultate vraća u obliku objekta tipa ResultSet void close () – zatvara Statement objekt Rezultat SELECT upita vraća se u obliku ResultSeta . ResultSet možemo zamisliti kao tablicu u kojoj se nalaze rezultati upita. Nakon što se upit izvrši i rezultati upita se smjeste u ResultSet , preostaje nam još pročitati podatke iz ResultSeta te ih na neki način prikazati u aplikaciji. Rezultate ćemo čitati tako da s kursorom prolazimo red po red ResultSeta i čitamo podatke iz odgovarajućih stupaca unutar trenutnog reda. To će nam omogućiti metode klase ResultSet : boolean absolute (int n) – postavlja kursor u n-ti redak ResultSeta void afterLast () – postavlja kursor na kraj ResultSeta (iza zadnjeg zapisa) void beforeFirst () – postavlja kursor na početak ResultSeta (ispred prvog zapisa) void close () – zatvara ResultSeta objekt void deleteRow () – biše trenutni redak unutar ResultSeta int findColumn (String s) – vraća redni broj stupca s imenom s unutar trenutnog ResultSeta boolean first () – postavlja kursor na prvi redak ResultSeta boolean getBoolean (String s) – vraća logičku vrijednost koja se nalazi u trenutnom retku u stupcu s imenom s danog ResultSeta boolean getBoolean (int n) – vraća logičku vrijednost koja se nalazi u trenutnom retku u stupcu s rednim brojem n danog ResultSeta Date getDate (String s) – vraća datum koji se nalazi u trenutnom retku u stupcu s imenom s danog ResultSeta Date getDate (int n) – vraća datum koji se nalazi u trenutnom retku u stupcu s rednim brojem n danog ResultSeta float getFloat (String s) – vraća realnu vrijednost koja se nalazi u trenutnom retku u stupcu s imenom s danog ResultSeta float getFloat (int n) – vraća realnu vrijednost koja se nalazi u trenutnom retku u stupcu s rednim brojem n danog ResultSeta int getInt (String s) – vraća cjelobrojnu vrijednost koja se nalazi u trenutnom retku u stupcu s imenom s danog ResultSeta int getInt (int n) – vraća cjelobrojnu vrijednost koja se nalazi u trenutnom retku u stupcu s rednim brojem n danog ResultSeta int getRow () – vraća redni broj trenutnog retka unutar ResultSeta String getString (String s) – vraća tekstualnu vrijednost koja se nalazi u trenutnom retku u stupcu s imenom s danog ResultSeta

Page 219: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

219

String getString (int n) – vraća tekstualnu vrijednost koja se nalazi u trenutnom retku u stupcu s rednim brojem n danog ResultSeta boolean isAfterLast () – vraća true ako je kursor iza zadnjeg reda ResultSeta , inače vraća false boolean isBeforeFirst () – vraća true ako je kursor ispred prvog reda ResultSeta , inače vraća false boolean isFirst () – vraća true ako je kursor na prvom elementu ResultSeta , inače vraća false boolean isLast () – vraća true ako je kursor na zadnjem elementu ResultSeta , inače vraća false boolean last () – postavlja kursor na zadnji redak ResultSeta boolean next () – pomiče kursor na sljedeći redak ResultSeta boolean previous () – pomiče kursor na prethodni redak ResultSeta boolean relative (int n) – pomiče kursor za n redaka, s obzirom na trenutni redak unutar ResultSeta Sve gore navedene klase za rad s bazama podataka nalaze se unutar posebnog paketa: java.sql , koji ćemo morati pozvati unutar aplikacije koja će raditi s bazama podataka.

Još neki elementi grafičkog korisničkog sučelja Sa aspekta baza podataka znamo sve potrebno za kreiranje aplikacije. Preostaje nam još nešto reći o elementima grafičkog korisničkog sučelja kakve još nismo susreli:

� jahačima, � liste

Prisjetimo se naša aplikacija treba imati dva sučelja:

� sučelje za unos podataka � sučelje za pretraživanje, izmjenu i brisanje podataka

Sučelja trebaju biti implementirana pomoću dva jahača na jednom prozoru, a rezultati upita (imena i prezimena osoba) će se ispisivati unutar liste. Klikom na neko ime unutar liste, svi podaci o toj osobi bit će prikazani u posebnim poljima. Jahači Izgled jahača možemo vidjeti na slici 17-1. Kao i za sve ostale elemente Java ima posebnu klasu koja će nam omogućiti kreiranje jahača. Područje na koje ćemo slagati jahače kreirat ćemo klasom JTabbedPane . Neki od konstruktora ove klase su: JTabbedPane () – kreira prazno područje za jahače, pri čemu su jahači inicijalno okrenuti prema gore (JTabbedPane.TOP ) JTabbedPane (int p) – kreira prazno područje za jahače, pri čemu je smjer jahača odreñen parametrom p: JTabbedPane.TOP – gore JTabbedPane.BOTTOM – dolje JTabbedPane.LEFT – lijevo JTabbedPane.RIGHT – desno

Page 220: Java i objektno orijentirano programiranje

220

Kao što smo rekli klasa JTabbedPane nam omogućava kreiranje područja na koje ćemo stavljati jahače. Jahače, koje ćemo stavljati unutar područja, kreirat ćemo posebnom klasom JPanel . Najčešće korišteni konstruktor klase JPanel je: JPanel () – kreira objekt klase JPanel Izmeñu ostalih, klasa JPanel nasljeñuje klasu Container što znači da je na njega moguće dodavati elemente grafičkog korisničkog sučelja metodom add () , definirati Layout,... JPanel ćemo dodati JTabbedPane posebnom metodom addTab () . Osim metode addTab () klasa JTabbedPane ima i niz drugih metoda, a neke od njih su: void addTab (String s, Component c) – dodaje komponentu c na JTabbedPane pri čemu će naslov komponente biti s void addTab (String s, Icon i, Component c) – dodaje komponentu c na JTabbedPane pri čemu će naslov komponente biti s, dok će sličica komponente biti i void addTab (String s, Icon i, Component c, String t) – dodaje komponentu c na JTabbedPane pri čemu će naslov komponente biti s, sličica će biti i, dok će tooltip tekst biti t int getSelectedIndex () – vraća redni broj trenutno aktivnog jahača int getTabCount () – vraća ukupni broj jahača unutar JTabbedPanea void remove (int i) – briše jahač s rednim brojem i void setColorAt (int i, Color c) – definira pozadinsku boju za jahač s rednim brojem i Lista Lista na prvi pogled ima slične karakteristike kao padajuća lista (JOptionPane ), meñutim rad s listama je u Javi je znatno složenija od rada s padajućim listama. No to svakako nije razlog da ne kažemo nešto i o njima. Klasa koja će kreirati listu na ekranu je JList . Najčešći konstruktori ove klase su: JList () – kreira objekt klase JList JList (ListModel m) – kreira objekt klase JList koji će prikazivati podatke iz zadanog modela m Najčešće korištene metode klase JList su: void addListSelectionListener (ListSelectionListene r l) – kreira listener na listi koji prati svaku promjenu na označenoj stavki liste int getSelectedIndex () – vraća redni broj prve označene stavke unutar liste, ukoliko niti jedna stavka nije označena vraća -1 int[] getSelectedIndices () – vraća niz sa rednim indeksima svih označenih stavki liste Object getSelectedValue () – vraća prvu označenu stavku unutar liste, ukoliko niti jedna stavka nije označena vraća null Object[] getSelectedValues () – vraća niz sa vrijednostima svih označenih stavki liste boolean isSelectedIndex (int n) – vraća true ako je element na n-tom mjestu označen boolean isSelectionEmpty () – vraća true ako niti jedan element liste nije označen void setModel (ListModel m) – postavlja model m, koji predstavlja sadržaj liste void setSelectecIndex (int n) – označava stavku liste na n-tom mjestu

Page 221: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

221

void setSelectedIndices (int[] a) – označava skup stavki, čiji su redni brojevi elementi niza a void setSelectionBackground (Color c) – definira pozadinsku boju označene stavke void setSelectionForeground (Color c) – definira boju teksta označene stavke void setSelectionInterval (int s, int k) – označava interval stavki Želimo li pratiti dogaćaje na listi, morat čemo u aplikaciji implementirati i još jedan interface. Radi se o interfaceu ListSelectionListener , te ćemo trebati definirati metodu: void valueChanged(ListSelectionEvent e)

Kao što možemo primijetiti nema metode kojom ćemo dodati stavku u listu. Ne, nismo ju zaboravili, ona jednostavno ne postoji. Stvar je u tome da je JList samo "ljuska" za popis stavki koje će se u njoj nalaziti. Popis stavki koje će biti ispisane u listi nalazi se u posebnom objektu. Mi ćemo stavke držati u objektu koji će biti tipa DefaultListModel . DefaultListModel je posebna klasa koja će brinuti o sadržaju liste. Samo je jedan konstruktor ove klase: DefaultListModel () – kreira objekt klase DefaultListModel Neke od metoda klase DefaultListModel su: void add (int n, Object o) – dodaje objekt na odreñeno mjesto u listi void add (Object o) – dodaje objekt na posljednje mjesto u listi void clear () – briše sve stavke liste boolean contains (Object o) – provjerava je li o element liste boolean contains (Object o) – provjerava je li o element liste Object elementAt (int n) – vraća element koji se nalazi na n-tom mjestu liste int getSize () – vraća broj elemenata liste boolean isEmpty () – provjerava ima li lista elemenata void removeElementAt (int n) – iz liste briše element na n-tom mjestu Object[] toArray () – vraća niz koji sadrži sve elemente liste u onom redoslijedu u kojem se pojavljuju u listi Sada uistinu imamo sve potrebno za kreiranje aplikacije:

Page 222: Java i objektno orijentirano programiranje

222

Service Port Protocol

echo 7 tcp

echo 7 udp

discard 9 tcp

discard 9 udp

systat 11 tcp

systat 11 tcp

daytime 13 tcp

daytime 13 udp

netstat 15 tcp

qotd 17 tcp

qotd 17 udp

chargen 19 tcp

chargen 19 udp

ftp-data 20 tcp

ftp 21 tcp

telnet 23 tcp

smtp 25 tcp

time 37 tcp

time 37 udp

rlp 39 udp

name 42 tcp

name 42 udp

whois 43 tcp

domain 53 tcp

domain 53 udp

nameserver 53 tcp

nameserver 53 udp

mtp 57 tcp

bootp 67 udp

tftp 69 udp

gopher 70 tcp

rje 77 tcp

finger 79 tcp

http 80 tcp

link 87 tcp

supdup 95 tcp

hostnames 101 tcp

iso-tsap 102 tcp

dictionary 103 tcp

x400 103 tcp

x400-snd 104 tcp

Page 223: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

223

csnet-ns 105 tcp

pop 109 tcp

pop2 109 tcp

pop3 110 tcp

portmap 111 tcp

portmap 111 udp

sunrpc 111 tcp

sunrpc 111 udp

auth 113 tcp

sftp 115 tcp

path 117 tcp

uucp-path 117 tcp

nntp 119 tcp

ntp 123 udp

nbname 137 udp

nbdatagram 138 udp

nbsession 139 tcp

NeWS 144 tcp

sgmp 153 udp

tcprepo 158 tcp

snmp 161 udp

snmp-trap 162 udp

print-srv 170 tcp

vmnet 175 tcp

load 315 udp

vmnet0 400 tcp

sytek 500 udp

biff 512 udp

exec 512 tcp

login 513 tcp

who 513 udp

shell 514 tcp

syslog 514 udp

printer 515 tcp

talk 517 udp

ntalk 518 udp

efs 520 tcp

route 520 udp

timed 525 udp

tempo 526 tcp

courier 530 tcp

conference 531 tcp

rvd-control 531 tcp

Page 224: Java i objektno orijentirano programiranje

224

netnews 532 tcp

netwall 533 udp

uucp 540 tcp

klogin 543 tcp

kshell 544 tcp

new-rwho 550 udp

remotefs 556 tcp

rmonitor 560 udp

monitor 561 udp

garcon 600 tcp

maitrd 601 tcp

busboy 602 tcp

acctmaster 700 udp

acctslave 701 udp

acct 702 udp

acctlogin 703 udp

acctprinter 704 udp

elcsd 704 udp

acctinfo 705 udp

acctslave2 706 udp

acctdisk 707 udp

kerberos 750 tcp

kerberos 750 udp

kerberos_master 751 tcp

kerberos_master 751 udp

passwd_server 752 udp

userreg_server 753 udp

krb_prop 754 tcp

erlogin 888 tcp

kpop 1109 tcp

phone 1167 udp

ingreslock 1524 tcp

maze 1666 udp

nfs 2049 udp

knetd 2053 tcp

eklogin 2105 tcp

rmt 5555 tcp

mtb 5556 tcp

man 9535 tcp

w 9536 tcp

mantst 9537 tcp

bnews 10000 tcp

rscs0 10000 udp

Page 225: Java i objektno orijentirano programiranje

Java i objektno orijentirano programiranje

225

queue 10001 tcp

rscs1 10001 udp

poker 10002 tcp

rscs2 10002 udp

gateway 10003 tcp

rscs3 10003 udp

remp 10004 tcp

rscs4 10004 udp

rscs5 10005 udp

rscs6 10006 udp

rscs7 10007 udp

rscs8 10008 udp

rscs9 10009 udp

rscsa 10010 udp

rscsb 10011 udp

qmaster 10012 tcp

qmaster 10012 udp

irc 6667 tcp