Predavanje br. index|1|2|3|4|5|6|7|8|9|10|11|12|13|14|HOME


Peto predavanje – appleti

HTML, jezik za oblikovanje web stranica - URL, jedinstvena adresa dokumenta – dijelovi URLa – linkovi – relativni URLovi – applet Hello World – što je applet? – HTML oznaka <applet> - odabir pozicije na stranici – alternativni tekst – imenovanje appleta – JAR arhive – HTML oznaka <object> - veličina appleta – HTML oznaka <param> - obrada nepoznatog broja parametara – sigurnost appleta – što applet može činiti? – s kim applet može komunicirati? – koliko CPU vremena applet dobija? – sigurnost i social engineering – sprečavnje hakerskih napada kroz applete – Životni ciklus appleta – metode init(), start(), stop() i destroy() – koordinatni sustav – objekti klase Graphics – crtanje linija – crtanje pravokutnika – punjenje pravokutnika – brisanje pravokutnika – elipse i kružnice – primjer, bullseye – poligoni – višestruke linije (polylines) – učitavanje slika – metode getCodeBase() i getDocumentBase() – prikaz slike u pravoj veličini – skaliranje slika – boje – sistemske boje – fontovi – odabir oblika i veličine fonta – klasa FontMetrics


HTML - jezik za oblikovanje web stranica

HTML znači HyperText Markup Language. HTML datoteke su tekstualne datoteke u kojima su dijelovi teksta označeni pomoću tagova (oznaika). Ekstenzija takve datlteke je .htm ili .html. Evo primjera jedne jednostavne HTML datoteke:

 
<html>
<head>
<title>Moj prvi HTML Document</title>
</head>
<body>
<h1>Zaglavlje veličine 1</h1>
 
Ovdje se piše vidljivi dio dokumenta.
Ovako se <STRONG>naglašava</STRONG> sadržaj.
 
</body>
</html>

Elementi koji su zatvoreni u trokutastim zagradama kao <html>, <head>, and <title> >zovu se oznake (tags). Oznake se mogu pisati velikim ili malim slovima (nisu case sensitive).

Većina oznaka ima zatvarač koji definira doseg oznake. Zatvarač ima isto ime kao i oznaka, ali mu je dodan slash (/) nakon otvorene zagrade. Na primjer, </html>, </head>, i </title> su zatvarači. Tekst između <title> i </title>, Moj prvi HTML dokument iz gornjeg primjera, predstavlja naslov stranice.

Oznake se u pravilu mogu pisati unutar drugih oznaka, ali se ne mogu preklapati.

Neke oznake imaju dodatne atribute (to nije isto što i atributi u Javi). Atribut je ime iza kojeg slijedi znak jednakosti i vrijednost, a zajedno s oznakom pobliže određuje način interpretacije teksta. Na primjer, da bismo zaglavlje H1 centrirali, možemo koristiti atribut ALIGN i dati mu vrijednost center; tj.

<h1 align="center">Zaglavlje veličine 1</h1>
 

Atributi su također case-insensitive. Dvostruki navodnici oko vrijednosti su opcionalni osim ako vrijednost sadrži bjeline.Za potpunu informaciju o HTML-u pogledajte HyperText Markup Language na W3C - World Wide Web Consortium.


URL – jedinstvena adresa dokumenta

URL je kratica za uniform resource locator. To je pointer na određeni resurs na nekoj lokaciji na Internetu. Na primjer, http://student.math.hr/~vedris/ ili http://student.math.hr/~vedris/java/java-predavanje-05.htm su URLovi.

URL specificira protokol za pristup poslužitelju, npr. ftp, http, ime poslužitelja, lokaciju datoteke na poslužitelju i eventualno lokaciju nekog mjesta (sidro, anchor) unutar datoteke. Opći oblik URLa je

protocol://hostname[:port]/path/filename#section


Dijelovi URL-a

Protokol je uglavnom jedan od sljedećih:

 

Hostname (ime poslužitelja) mora biti valjano mrežno ime hosta na Internetu, a može biti i IP adresa, npr student.math.hr, www.ora.com or shock.njit.edu ali i 204.29.207.217 ili 128.235.252.184.

Port (broj porta) je opcionalan Za http je default port 80.

Path (put do datoteke) pokazuje određeni direktorij na poslužitelju. Formira se u odnosu na početni direktorij servisa (server root, document root) koji ne mora biti (i obično nije) nužno početni direktorij (root) sustava datoteka (file system). Cijeli sustav datoteka obično se ne otkriva javnosti.

Filename (ime datoteke) pokazuje na određenu datoteku unutar navedenog direktorija. Na mnogim poslužiteljima uobičajeno je da se, ako je ime datoteke izostavljeno, podrazumijeva datoteka index.html. Na drugima će se dobiti ispis direktorija, a neki će poslati poruku o pogreški.

Section (mjesto unutar datoteke) referencira imenovano sidro (anchor) unutar HTML dokumenta. Ono se označava ovako:

<A NAME="xtocid1902914">Comments</A>
 

URL koji pokazuje na to sidro sadrži nakon imena datoteke još i ime sidra ispred kojeg je znak #, na primjer ovako:

 
http://metalab.unc.edu/javafaq/javafaq.html#xtocid1902914

Linkovi

Da biste u HTML datoteci napravili link od dijela teksta, zatvorit ćete ga unutar oznaka <A> i </A>. Oznaci <A> dodat ćete atribut HREF i u njemu navesti url na koji želite usmjeriti vaš link. Na primjer,

 
Ovaj link pokazuje na 
<A HREF="http://student.math.hr/~vedris/java/java-predavanja/java-predavanje-05.htm">
peto predavanje iz Jave
</A> 
na PMF-u.
 

Većina browsera će tako označeni tekst prikazati podvučeno, u plavoj ili ljubičastoj boji, no to ovisi o podešenosti browsera. Klikanjem na taj dio teksta prikazat će se resurs koji je naveden u pripadnom URLu.


Relativni URL-ovi

When a web browser reads an HTML document, it has a great deal of information about the document. This includes the protocol used to retrieve the document, the name of the host where the document lives, and the path to that document on the host. Most of this is likely to be the same for many of the URLs in that document. Relative URLs inherit the protocol, hostname, and path of their parent document rather than respecifying it in each <A HREF> tag. Thus if any piece of the URL is missing, it is assumed to be the same as that of the document in which the URL is found. Such a URL is called a relative URL. In contrast, a completely specified URL is called an absolute URL. Na primjer, ako pregledavajući dokument http://metalab.unc.edu/javafaq/books.html kliknete na sljedeći hiperlink:

 
<a href="javafaq.html">the FAQ</A>
 

Browser će odrezati books.html sa završetka izraza http://metalab.unc.edu/javafaq/books.html i ostaviti http://metalab.unc.edu/javafaq/, a zatim pripojiti javafaq.html na završetak izraza http://metalab.unc.edu/javafaq/ da bi dobio http://metalab.unc.edu/javafaq/javafaq.html.

Ako relativni link počinje sa /, onda je on relativan u odnosu na document root umjesto na trenutno aktivnu datoteku.. Znači, ako prilikom pregledavanja datoteke http://metalab.unc.edu/javafaq/books.html kliknete na hiperlink

<a href="/boutell/faq/www_faq.html">
 

browser će odbaciti /javafaq/javafaq.html i pripojiti /boutell/faq/www_faq.html na završetak izraza http://metalab.unc.edu/ da bi dobio http://metalab.unc.edu/boutell/faq/www_faq.html.

Relativni URLovi imaju raznih prednosti. Smanjuju količinu potrebnog tipkanja, ali što je još važnije, omogućuju premiještanje cijelih stabala HTML dokumenata bez narušavanja njihovih internih linkova


Applet Hello World

Jedan od razloga popularnosti Jave je mogućnost pisanja interaktivnih appleta na webu. Program Hello World nije baš interaktivan, no pogledajmo svejedno njegovu web verziju:

import java.applet.Applet;   
import java.awt.Graphics; 
 
public class HelloWorldApplet extends Applet {
 
  public void paint(Graphics g) {
    g.drawString("Hello world!", 50, 25);
  }
  
} 

Primjećujete da je applet Hello World nešto složeniji nego aplikacija, a ima i nešto dodatnog posla da bi ga se pokrenulo.

Najprije spremite izvorni kod u datoteku HelloWorldApplet.java. Kompilirajte je na uobičajeni način. Dobit ćete klasu HelloWorldApplet.class. Da biste je pokrenuli, potrebno je napraviti HTML dokument koji će sadržati naš applet. Evo jednog takvog dokumenta:

<HTML>
<HEAD>
<TITLE> HelloWorldApplet</TITLE>
</HEAD>
 
<BODY>
Ovo je applet HelloWorld:<P>
<applet code="HelloWorldApplet.class" width="150" height="50">
</applet>
</BODY>
</HTML>

Spremite tu datoteku pod imenom HelloWorldApplet.html u isti direktorij gdje se nalazi datoteka HelloWorldApplet.class. Pogledajte tu HTML datoteku pomoću nekog standardnog (Java enabled) browsera kao što je Internet Explorer, Netscape ili Applet viewer koji se nalazi u JDK paketu. Vidjet ćete string Hello World unutar pravokutnika veličine 150x50 točaka.

Hello World!Applet: HelloWorldApplet

Ako je kompilacija prošla bez pogreške, a ne vidite string Hello World, provjerite da li je klasa u istom direktoriju kao i HTML datoteka. Također budite sigurni da koristite dovoljno novu verziju browsera, koja podržava Javu. Ako ni Applet Viewer ne vidi vaš applet, pogreška je vjerojatno u appletu, a ne u browseru.


Što je Applet?

Applet je mala aplikacija koja je zamišljena da se ne izvršava samostalno, nego unutar druge aplikacije, tipično unutar web browsera. Klasa java.applet.Applet osigurava standardno sučelje između appleta i njihove okoline. Evo što se sve naziva appletom:

Ovo je hijerarhija njenih nadklasa:

 
java.lang.Object
   |
   +---java.awt.Component
           |
           +---java.awt.Container
                   |
                   +---java.awt.Panel
                           |
                           +---java.applet.Applet

HTML oznaka <APPLET>

Appleti se u HTML stranicu ugrađuju pomoću oznaka <APPLET> i </APPLET>. Oznaka <APPLET> se ponaša lično kao <IMG>. Kompilirana klasa koja sadrži appletov kod referencira se pomoću atributa CODE. Njezina je lokacija relativna u odnosu na izvorni HTML dokument. Na primjer, ako pregledavate stranicu http://metalab.unc.edu/javafaq/index.html, a ta stranica referencira applet pomoću CODE="Animation.class", onda bi datoteka Animation.class trebala biti na adresi http://metalab.unc.edu/javafaq/animation.class.

Međutim, suprotno od uobičajene prakse, ako se applet nalazi negdje drugdje, a ne u istom direktoriju kao i HTML dokument, ne možete u atributu <CODE> jednostavno navesti njegov URL, nego umjesto toga morate koristiti još i atribut CODEBASE u kojem ćete navesti dio URLa koji pokazuje put do appleta. Na primjer, da je HTML stranica s našim appletom HelloWorldApplet bila napisana kao

<APPLET CODE="HelloWorldApplet.class" CODEBASE="classes" 
WIDTH=200 HEIGHT=200>
</APPLET>
 

onda bi browser pokušao tražiti klasu HelloWorldApplet.class u poddirektoriju classes onog direktorija u kojem se nalazi HTML dokument. Također, ako napišemo

 
<APPLET CODE="HelloWorldApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes" WIDTH=200 HEIGHT=200>
</APPLET>
 

onda će browser pokušati naći našu klasu na adresi http://student.math.hr/~vedris/java/classes/HelloWorldApplet.class neovisno o tome gdje se HTML dokument nalazi.

Ukratko, browser pokušava rekonstruirati URL po formuli (CODEBASE + "/" + CODE). Jednom kad je URL formiran, vrijede sva pravila o relativnim i apsolutnim URLovima.

Ekstenziju .class možete u atributu CODE izostaviti i pisati samo ime klase. Na primjer

<APPLET CODE="HelloWorldApplet" 
CODEBASE="http://student.math.hr/~vedris/java/classes" WIDTH=200 HEIGHT=200>
</APPLET>
 

Ako applet nije u default paketu, potrebno je pisati puno ime paketa. Na primjer

 
<APPLET CODE="hr.math.student.vedris.myApplets.HelloWorldApplet" 
CODEBASE="http://student.math.hr/~vedris/java/classes" WIDTH=200 HEIGHT=200>
</APPLET>
 

U ovom slučaju browser će tražiti klasu na adresi http://student.math.hr/~vedris/java/classes/hr/math/student/vedris/myApplets/HelloWorldApplet.class, pa struktura direktorija na serveru mora biti napravljena u skladu s hijerarhijom paketa.

Atributi HEIGHT i WIDTH rade na isti način kao i kod oznake IMG, određujući veličinu pravokutnika koji će browser rezervirati za prikaz appleta. Veličine su specificirane u pikselima i obavezne su.


Odabir pozicije na stranici

Oznaka <APPLET> ima nekoliko atributa za definiranje pozicije appleta na stranici.

Atribut ALIGN određuje kako je appletov pravokutnik pozicioniran na stranice u odnosu na druge elemente. Dozvoljene vrijednosti ovog atributa su LEFT, RIGHT, TOP, TEXTTOP, MIDDLE, ABSMIDDLE, BASELINE, BOTTOM i ABSBOTTOM. Atribut je opcionalan.

U atributima HSPACE i VSPACE moguće je odrediti količinu praznog prostora (u pikselima) između appleta i okolnog teksta. I ovi su atributi opcionalni.

<applet code="HelloWorldApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes" width=200 height=200
ALIGN=RIGHT HSPACE=5 VSPACE=10>
</APPLET>
 

Atributi ALIGN, HSPACE, i VSPACE identični su onima koji se koriste u oznaci <IMG>.


Alternativni tekst

Oznaka <APPLET> ima i atribut ALT. Browser ga koristi u slučaju ako iz nekog razloga ne može izvesti applet. Na primjer, ako je u browseru isključena opcija za dozvolu izvođenja Java appleta, trebao bi se prikazati tekst naveden u atributu ALT. Atribut ALT je opcionalan.

 
<applet code="HelloWorldApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes" width=200 height=200
ALIGN=RIGHT HSPACE=5 VSPACE=10
ALT="Hello World!">
</APPLET>
 

Ovim se atributom ne koriste stariji browseri koji uopće ne razumiju oznaku <APPLET>. Oni umjesto toga prikazuju čisti tekst koji se nalazi između oznake <APPLET> i njenog zatvarača, </APPLET>. S druge strane, browseri koji su Java enabled ignorirat će taj tekst. Na primjer, sljedeći HTML fragment ispisuje string Hello World! svima, dakle i Java enabled i non-Java enabled browserima.

 
<applet code="HelloWorldApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes" width=200 height=200
ALIGN=RIGHT HSPACE=5 VSPACE=10
ALT="Hello World!">
Hello World!<P>
</APPLET>

Imenovanje appleta

Appletu se unutar web stranice može dati ime kako bi mogao komunicirati s drugim appletima. To se radi pomoću atributa NAME. Na primjer,

 
<applet code="HelloWorldApplet.class" Name=Applet_01
CODEBASE="http://student.math.hr/~vedris/java/classes" width=200 height=200
ALIGN=RIGHT HSPACE=5 VSPACE=10
ALT="Hello World!">
Hello World!<P>
</APPLET>

JAR arhive

Sve slike, zvukove i klase koje su potrebne za izvršavanje vašeg appleta možete spakirati u JAR arhivu i tako ih učitati odjednom, a ne svaku posebno. Time smanjujete broj konekcija koje browser mora ostvariti da bi dobio sve što mu treba. Ako se appletova klasa nalazi u takvoj arhivi, onda ćete oznaci <APPLET> dodati još i atribut <ARCHIVE>. Na primjer:

<APPLET CODE=HelloWorldApplet 
CODEBASE="http://student.math.hr/~vedris/java/classes" WIDTH=200 HEIGHT=200 
ARCHIVE="HelloWorld.jar">
<hr>
Hello World!
<hr>
</APPLET>
 

U ovom primjeru appletova klasa je i dalje HelloWorldApplet. Međutim, browser će odgovarajuću datoteku potražiti u arhivi HelloWorld.jar a ne u zasebnoj datoteci HelloWorldApplet.class.

Arhiva je spakirana na neki od uobičajenih načina, na primjer:

% jar cf HelloWorld.jar HelloWorldApplet.class 
added manifest
adding: HelloWorldApplet.class(in = 384) (out= 271)(deflated 29%)
%
 

Želimo li pogledati što ima u arhivi, možemo to učiniti ovako:

 
% jar tf HelloWorld.jar
META-INF/
META-INF/MANIFEST.MF
HelloWorldApplet.class
% 

HTML oznaka <OBJECT>

HTML 4.0 uvodi umjesto oznake <APPLET> novu oznaku <OBJECT>. Umjesto atributa CODE uvodi se atribut CLASSID. Na primjer:

 
<OBJECT CLASSID="HelloWorldApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes" WIDTH=200 HEIGHT=200
ALIGN=RIGHT HSPACE=5 VSPACE=10>
</OBJECT>
 

Atribut <OBJECT> omogućuje i uključivanje ActiveX kontrola i drugih aktivnih elemenata, no za Javu nam to ne treba. Podržavaju je samo najnovije verzije browsera i smatra se da će oznaka <APPLET> biti još dosta vremena aktualna.

Možete imati i obje oznake, jednu unutar druge, ovako:

<OBJECT CLASSID="HelloWorldApplet.class" WIDTH=200 HEIGHT=200
CODEBASE="http://student.math.hr/~vedris/java/classes">
<APPLET CODE="HelloWorldApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes" WIDTH=200 HEIGHT=200>
</APPLET>
</OBJECT>
 

Browseri koji razumiju oznaku <OBJECT> ignorirat će sadržaj između nje i njenog zatvarača, dok će ga ostali prikazati. Elementi PARAM su isti za obje oznake.


Veličina appleta

Veličina prostora koju zauzima applet dok se izvršava unutar web browsera zadana je atributima HEIGHT i WIDTH i sam applet je ne može promijeniti. Međutim, može doznati kolika je ta veličina, što mu je potrebno npr. da ne bi  crtao izvan zadanog prostora.

Veličina appleta doznaje se pomoću metode getSize() koju klasa java.applet.Applet nasljeđuje od svoje nadklase java.awt.Component. Ova metoda vraća objekt tipa java.awt.Dimension. Takav objekt ima dva atributa tipa int, to su height i width. Pogledajmo sljedeći primjer appleta koji ispisuje svoje dimenzije.

import java.applet.*;    
import java.awt.*;
 
 
public class SizeApplet extends Applet {
 
  public void paint(Graphics g) {
 
    Dimension appletSize = this.getSize();
    int appletHeight = appletSize.height;
    int appletWidth = appletSize.width;
    
    g.drawString("Applet je " + appletHeight + 
      " pt visok i " + appletWidth + " pt sirok.", 
      15, appletHeight/2);
    
  }
 
}

Prmijetite kako je ovdje visina appleta uzeta u obzir kod odlučivanja gdje smjestiti tekst. Korištenje appletove dimenzije za određivanje mjesta objekata na stranici često je korištena tehnika.


HTML oznaka <param>

Parametri se iz HTML dokumenta prenose appletima pomoću para NAME=VALUE i oznaci <PARAM> koja se smješta između oznake <APPLET> i njenog zatvarača. Unutar samog appleta vrijednosti proslijeđene putem oznake <PARAM> čitaju se pomoću metode getParameter() iz klase java.applet.Applet.

Sljedeći program demonstrira ispis stringova dobivenih sa HTML stranice. String koji se ispisuje je ovdje vrijednost parametra "Message".

import java.applet.*;    
import java.awt.*; 
             
public class DrawStringApplet extends Applet {
 
  public void paint(Graphics g) {
  
    String inputFromPage = this.getParameter("Message");
    g.drawString(inputFromPage, 50, 25);
    
  }
  
} 
 

Na HTML stranici imat ćemo parametar "Message" čija će vrijednost biti string "Kako ste?".

 
<HTML>
<HEAD>
<TITLE>DrawStringApplet</TITLE>
</HEAD>
 
<BODY>
Ovo je applet DrawStringApplet:<P>
<APPLET code="DrawStringApplet.class" 
CODEBASE="http://student.math.hr/~vedris/java/classes"
WIDTH="300" HEIGHT="50">
<PARAM name="Message" value="Kako ste?">
Ova stranica ce biti vrlo dosadna ako vaš browser ne razumije Javu.
</APPLET>
</BODY>
</HTML>
 

Promijenimo li vrijednost parametra, applet će ispisivati odgovarajući string bez potrebe da ga iznova kompiliramo.

Ovaj je applet vrlo sličan appletu HelloWorldApplet. Međutim, umjesto da fiksno kodiramo poruku koju on ispisuje, ona će biti učitana u varijablu inputFromPage izravno iz klauzule PARAM u HTMLu.

Metodi getParameter() daje se kao argument ime parametra sa HTML stranice, a ona će vratiti njegovu vrijednost. I argument i povratna vrijednost su stringovi. Ako je potreban drugačiji tip, morat ćete osigurati potrebne konverzije.

Oznaka <PARAM> stavlja se između <APPLET> i </APPLET>. Ona ima svoje atribute, NAME i VALUE koji identificiraju njegovo ime i vrijednost. Oba se stavljaju u dvostruke navodnike ako sadrže praznine.

Broj parametara nije ograničen. Možete imati po volji mnogo oznaka <PARAM> koje applet i ne mora sve iskoristiti. Višak će biti na siguran način ignoriran.


Obrada nepoznatog broja parametara

Ponekad je potrebno obraditi nepoznati broj parametara. U tom slučaju, parametri trebaju biti imenovani na neki predvidljiv način. Na primjer,

 
<PARAM name="Line1" value="There once was a man from Japan">
<PARAM name="Line2" value="Whose poetry never would scan">
<PARAM name="Line3" value="When asked reasons why,">
<PARAM name="Line4" value="He replied, with a sigh:">
<PARAM name="Line5" value="I always try to get as many syllables into the last line as I can.">
 

Sljedeći program ispisuje ovaj tekst znajući način na koji su parametri imenovani ("Line" + numlines).

Metoda paint() ispisuje svaki string na ekran, povećavajući y poziciju za 15 piksela svaki put.

import java.applet.*;    
import java.awt.*; 
             
public class PoetryApplet extends Applet {
 
  String[] poem = new String[101];
  int numlines;
 
  public void init() {
 
    String nextline;
 
    for (numlines = 1; numlines < poem.length; numlines++) {
      nextline = this.getParameter("Line" + numlines);
      if (nextline == null) break;
      poem[numlines] = nextline;
    }
    numlines--;
    
  }
  
  public void paint(Graphics g) {
  
    int y = 15;
  
    for (int i=1; i <= numlines; i++) {
      g.drawString(poem[i], 5, y);    
      y += 15;
    }
    
  }
  
} 
 

Ovako bi izgledao HTML dokument

 

<HTML>

<HEAD>

<TITLE>PoetryApplet</TITLE>

</HEAD>

 

<BODY>

Ovo je applet PoetryApplet:<P>

<APPLET code="PoetryApplet.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

WIDTH="350" HEIGHT="100">

<PARAM name="Line1" value="There once was a man from Japan">

<PARAM name="Line2" value="Whose poetry never would scan">

<PARAM name="Line3" value="When asked reasons why,">

<PARAM name="Line4" value="He replied, with a sigh:">

<PARAM name="Line5" value="I always try to get as many syllables into the last line as I can.">

 

Ova stranica ce biti vrlo dosadna ako vas browser ne razumije Javu.

</APPLET>

</BODY>

</HTML>

Procesiranje proizvoljne liste parametara bez znanja o načinu formiranja njihovih imena za sad nije moguće.


Sigurnost appleta

Suprotno raširenom mišljenju, Java appleti su sigurni za korisnike koji surfaju po internetu. Neće vam se dogoditi da vam applet formatira disk ili unese virus u sustav. Zbog mehanizama virtualne mašine, hvatanja iznimaka i tako dalje, Java appleti i aplikacije su u praksi sigurniji od tradicionalnih programskih jezika.

Appleti imaju ugrađena dodatna sigurnosna ograničenja kako bi zaštitili korisnike od programerskih pogrešaka, ali i od virusa. To je implementirano pomoću klase java.lang.SecurityManager. Različite podklase ove klase osiguravaju različita sigurnosna okruženja na različitim virtualnim mašinama. Loša strana toga je uvođenje raznih restrikcija na akcije koje aplet može činiti.


Što applet može činiti?

Applet može:

Sve što s tim ograničenjima možete učiniti moguće je učiniti iz appleta. S druge strane, applet ne može:


S kim applet može komunicirati?

Po pretpostavci applet može ostvariti mrežnu konekciju samo na stroj (file system) s kojeg je učitan. Taj sistem se zove codebase. Applet ne može komunicirati s bilo kojim strojem na internetu. Sva komunikacija te vrste mora biti posredovana preko poslužitelja.

Razlog je taj što bi inače applet mogao lansirati s neke mašine napade na internu mrežu organizacije. To bi pogotovo bio problem za mašine unutar firewalla koje su obično konfigurirane tako da jedne drugima vjeruju. Također, to bi omogućilo hakerima da lakše sakriju svoju pravu lokaciju.

HotJava, Sunov applet viewer i Internet Explorer (ali ne i Netscape) dozvoljavaju vam da appletu dopustite ostvarivanje konekcija na proizvoljni stroj, ali to nije default opcija.


Koliko CPU vremena applet dobija?

Jedan od razloga za brigu oko zlonamjernih appleta je mogućnost pretjerane uporabe CPU vremena, što je problem na, recimo Mac-u, a nešto manje na Windows NT ili Solaris. U svakom slučaju, applet može natjerati korisnika da npr. prisilno ugasi browser što može uzrokovati određeni gubitak podataka.

Moguće je također da applet koristi CPU vrijeme za svrhe koje nisu odmah vidljive. Na primjer, neki popularni applet može lansirti napad na password datoteku pomoću tzv. kineske lutrije. Ili, applet koji simulira neku igru može u backgroundu lansirati thread koji pokušava slučajnim pristupom razbiti enkripciju neke datoteke. U tom slučaju mogao bi ostvariti konekciju prema svom serveru i poslati ključ natrag. Što je applet popularniji, to je vjerojatnost pronalaženja ključa veća. Ipak, Java kod se lako dekompilira, pa se takvi appleti mogu otkriti.


Sigurnost i social engineering

Suprotno popularnom vjerovanju, većina provala na kompjutore nije rezultat briljantnih ideja i velikog znanja nego različitih oblika krađe passworda, od pretraživanja smeća do prijevare putem lansiranja prozora na kojem piše da je veza prekinuta pa se traži upis passworda (pogledajte za primjer ovaj TricksterApplet). Takve aktivnosti poznate su pod nazivom social engineering., u slobodnom prijevodu "lov u mutnom".

 


Sprečavanje hakerskih napada kroz applete

Da bi se spriječile takve zabune, prozori appleta su uvijek snabdjeveni nekom uočljivom porukom kao: "Warning: Applet Window" ili "Unsigned Java Applet Window." To, naravno, još uvijek ne garantira da netko neće upisati svoj password ne čitajući što piše na prozoru. Obrazovanje korisnika na prvom je mjestu u računalnoj sigurnosti.


Životni ciklus appleta

  1. broser učitava HTML stranicu i pronalazi oznaku <APPLET>
  2. browser analizira oznaku <APPLET> tražeći atribut CODE i eventualno CODEBASE.
  3. browser učitava .class datoteku appleta sa prethodno pronađenog URLa
  4. browser konvertira bytove u Java klasu, dakle objekt od java.lang.Class object.
  5. browser instancira appletovu klasu kako bi formirao objekt-applet. To zahtijeva da applet ima konstruktor bez argumenata.
  6. browser poziva appletovu init() metodu.
  7. browser poziva appletovu start() metodu.
  8. dok se applet izvršava, browser mu šalje informacije o događajima koji su mu namijenjeni, npr. klik mišem, pritisak na tipku itd. preko appletove handleEvent() metode. Događaji koji rade update kažu appletu da se iznova prikaže (repaint)
  9. browser poziva appletovu stop() metodu.
  10. browser poziva appletovu destroy() metodu.

Metode init(), start(), stop() i destroy()

Svi appleti imaju sljedeće četiri metode:

 
public void init();
public void start();
public void stop();
public void destroy();
 

Imaju ih jer ih ima njihova nadklasa, java.applet.Applet (pored ostalih, naravno). U nadklasi su one samo deklarirane i ne čine ništa, npr.

 
public void init() {}
 

Podklase mogu (ali i ne moraju) prekriti ove metode kako bi ispunile određene zadaće u određeno vrijeme. Na primjer, metoda init() je dobro mjesto za učitavanje parametara iz oznake <PARAM> jer ona će biti pozvana upravo u trenutku kad se applet počne izvršavati.  because it's called exactly once when the applet starts up. Budući da su deklarirane u nadklasi, Web browser će pozvati te metode kad mu trebaju, čak ni ne znajući jesu li implementirane u appletu ili u nadklasi. To je dobar primjer polimorfizma.

Metoda start() se poziva bar jednom u appletovom životnom ciklusu, onda kad se applet starta ili restarta. Ponekad to može biti i više nego jednom. Mnogi appleti nemaju eksplicitnu start()metodu nego je nasljeđuju iz nadklase. Najčešće se koristi za startanje threadova koje će applet trebati dok se izvršava.

Metoda stop() se poziva bar jednom, kad browser napusti stranicu koja sadrži applet. Kad se na nju opet vrati, pozvat će se metoda start(). Koristi se za zaustavljanje zaustavljanje threadova koje applet koristi. Kad je applet zaustavljen, ne bi trebao trošiti CPU cikluse.

Metoda destroy() se poziva točno jednom u životnom ciklusu appleta, upravo prije nego browser otpusti applet. Koristi se uglavnom za završno čišćenje.  is called exactly once in an applet's life, just before the browser unloads the applet. This method is generally used to perform any final clean-up.

U JDK appletvieweru, izbor opcije Restart poziva stop() i onda start(). Opcija Reload poziva redom stop(), destroy() i init(). (Normalno bi byte kodovi trebali biti ponovno učitani zajedno s HTML dokumentom, no u Netscapeu postoji problem s tim.)

Appletove metode start() i stop() nemaju veze sa istoimenim metodama iz klase java.lang.Thread.

Vaš vlastiti kod pozivat će povremeno metode start() i stop(). S druge strane, pozivanje metoda init() i destroy() nije dobra ideja. Browser (ili druga okolina) je taj koji će pozvati ove metode.


Koordinatni sustav

Java koristi standardni, dvodimenzionalni sustav za računalnu grafiku. Prvi vidljivi piksel u gornjem lijevom kutu appletove podloge je točka (0, 0). Koordinate se povećavaju prema desno i prema dolje.


Objekti klase Graphics

Crtanje se u Javi obavlja pomoću objekata klase java.awt.Graphics.

U početku ćete koristiti grafički objekt koji se daje kao argument metodi paint(Graphics g)koju klasa java.applet.Applet nasljeđuje od klase java.awt.Container. Kasnije ćete upoznati i ostale objekte klase Graphics. Sve što sada budete naučili o crtanju u appletima vrijedi i za objekte kao što su paneli, okviri, gumbi, podloge itd.

Svaki objekt tipa Graphics ima svoj vlastiti koordinatni sustav i metode za crtanje stringova, linija, pravokutnika, krugova, poligona i tako dalje. Crtanje u Javi počinje od pojedinačnog objekta tipa Graphics. Pristup tom objektu ostvarujete preko metode paint(Graphics g) u svom appletu.. Svaki poziv metode za crtanje izgledat će otprilike ovako:

g.drawString("Hello World", 0, 50) 

gdje je g specifični objekt tipa Graphics pomoću kojeg crtate.

Zbog razumljivosti, g će nam uvijek značiti već postojeći objekt klase Graphics. Naravno da, kao i kod svake druge metode, možete koristiti i druga imena za određeni kontekst, npr  myGraphics ili appletGraphics i slično.


Crtanje linija

Za crtanje ravne linije pozovite metodu drawline() čija je signatura:

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

Poziva se ovako:

 
g.drawLine(x1, y1, x2, y2) 
 

Pri tome su (x1, y1) i (x2, y2) krajnje točke linije, a g je objekt tipa Graphics pomoću kojeg crtate. Pogledajmo program koji će nacrtati liniju dijagonalno preko appleta.

 
import java.applet.*;    
import java.awt.*; 
 
public class SimpleLine extends Applet {
 
 public void paint(Graphics g) {
 
    g.drawLine(0, 0, this.getSize().width, this.getSize().height);
  
 }
 
}
 

<APPLET code="SimpleLine.class"

HEIGHT="50" WIDTH="100">

CODEBASE="http://student.math.hr/~vedris/java/classes"

</APPLET>


Crtanje pravokutnika

Pravokutnik crtate pomoću objekta g iz klase Graphics i metode drawRect() čija je signatura:

 
public void drawRect(int x,
                     int y,
                     int width,
                     int height)
 

Poziva se ovako:

 
public void drawRect(x, y, width, height)
 

Prva dva argumenta su koordinate gornjeg lijevog ugla pravokutnika, dok su ostala dva njegova širina i visina. Sljedeći program crta pravokutnik oko appleta.

 
import java.applet.*;    
import java.awt.*; 
 
public class RectangleApplet extends Applet {
 
  public void paint(Graphics g) {
 
    g.drawRect(0, 0, this.getSize().width - 1, this.getSize().height - 1);
    
  }
 
}
 

<APPLET code="RectangleApplet.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="50" WIDTH="40">

</APPLET>

 

 

Prisjetite se da je getSize().width širina pravokutnika, a getSize().height njegova visina.

Zašto crtamo pravokutnik samo do getSize().height-1 i getSize().width-1?

Zato jer se lijevi gornji ugao nalazi u točki (0, 0), a ne u (1, 1). To znači da aplet veličine 100 x 200 piksela uključuje točke s x-koordinatama između 0 i 99, a ne između 0 i 100. Slično, y-koordinate su između 0 i 199 uključivo, a ne između 0 i 200.

Za crtanje kvadrata ne postoji posebma drawSquare() metoda. Kvadrat je naprosto pravokutnik kojemu su duljina i širina iste.


Punjenje pravokutnika

Metoda drawRect() crta prazan pravokutnik. Ako ga želite ispuniti, koristite metodu fillRect() čija je signatura:

 

public abstract void fillRect(int x,
                              int y,
                              int width,
                              int height)
 

Sljedeći program crta ispunjeni pravokutnik u centru appleta. Morat ćemo razlikovati veličinu pravokutnika od veličine appleta.

 
import java.applet.*;    
import java.awt.*; 
 
public class FillAndCenter extends Applet {
 
  public void paint(Graphics g) {
 
    int appletHeight = this.getSize().height;
    int appletWidth  = this.getSize().width;
    int rectHeight   = appletHeight/3;
    int rectWidth    = appletWidth/3;
    int rectTop      = (appletHeight - rectHeight)/2;
    int rectLeft     = (appletWidth - rectWidth)/2;
    
    g.fillRect(rectLeft, rectTop, rectWidth-1, rectHeight-1);
    
  }
 
}
 

<APPLET code="FillAndCenter.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="50" WIDTH="40">

</APPLET>

 

 

 

 


Brisanje pravokutnika

Nacrtani pravokutnik može se izbrisati metodom clearRect() čija je signatura:

 

public abstract void clearRect(int x,
                               int y,
                               int width,
                               int height)

 

Pogledajmo program koji koristi ovu metodu da bi prikazao bljeskanje pravokutnika na ekranu.

 
import java.applet.*;    
import java.awt.*; 
 
public class Blink extends Applet {
 
  public void paint(Graphics g) {
 
    int appletHeight = this.getSize().height;
    int appletWidth  = this.getSize().width;
    int rectHeight   = appletHeight/3;
    int rectWidth    = appletWidth/3;
    int rectTop      = (appletHeight - rectHeight)/2;
    int rectLeft     = (appletWidth - rectWidth)/2;
 
    for (int i=0; i < 1000000; i++) {
      g.fillRect(rectLeft, rectTop, rectWidth-1, rectHeight-1);
      g.clearRect(rectLeft, rectTop, rectWidth-1, rectHeight-1);
    }
    
  }
 
}
 

<APPLET code="Blink.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="50" WIDTH="40">

</APPLET>

Ovo nije način kako se u praksi radi animacija, no to je najbolje što možemo učiniti dok ne naučimo raditi s threadovima.


Elipse i kružnice

Elipse i kružnice crtaju se pomoću metode drawOval(), a pune pomoću metode fillOval() čije su signature:

 

public abstract void drawOval(int x,
                              int y,
                              int width,
                              int height)
 
public abstract void fillOval(int x,
                              int y,
                              int width,
                              int height)
 

Argumenti ovih metoda predstavljaju koordinate gornjeg lijevog ugla te širinu i visinu pravokutnika kojemu je elipsa upisana (pogledajte sliku)

Nema posebne metode za crtanje kružnice. Kružnica je naprosto elipsa upisana u kvadrat.

Java također sadrži metode za crtanje praznih i ispunjenih lukova. To su metode drawArc() i fillArc(). Ponašaju se slično kao drawOval() i fillOval(). Signature su im:

public abstract void drawArc(int x,
                             int y,
                             int width,
                             int height,
                             int startAngle,
                             int arcAngle)
 
public abstract void fillArc(int x,
                             int y,
                             int width,
                             int height,
                             int startAngle,
                             int arcAngle)
 

U pravokutnik se upisuje najveći mogući luk. Lokacija luka od 0 stupnjeva, kao i to da li je luk nacrtan u smijeru kazaljke na satu ili protivnom je neovisno o platformi.


Primjer – bullseye

Ovo je jednostavni applet koji crta niz ispunjenih, koncentričnih krugova, naizmjenično crvenih i bijelih.

 
import java.applet.*;
import java.awt.*;
 
 
public class Bullseye extends Applet {
 
  public void paint(Graphics g) {
    
    int rectLeft, rectTop, rectHeight, rectWidth;
    int appletHeight = this.getSize().height;
    int appletWidth = this.getSize().width;
 
    for (int i=8; i >= 0; i--) {
      if ((i % 2) == 0) g.setColor(Color.red);
      else g.setColor(Color.white);
      
      // Centriramo pravokutnik
      rectHeight = appletHeight*i/8;
      rectWidth = appletWidth*i/8;
      rectLeft = appletWidth/2 - i*appletWidth/16;
      rectTop = appletHeight/2 - i*appletHeight/16;
      g.fillOval(rectLeft, rectTop, rectWidth, rectHeight);
    }
    
  }
 
}
 

<APPLET code="Bullseye.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="100" WIDTH="100">

</APPLET>

Klasa koja crta ovu sliku velika je 684 bytea. Ekvivalentna GIF slika imala bi 1,850 bytea, dakle gotovo tri puta više.


Poligoni

U Javi su pravokutnici definirani pomoću pozicije svojeg gornjeg lijevog ugla, visine i širine. Implicitno se podrazumijeva da pravokutnik nije rotiran. Ako jest, moramo ga smatrati specijalnim slučajem poligona, tj. objekta iz klase java.awt.Polygon.

Poligoni su definirani svojim vrhovima bez dodatnih pretpostavki osim da leže u dvodimenzionalnoj ravnini.Osnovni konstruktor klase Polygon je

public Polygon(int[] xpoints,
               int[] ypoints,
               int npoints)

xpoints je polje koje sadrži x koordinate vrhova poligona, a ypoints polje koje sadrži y koordinate njegovih vrhova. Oba polja trebaju imati duljinu npoints. Pogledajmo primjer konstrukcije trokuta s pravim kutem u ishodištu:

int[] xpoints = {0, 3, 0};
int[] ypoints = {0, 0, 4};
Polygon myTriangle = new Polygon(xpoints, ypoints, 3);
 

Da biste taj trokut i nacrtali, možete unutar svoje paint() metode pozvati iz klase java.awt.Graphics metodu drawPoligon() sa signaturom

 
public void drawPolygon(Polygon p)
 

ovako:

 
g.drawPolygon(myTriangle);
 

Na raspolaganju vam je i druga verzija metode drawPolygon() koja ima signaturu:

 
public abstract void drawPolygon(int[] xPoints,
                                 int[] yPoints,
                                 int nPoints)
 

a poziva se ovako:

 
g.drawPolygon(xpoints, ypoints, xpoints.length);
 

Postoji također i polimorfna metoda fillPolygon(). Sintaksa je očekivana:

 
g.fillPolygon(myTriangle);
g.fillPolygon(xpoints, ypoints, xpoints.length());

Višestruke linije (polylines)

Java automatski zatvara poligone koje nacrta (desna slika).

Ako želite crtati otvorene poligone (lijeva slika), koristit ćete metodu drawPolyline().

public abstract void drawPolyline(int[] xPoints,
                                  int[] yPoints,
                                  int nPoints)

Učitavanje slika

Poligoni, elipse, linije i tekstovi pokrivaju veliki dio grafičkih potreba. Ono što nam još treba su slike. U Javi to su GIF ili JPEG datoteke koje pokrivaju uglavnom sve.

Slike koje se prikazuju pomoću Java appleta učitavaju se s mreže preko URLa koji pokazuje na datoteku sa slikom. Mogu biti spremljene na web poslužitelju, lokalnom disku ili bilo gdje kamo applet može doći preko URLa. Treba paziti da budu spremljene tamo gdje će ih korisnik koji gleda applet moći dohvatiti. URL koji pokazuje na vaš lokalni disk možda radi dok testirate applet, ali možda neće biti od koristi za nekoga tko dolazi s mreže.

U pravilu se, iako to nije nužno, slike stavljaju u isti direktorij gdje je applet ili u onaj gdje je HTML datoteka. Stavite sliku u appletov direktorij ako će se ona koristiti u svim instancama apleta, a u HTML direktorij ako će različite instance appleta koristiti različite slike. Treća mogućnost je staviti sve slike u neki posebni direktorij i onda preko <PARAM> oznake reći appletu gdje su.

Ako znate točan URL slike, možete je učitati pomoću metode getImage():

URL imageURL = new URL("http://www.prenhall.com/logo.gif");
java.awt.Image img = this.getImage(imageURL);
 

Ili u jednoj naredbi:

 
Image img = this.getImage(new URL("http://www.prenhall.com/logo.gif"));
 

Metoda getImage() pripada klasi java.applet.Applet. Za URL objekte koristimo klasu java.net.URL. Provjeravajte u svojim programima da su te klase importirane ako ih koristite.


Metode getCodeBase() i getDocumentBase()

Ako ne znate točan URL slike, ali znate njeno ime i da se ona nalazi u istom direktoriju kao i applet, možete koristiti drugu varijantu metode getImage() koja uzima URL i ime datoteke. Koristite appletovu metodu getCodeBase() da dobijete URL appletovog direktorija:

 
Image img = this.getImage(this.getCodeBase(), "test.gif");
 

Metoda getCodeBase() vraća objekt tipa URL koji pokazuje na direktorij iz kojeg je applet došao.

Konačno, ako je slika spremljena u istom direktoriju kao i HTML datoteka, možete uporabiti istu metodu getImage(), ali joj dajte getDocumentBase(). To će vratiti URL koji pokazuje na direktorij u kojem se nalazi HTML stranica koja je pozvala applet.

Image img = this.getImage(this.getDocumentBase(), "test.gif");
 

Ako se slika učitava s Interneta, može potrajati dok se sva ne učita. U pravilu vas to ne mora brinuti i možete je crtati odmah nakon spajanja na neki od spomenutih URLova. Java će se sama pobrinuti za update kako podaci budu stizali, bez vaše intervencije.

Sve slike koje vaš applet koristi učitajte u metodi init(). Nemjte ih učitavati unutar metode paint() jer će se inače svaki put kad se applet obnovi slike učitavati iz početka.


Prikaz slike u pravoj veličini

Jednom kad je slika učitana, nacrtajte je u metodi paint() pomoću metode drawImage() ovako:

 
g.drawImage(img, x, y, io)
 

Pri tome je img objekt klase Image koji ste već učitali unutar metode init(). Nadalje, x je apscisa, a y ordinata lijevog gornjeg ugla slike. Argument io je objekt klase koja implementira interface ImageObserver. Taj interface propisuje kako Java rukuje asinhronim obnavljanjem slike kad se ona učitava sa udaljenog računala. Budući da klasa java.applet.Applet implementira ImageObserver za sad samo stavite ključnu riječ this za odgovarajući argument metode drawImage() čime naznačujete da želite koristiti ImageObserver trenutno aktivnog appleta.

Metoda paint() koja ne radi ništa osim crtanja slike u pravoj veličini, počevši od gornjeg lijevog ugla izgledala bi ovako:

public void paint(Graphics g) {
  g.drawImage(img, 0, 0, this);
}

Skaliranje slika

Sliku možete i skalirati unutar zadanog pravokutnika koristeći sljedeću verziju metode drawImage():

 
public boolean drawImage(Image img, int x, int y, 
                         int width,  int height, ImageObserver io) 
 

pri čemu su width i height dimenzije pravokutnika u koji želite smjestiti sliku. Ostali argumenti su isti kao i prije. Ako skaliranje nije u skladu s proporcijama slike, on može izgledati izobličeno.

Da biste izbjegli izobličenja, koristite metode getHeight() i getWidth() koje vam daju pravu veličinu slike. Tada je možete skalirati na odgovarajući način. Na primjer, ako je želite smanjiti na četvrtinu, postupili biste ovako:

g.drawImage(img, 0, 0, img.getWidth(this)/4, img.getHeight(this)/4, this);
 

Sljedeći program učitava sliku i povećava je za zadani faktor:

 
import java.awt.*;
import java.applet.*;
 
public class MagnifyImage extends Applet {
 
  private Image image;
  private int scaleFactor;
 
  public void init() {
    String filename  = this.getParameter("imagefile");
    this.image       = this.getImage(this.getCodeBase(), filename);
    this.scaleFactor = Integer.parseInt(this.getParameter("scalefactor")); 
  }
  
  public void paint (Graphics g) {
    int width    = this.image.getWidth(this);
    int height   = this.image.getHeight(this);
    int scaledWidth  = width * this.scaleFactor;
    int scaledHeight = height * this.scaleFactor;
    g.drawImage(this.image, 0, 0, scaledWidth, scaledHeight, this);
  }
 
}
 

<APPLET CODE="MagnifyImage.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

ARCHIVE="MagnifyImage.jar"

WIDTH=200 HEIGHT=200>

<param name="imagefile" value="java.gif">

<param name="scalefactor" value=2>

</APPLET>

 

Metoda init() čita dva parametra od kojih jedan daje ime slike, a drugi faktor povećanja. Metoda paint() računa omjere i zatim crta sliku.

 

Možda se pitate zašto se skaliranje obavlja u metodi paint() a ne već u metodi init() kad se veličina slike u pravilu i onako ne mijenja dinamički.

Razlog je taj što za vrijeme izvršavanja metode init() slika vjerojatno neće biti do kraja učitana, a u tom slučaju metode getWidth() i getHeight() će vratiti –1 i skaliranje se uopće neće obaviti. Pokušajte to vidjeti što se događa ako računanje premjestimo u metodu init():

import java.applet.*;
import java.awt.*;
 
 
public class MagnifyImage extends Applet {
 
  Image theImage;
  int scaledWidth, scaledHeight;
 
  public void init() {
  
    String filename = this.getParameter("imagefile");
    theImage        = this.getImage(this.getDocumentBase(), filename);
    int scalefactor = Integer.valueOf(this.getParameter("scalefactor")).intValue();
    int width       = theImage.getWidth(this);
    int height      = theImage.getHeight(this);
    scaledWidth     =  width  * scalefactor;
    scaledHeight    =  height * scalefactor;
 
  }
  
  public void paint (Graphics g) {
 
    g.drawImage(theImage, 0, 0, scaledWidth, scaledHeight, this);
 
  }
 
}

Boje

Boje su u Javi instance klase java.awt.Color. Uvjerite se da ste importirali tu klasu prije nego koristite boje koje nisu default. Nove boje možete kreirati koristeći RGB trojke kao kod web stranica. Na primjer:

 
Color medGray = new Color(127, 127, 127);
Color cream = new Color(255, 231, 187);
Color lightGreen = new Color(0, 55, 0);
 

Nekoliko najčešće korištenih boja dostupne su i po imenu. To su:

Boja nije svojstvo određenog pravokutnika, stringa i slično, nego je to dio objekta tipa Graphics koji obavlja određena crtanja. Za promjenu boje potrebno je promijeniti boju vašeg objekta iz Graphics. Tada će sve što crtate poprimiti tu boju, do sljedeće promjene.

Kad se applet počne izvršavati, njegova boja je crna. Možete je promijeniti stavljajući npr. g.setColor(Color.red). Vratit ćete je na početnu ako pozovete g.setColor(Color.black). Sljedeći kod bi proizveo ružičasti string, a iza njega zeleni:

g.setColor(Color.pink);
g.drawString("This String is pink!", 50, 25);
g.setColor(Color.green);
g.drawString("This String is green!", 50, 50);
 

Primijetite da će sve nakon ove zadnje linije biti zeleno. Da biste se vratili na početnu boju, možete koristiti ki metodu getColor() na primjer ovako:

 
Color oldColor = g.getColor();
g.setColor(Color.pink);
g.drawString("This String is pink!", 50, 25);
g.setColor(Color.green);
g.drawString("This String is green!", 50, 50);
g.setColor(oldColor);

Sistemske boje

U Javi 1.1 i dalje, postoji klasa java.awt.SystemColor koja je podklasa od java.awt.Color i omogućuje korištenje boja native komponenata. Na primjer, ako želite pozadinu vašet appleta učiniti istom kao i pozadinu prozora, možete u init() metodi postupiti ovako:

 
public void paint (Graphics g) {
 
  g.setColor(SystemColor.control);
  g.fillRect(0, 0, this.getSize().width, this.getSize().height);
  
}
 

Dostupne su sljedeće sistemske boje:


Fontovi

Vidjeli ste primjer crtanja teksta u appletu HelloWorldApplet. Pozivate metodu drawString() za objekt tipa Graphics. Toj metodi dajete argument tipa String kao i koordinate x i y. Ako je g objekt tipa Graphics onda je sintaksa sljedeća:

 
g.drawString(String s, int x, int y)
 

String je ovdje tekst koji hoćete ispisati. Integeri x i y su koordinate donjeg lijevog ugla teksta. Tekst će biti ispisan iznad i desno od te točke. Izuzetak su slova sa indeksima koji mogu biti ispisani i ispod crte.

Do sad smo koristili default font, no Java dozvoljava i izbor fonta. Garantira se postojanje serif fonta kao što je Times kojemu se pristupa preko imena "Serif", zatim neproporcionalnog fonta kao što je Courier, koji se referencira kao "Mono" i, konačno, sans serif fonta kao Helvetica kojem se pristupa kao "SansSerif".

Sljedeći applet ispisuje listu dostupnih fontova na računalu gdje se izvršava. Koristi se metodom getFontList() it klase java.awt.Toolkit. Ova metoda vraća polje stringova koji sadrže imena dostupnih fontova. Svi fontovi implementirani na vašem računalu možda i nisu dostupni appletu.

import java.awt.*;
import java.applet.*;
 
 
public class FontList extends Applet {
 
  String[] availableFonts;
 
  public void init () {
 
    Toolkit t = Toolkit.getDefaultToolkit();
    availableFonts = t.getFontList();
 
  }
 
  public void paint(Graphics g) {
  
    for (int i = 0; i < availableFonts.length; i++) {
      g.drawString(availableFonts[i], 5, 15*(i+1));
    }
  }
 
}
 

<APPLET code="FontList.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="200" WIDTH="100">

</APPLET>

 


Odabir oblika i veličine fonta

Odabir oblika fonta je jednostavan. Kreirate novi objekt tipa Font. Zatim pozovete g.setFont(Font f). Da biste instancirali klasu Font uporabite konstruktor:

 
public Font(String name, int style, int size)  
 

Ovdje je name ime odgovarajuće familije fontova, npr. "Serif", "SansSerif", ili "Mono" dok je size veličina fonta u točkama. U kompjutorskoj grafici točka je isto što i piksel. Nadalje, style je mnemonička konstanta iz java.awt.Font koja kaže da li je tekst bold, italic ili običan. Te konstante su Font.PLAIN, Font.BOLD, i Font.ITALIC. Sljedeći program ispisuje sve dostupne fontove u prirodnom obliku i u 14 točaka bold.

 
import java.applet.*;
import java.awt.*;
 
 
public class FancyFontList extends Applet {
 
  String[] availableFonts;
 
  public void init () {
 
    Toolkit t = Toolkit.getDefaultToolkit();
    availableFonts = t.getFontList();
 
  }
 
  public void paint(Graphics g) {
  
    for (int i = 0; i < availableFonts.length; i++) {
      Font f = new Font(availableFonts[i], Font.BOLD, 14);
      g.setFont(f);
      g.drawString(availableFonts[i], 5, 15*i + 15);
    }
  }
 
}
 

<APPLET code="FancyFontList.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="200" WIDTH="100">

</APPLET>

 
 


Klasa FontMetrics

Primijetite da se tekst neće sam prebacivati u novi redak, čak ni ako u njega stavite \n. Za takve tekstove pogodnije je koristiti komponente kao što je TextArea o kojima ćete učiti poslije. Ipak, da biste doznali koliko prostora zauzima vaš tekst koristit ćete objekte iz klase java.awt.FontMetrics.

Sljedeći primjer proširuje naš applet DrawString. Ako tekst prelazi širinu appleta, on će se prelomiti u novi redak.

Da bismo dobili metriku trenutačnog grafičkog objekta, koristit ćemo metodu java.awt.Graphics.getFontMetrics(). Iz klase java.awt.FontMetrics primijenit ćemo na taj objekt metodu stringWidth(String s) koja će nam vratiti širinu stringa, a onda getLeading() da dobijemo odgovarajući prored. Na raspolaganju je još mnogo metoda kojima se utvrđuju veličine teksta, no ove će biti dovoljne.

Konačno, trebat će nam klasa java.util.StringTokenizer da bismo string razbili na pojedine riječi.

import java.applet.*;    
import java.awt.*; 
import java.util.*;
 
 
public class WrapTextApplet extends Applet {
 
  String inputFromPage;
 
  public void init() {
    this.inputFromPage = this.getParameter("Text");
  }
  
  public void paint(Graphics g) {
  
    int i = 0;
    int linewidth = 0;
    int margin = 5;
    StringBuffer sb = new StringBuffer();
    FontMetrics fm = g.getFontMetrics();
    StringTokenizer st = new StringTokenizer(inputFromPage);
    
    while (st.hasMoreTokens()) {
      String nextword = st.nextToken();
      if (fm.stringWidth(sb.toString() + nextword) + margin < 
        this.getSize().width) {
        sb.append(nextword);
        sb.append(' ');
      }
      else if (sb.length() == 0) {
        g.drawString(nextword, margin, ++i*fm.getHeight());
      }
      else {
        g.drawString(sb.toString(), margin, ++i*fm.getHeight());
        sb = new StringBuffer(nextword + " ");
      }      
      
    }
    if (sb.length() > 0) {
      g.drawString(sb.toString(), margin, ++i*fm.getHeight());
    }  
 
  }
  
}
 

<APPLET code="WrapTextApplet.class"

CODEBASE="http://student.math.hr/~vedris/java/classes"

HEIGHT="200" WIDTH="100">

<PARAM name="Text" value="Jako dugi tekst koji se treba prelomiti">

</APPLET>