|
Els applets |
|
|
|
Una de les causes de l'enorme popularitat
de Java és que permet construir
petites (a vegades molt grans!) aplicacions,
el codi de les quals resideix en un servidor
web i es transmet per la xarxa,
executables en el si dels navegadors (Internet
Explorer, Netscape Navigator, Mozilla,
etc.) com a elements de pàgines HTML.
Aquestes petites aplicacions són els applets
i ara hi treballarem. |
|
|
|
Pel que fa als applets, cal considerar
dos aspectes:
- L'elaboració de l'applet
com a tal, que és el procés general d'elaboració
d'una aplicació Java: escriptura
del codi font i compilació.
- Què ha de contenir la pàgina
HTML per tal que, quan es carregui al navegador de l'usuari,
també es carregui i s'executi l'applet.
Tractarem aquestes dues qüestions separadament. |
|
|
|
Les etiquetes (tags) HTML per a
applets: |
|
|
 |
És força senzill. Al
punt del document HTML on vulguem que aparegui
l'applet, hi hem de posar el codi: |
|
|
|
<APPLET
CODE="el_meu_applet.class"
WIDTH="500"
HEIGHT="300"
>
</APPLET>
|
|
|
|
i, des del punt de vista del llenguatge
HTML, un applet es comporta com
una imatge, és a dir, pot centrar-se,
incloure en una taula, etc. |
|
|
|
La classe
que es cita després de l'atribut
CODE= és la classe
principal de l'applet. I si hem comprimit
tot l'applet en un fitxer
*.jar, cosa que d'altra banda és absolutament
recomanable, el codi és: |
|
|
|
<APPLET
CODE="el_meu_applet.class"
ARCHIVE="el_meu_fitxer_comprimit.jar"
WIDTH="500"
HEIGHT="300"
>
</APPLET> |
|
|
|
El tag
<APPLET> admet molts d'altres atributs.
Podeu veure'n la llista completa a la pàgina "The
APPLET Tag" del tutorial oficial de
Sun, "The
Java Tutorial", descarregable des de http://java.sun.com.,
si no és que ja ho havíeu fet... |
|
|
|
Tot construint applets... |
|
|
|
Anem a construir el nostre primer applet.
Al JCreator, definim el projecte
AppletFacil, però ara com a "Basic
Java Applet" en lloc de "Basic
Java Application" com havíem fet fins ara. Immediatament
i automàtica, JCreator crea el
fitxer AppletFacil.java, que és
l'applet, i un document
HTML, AppletFacil.htm, que és
on es veurà l'applet.
Aquests fitxers són suficients per tal que la cosa funcioni i,
per tant, ja podem compilar-los. Per veure'n el resultat, tenim dues opcions:
|
|
|
|
- Executar-lo des de JCreator,
el qual, automàticament, ens el mostra mitjançant l'eina
AppletViewer.exe (es el que farem mentre els
nostres applets estiguin en construcció).
El resultat és aquest:
- Demanar el document HTML,
AppletFacil.htm, amb el navegador.
El resultat és aquest:
|
|
|
|
|
|
|
Però, com estan fets els
applets? |
|
|
 |
Vegem-ne els punts principals:
|
|
|
|
- Un applet és
sempre una classe filla de la classe
java.applet.Applet. Això vol dir que
cal importar el package java.applet
i que la definició de la classe
és:
public class el_meu_applet
extends Applet { ... |
- La classe java.applet.Applet
és filla de la classe
java.awt.Panel ( filla
de java.awt.Container). Per tant, hi podem
posar els components que ens vingui
de gust: més pannells, botons,
canvas, etc. El layout
manager per defecte és java.awt.FlowLayout,
però podem canviar això i definir el que mes ens convingui.
- Quan la Màquina
Virtual de Java del navegador es disposa a executar
un applet, es dirigeix al mètode
public void init () de l'applet.
En certa forma, el paper del mètode
init en els applets
és el del mètode public
void main(String[] args) de les aplicacions
Java autònomes: tot allò que posaríem al
mètode main,
ho hem de posar ara al mètode
init.
|
|
- Una qüestió pel que fa a seguretat:
Un applet no pot gestionar ni
fitxers ni d'altres recursos
que no resideixin al servidor en el qual també resideix el document
HTML que el conté. Per tant, amb un applet
no es poden llegir ni escriure fitxers
de la màquina on s'executa (la màquina
client). Aquesta és una limitació molt severa,
però que ens protegeix dels applets
maliciosos que podrien funcionar com a
virus...
|
 |
Vist això, ara convertirem
una aplicació que ja tenim, la de
l'"editor de missatges" (projecte,
Missatgeria02, pràctica
5, mòdul 5) en un applet: |
|
|
|
Copiem el fitxer
etiquetes.java a la carpeta
AppletFacil i l'afegim
al projecte (poseu el mouse sobre
el nom del projecte i premeu el botó
de la dreta). Al fitxer AppletFacil.java
que ens havia fet JCreator, hi esborrem
el mètode public
void paint (Graphics g) que no ens és necessari, omplim el
mètode public
void init() i hi afegim la classe
ElMeuPanel. El codi ha de quedar com el que mostrem
a continuació: en groc hem marcat el codi que serà diferent
del projecte Missatgeria02,
l'altre queda exactament igual: |
|
|
|
/*
* @(#)AppletFacil.java 1.0 02/11/02
*
* You can modify the template of this file in the
* directory ..\JCreator\Templates\Template_2\Project_Name.java
*
* You can also create your own project template by making a new
* folder in the directory ..\JCreator\Template\. Use the other
* templates as examples.
*
*/
import java.awt.*;
|
|
import java.awt.event.*; |
|
import
java.applet.*;
public class AppletFacil extends Applet {
public void init() { |
|
setBackground(Color.LIGHT_GRAY);
ElMeuPanel
panel=new ElMeuPanel(this);
add(panel,BorderLayout.CENTER); |
|
}
}
class ElMeuPanel extends Panel implements ActionListener,
ItemListener {
|
|
AppletFacil
applet; |
|
Label
labelNomDestinatari;
Label labelNomRemitent;
TextField fieldNomDestinatari;
TextField fieldNomRemitent;
Button ok;
Button enviar;
List listInici;
List listFinal;
TextArea text;
int numIdioma=Etiquetes.idiomaInicial;
Choice idioma;
|
|
public
ElMeuPanel(AppletFacil f) { //constructor |
|
super(); |
|
applet=f; |
|
setLayout(new
BorderLayout());
Panel
panelNord=new Panel();
panelNord.setLayout(new
BorderLayout());
Panel
panelLabels=new Panel();
panelLabels.setLayout(new
GridLayout(2,1));
labelNomDestinatari=new
Label("",Label.RIGHT);
labelNomRemitent=new
Label("",Label.RIGHT);
panelLabels.add(labelNomDestinatari);
panelLabels.add(labelNomRemitent);
panelNord.add(panelLabels,BorderLayout.WEST);
Panel
panelNoms=new Panel();
panelNoms.setLayout(new
GridLayout(2,1));
fieldNomDestinatari=new
TextField();
fieldNomDestinatari.addActionListener(this);
fieldNomRemitent=new
TextField();
fieldNomRemitent.addActionListener(this);
panelNoms.add(fieldNomDestinatari);
panelNoms.add(fieldNomRemitent);
panelNord.add(panelNoms,BorderLayout.CENTER);
ok=new
Button();
ok.addActionListener(this);
panelNord.add(ok,BorderLayout.EAST);
add(panelNord,BorderLayout.NORTH);
text=new
TextArea("");
add(text,BorderLayout.CENTER);
Panel
panelCortesia=new Panel();
panelCortesia.setLayout(new
GridLayout(2,1));
listInici=new
List();
listInici.addActionListener(this);
panelCortesia.add(listInici);
listFinal=new
List();
listFinal.addActionListener(this);
panelCortesia.add(listFinal);
add(panelCortesia,BorderLayout.WEST);
Panel
panelSur=new Panel();
panelSur.setLayout(new
GridLayout(1,2));
idioma=new
Choice();
idioma.addItemListener(this);
panelSur.add(idioma);
enviar=new
Button();
enviar.addActionListener(this);
panelSur.add(enviar);
add(panelSur,BorderLayout.SOUTH);
canviaIdioma();
}
public void actionPerformed(ActionEvent
e) {
Object
objAction=e.getSource();
if
(objAction instanceof TextField ||
objAction
instanceof List) {
preparaText();
}
else if (objAction instanceof Button) {
if(objAction==ok)
{
preparaText();
}
else if(objAction==enviar) {
enviaMissatge();
}
}
}
public void itemStateChanged(ItemEvent
e) {
numIdioma=idioma.getSelectedIndex();
canviaIdioma();
}
public void canviaIdioma()
{
|
|
//
mainFrame.setTitle(Etiquetes.titolFrame[numIdioma]); Com que
//
ja no hi
// ha
cap
// frame
// cal
// eliminar
// aquesta
// línia |
|
labelNomDestinatari.setText(Etiquetes.nomTo[numIdioma]);
labelNomRemitent.setText(Etiquetes.nomFrom[numIdioma]);
ok.setLabel(Etiquetes.ok[numIdioma]);
listInici.removeAll();
int
totalHis=Etiquetes.hi[numIdioma].length;
for
(int i=0;i<totalHis;i++) {
listInici.add(Etiquetes.hi[numIdioma][i]);
}
listInici.select(1);
listFinal.removeAll();
int
totalByes=Etiquetes.bye[numIdioma].length;
for
(int i=0;i<totalByes;i++) {
listFinal.add(Etiquetes.bye[numIdioma][i]);
}
listFinal.select(1);
idioma.removeAll();
int
totalIdiomes=Etiquetes.idiomes.length;
for
(int i=0;i<totalIdiomes;i++) {
idioma.add(Etiquetes.idiomes[numIdioma][i]);
}
idioma.select(numIdioma);
enviar.setLabel(Etiquetes.enviar[numIdioma]);
preparaText(); |
|
applet.validate(); |
|
}
public void preparaText
() {
text.setText(listInici.getSelectedItem()+
fieldNomDestinatari.getText()+
",\n\n
< . . . "+
Etiquetes.espaiText[numIdioma]+
"
. . . >\n\n"+
listFinal.getSelectedItem()+
",\n
"+
fieldNomRemitent.getText());
}
public void enviaMissatge()
{
System.out.println(text.getText());
}
}
|
|
|
|
Un cop compilat,
prèvia modificació dels atributs
WIDTH i HEIGHT del
tag <APPLET> al fitxer
AppletFacil.htm, l'executem
amb l'AppletViewer: |
|
|
 |
|
|
|
o bé, obrim
el fitxer AppletFacil.htm
amb el navegador: |
|
|
 |
|
|
|
|
|
Classes i mètodes abstractes: |
|
|
|
Aprofitarem que ja sabem fer applets
i inclourel's en documents HTML per reprendre
un fil que s'havia iniciat a la pràctica
2 del mòdul 3, a l'introduir la classe
java.util.Vector, continuat a la pràctica
3 del mòdul 4:
- Es tracta de fer un applet
amb un sol canvas pel qual hi puguem
moure tot d'objectes amb el mouse.
La presentació (amb AppletViewer)
serà aquesta:
i podeu comprovar-ne el funcionament tot clicant aquí.
La imatge la obtindreu aquí.
- L'esquema general de funcionament serà aquest:
- Cadascun dels sis objectes
que apareix sobre el canvas és
una instància d'alguna de
les tres classes trastets.Rodoneta,
trastets.Finestra o trastets.Postal.
El propi nom de les classes
ja indica que estaran agrupades en el package
trastets. Per tant, a l'encapçalament
del fitxer (un fitxer
per a cadascuna!) del codi hi ha d'haver la clàusula
package trastets.
- Cadascuna d'aquestes tres classes
tindrà, com a variables de classe,
- la variable
java.awt.Dimension posicio, que contindrà
informació quant a la posició
(les coordenades) de l'objecte
en el canvas, i
- la variable
java.awt.Rectangle rectangle, que
contindrà informació quant a la zona
clickable de l'objecte.
- Com a mètodes,
a part el constructor, cadascuna
d'aquestes tres classes tindrà:
- public void pinta (Canvas
canvas,Graphics g), que descriurà com pintar
l'objecte sobre el canvas canvas
en el context gràfic
g.
- public void setPosicio
(Dimension pos), que posarà la variable
posicio al valor
pos i recalcularà la zona
clickable rectangle.
- public void setOcupacio
(), que recalcularà la zona
clickable rectangle, a partir
del valor de la variable
posicio.
- public Dimension getPosicio
(), mitjançant el qual podrem demanar el valor
de la variable posicio.
- public Rectangle getOcupacio
(), mitjançant el qual podrem demanar el valor
de la variable rectangle.
- Els objectes
es desaran en un vector. Tal com
ja vam fer a la pràctica
3 del mòdul 4, com que cadascuna de les dues variables
i cadascun dels cinc mètodes
a cadascuna de les tres classes,
a més de compartir nom,
comparteixen funció: pintar,
situar, etc. (que no funcionament,
aquest és propi de cada classe),és
lògic fer que les tres classes
siguin filles d'una única
classe mare, la qual ja tindrà
aquestes variables i aquests mètodes
definits. Per tal d'estalviar espai de memòria en una nova
classe sense més funcions
que engendrar classes filles i
passar-les-hi mètodes per herència,
aquesta classe mare s'ha de declarar
com a abstracta, mitjançant la clàusula
abstract. El codi per a aquesta classe,
trastets.Trasto (projecte
AppletNoTanFacil, "Basic
Java Applet", fitxer
Trasto.java) és aquest:
package trastets;
import java.awt.*;
public abstract class Trasto { //
Declaració com a classe
//
abstracta
Dimension posicio;
Rectangle ocupo;
public Trasto (int
x,int y) { //constructor
posicio=new
Dimension(x,y);
ocupo=new
Rectangle(0,0,0,0);
}
public abstract void pinta (Canvas
canvas,Graphics g);
public void setPosicio (Dimension
pos) {
posicio=pos;
setOcupacio();
}
public abstract void setOcupacio
();
public Dimension getPosicio () {
return posicio;
}
public Rectangle getOcupacio ()
{
return ocupo;
}
}
|
- Dels cinc mètodes
que té la classe mare trastets.Trasto
i que heretaran les classes
filles, n'hi ha que tenen un funcionament exactament igual
per a cada classe filla i n'hi
ha que no.
- Els que sí
tenen un funcionament exactament igual per a cada classe
filla ja es poden codificar
a la classe mare. Són
els mètodes public void
setPosicio (Dimension pos), public
Dimension getPosicio () i public Rectangle
getOcupacio ().
- Els mètodes que tenen un funcionament
específic per a cada classe
filla es declaren abstractes
(mitjançant la clàusula
abstract) i no s'hi posa cos.
Són els mètodes
public abstract void pinta (Canvas canvas,Graphics
g) i public abstract void setOcupacio
(). Naturalment, cada classe
filla els ha de sobreescriure
(override) amb el seu propi
codi.
- El codi per a les tres classes
filles és aquest:
package trastets;
import java.awt.*;
public class Rodoneta extends Trasto {
int radi;
public Rodoneta (int x,int y,int
r) { //constructor
super(x,y);
radi=r;
setOcupacio();
}
public void pinta
(Canvas canvas,Graphics g) {
g.setColor(Color.BLACK);
g.fillOval(ocupo.x,ocupo.y,
ocupo.width,ocupo.height);
g.setColor(Color.RED);
g.fillOval(ocupo.x+3,ocupo.y+3,
ocupo.width-6,ocupo.height-6);
}
public void setOcupacio () {
ocupo.x=posicio.width-radi;
ocupo.y=posicio.height-radi;
ocupo.height=2*radi;
ocupo.width=2*radi;
}
}
|
package trastets;
import java.awt.*;
public class Finestra extends Trasto {
int ample,alt;
public Finestra (int
x,int y,
int amp,int al) { //constructor
super(x,y);
ample=amp;
alt=al;
setOcupacio();
}
public void pinta
(Canvas canvas,Graphics g) {
g.setColor(Color.ORANGE);
g.fill3DRect(ocupo.x,ocupo.y,
ocupo.width,ocupo.height,
true);
g.fill3DRect(ocupo.x+10,ocupo.y+8,
ocupo.width-20,ocupo.height-16,
false);
g.fill3DRect(ocupo.x+ocupo.width/2-2,ocupo.y+8,
4,ocupo.height-16,
true);
g.fill3DRect(ocupo.x+10,ocupo.y+ocupo.height/2-2,
ocupo.width-20,4,
true);
}
public void setOcupacio () {
ocupo.x=posicio.width;
ocupo.y=posicio.height;
ocupo.width=ample;
ocupo.height=alt;
}
}
|
package trastets;
import java.awt.*;
public class Postal extends Trasto {
int ample,alt;
Image imatge;
public Postal (int
x,int y,int amp,int al,
Image im) { //constructor
super(x,y);
ample=amp;
alt=al;
imatge=im;
setOcupacio();
}
public void pinta
(Canvas canvas,Graphics g) {
g.drawImage(imatge,
ocupo.x,ocupo.y,
ocupo.width,ocupo.height,
canvas);
}
public void setOcupacio () {
ocupo.x=posicio.width;
ocupo.y=posicio.height;
ocupo.width=ample;
ocupo.height=alt;
}
}
|
Observeu com a cap de les tres classes
ni s'hi declaren les variables
Dimension posicio i Rectangle
ocupo, ni els mètodes
public void setPosicio (Dimension pos),
public Dimension getPosicio () i public
Rectangle getOcupacio (). La raó és que ja
estan declarats, definits
i codificats a la classe
mare trastets.Trasto!
- La classe que
farà funcionar tot això serà un applet.
Aquest applet contindrà només
un canvas (ElMeuCanvas)
al qual se li implementen les interfícies
java.awt.event.MouseListener i java.awt.event.MouseMotionListener.
El codi és aquest:
/*
* @(#)AppletNoTanFacil.java 1.0 02/11/03
*
* You can modify the template of this file in the
* directory ..\JCreator\Templates\Template_2\Project_Name.java
*
* You can also create your own project template by making a new
* folder in the directory ..\JCreator\Template\. Use the other
* templates as examples.
*
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.applet.*;
import java.net.*;
import trastets.*;
public class AppletNoTanFacil extends Applet {
public void init() {
setLayout(new
BorderLayout());
ElMeuCanvas
canvas=new ElMeuCanvas(this);
add(canvas,BorderLayout.CENTER);
}
}
class ElMeuCanvas extends Canvas implements MouseListener,
MouseMotionListener
{
AppletNoTanFacil applet;
Image imEncaraNoEsVeu;
Vector trastos;
Trasto trastoPescat=null;
int posX,posY;
public ElMeuCanvas (AppletNoTanFacil
ap) { //constructor
super();
applet=ap;
addMouseListener(this);
addMouseMotionListener(this);
trastos=new
Vector();
afegeixTrasto(new
Rodoneta(30,50,12));
afegeixTrasto(new
Finestra(75,125,90,60));
afegeixTrasto(new
Rodoneta(245,175,19));
afegeixTrasto(new
Finestra(315,5,90,120));
Toolkit toolkit=Toolkit.getDefaultToolkit();
URL url=getClass().getResource("imatges/bosch.jpg");
Image imatge=toolkit.getImage(url);
MediaTracker
mediaTracker=new MediaTracker(this);
mediaTracker.addImage(imatge,0);
try
{
mediaTracker.waitForAll();
while(!mediaTracker.checkAll())
{
}
}
catch (InterruptedException e) {
System.out.println("No
puc!");
}
afegeixTrasto(new
Postal(295,145,189,149,imatge));
afegeixTrasto(new
Postal(215,15,63,50,imatge));
setBackground(new
Color(255,255,200));
}
public void afegeixTrasto (Trasto tr)
{
trastos.addElement(tr);
}
public void update (Graphics
g) {
paint(g);
}
public void paint (Graphics g) {
Dimension size=getSize();
if
(imEncaraNoEsVeu==null) {
imEncaraNoEsVeu=createImage(1024,768);
}
Graphics gEncaraNoEsVeu=imEncaraNoEsVeu.getGraphics();
gEncaraNoEsVeu.setColor(getBackground());
gEncaraNoEsVeu.fillRect(0,0,size.width,size.height);
for(Enumeration
enum=trastos.elements();
enum.hasMoreElements();){
Object
ob=enum.nextElement();
Trasto
tr=(Trasto)ob;
tr.pinta(this,gEncaraNoEsVeu);
}
g.drawImage(imEncaraNoEsVeu,0,0,this);
}
public void mouseClicked (MouseEvent
e) {
}
public void mousePressed
(MouseEvent e) {
posX=e.getX();
posY=e.getY();
for(Enumeration
enum=trastos.elements();
enum.hasMoreElements();){
Object
ob=enum.nextElement();
Trasto
tr=(Trasto)ob;
Rectangle
oc=tr.getOcupacio();
if
(oc.contains(posX,posY)) {
trastoPescat=tr;
break;
}
}
}
public void mouseReleased
(MouseEvent e) {
trastoPescat=null;
}
public void mouseEntered
(MouseEvent e) {
}
public void mouseExited
(MouseEvent e) {
}
public void mouseDragged
(MouseEvent e) {
int gX=e.getX();
int gY=e.getY();
if
(trastoPescat!=null) {
int
dX=gX-posX;
int
dY=gY-posY;
Dimension
posicio=trastoPescat.getPosicio();
trastoPescat.setPosicio(new
Dimension(
posicio.width+dX,posicio.height+dY));
repaint();
posX=gX;
posY=gY;
}
}
public void mouseMoved
(MouseEvent e) {
}
}
|
Observem:
- Com sempre que s'implementen interfícies,
la classe ElMeuCanvas
ha de tenir definits tots els mètodes
de les interfícies que implementa,
encara que, alguns d'ells no es facin servir. Nosaltres concentrarem
tota la funcionalitat en els mètodes
public void mousePressed (MouseEvent e),
public void mouseReleased (MouseEvent e)
i public void mouseDragged (MouseEvent e).
- Els objectes que passegem pel canvas
estan guardats en un vector: la
variable de classe Vector
trastos. Al construir el
canvas, s'afegeixen aquests objectes
al vector mitjançant el
mètode public
void afegeixTrasto (Trasto tr).
- El mètode
public void paint (Graphics g)
utilitza la tècnica del doble
buffering (vegeu la pràctica
anterior). Recupera els objectes que hi ha al vector
trastos mitjançant
una instància de
java.util.Enumeration,
Object ob=enum.nextElement();
// Recordeu que els objectes,
//
en un vector, s'hi guarden
//
com a instàncies de
//
java.lang.Object! |
fa la conversió
(casting)
corresponent,
els pinta sobre la imatge oculta
imEncaraNoEsVeu,
fent servir el seu context gràfic
gEncaraNoEsVeu
i, quan ha esgotat el contingut del vector,
pinta la imatge
imEncaraNoEsVeu
amb el context gràfic
g propi del
canvas,
que ja és visible a l'usuari.
- El mètode
public void mousePressed (MouseEvent e)
serveix per a determinar si hem premut el botó esquerre
del mouse just quan el cursor
és sobre un objecte. Amb la mateixa tècnica que la
del mètode public
void paint (Graphics g), recupera els
objectes que hi ha al vector
trastos i mira
si l'esdeveniment
s'ha produït dins del rectangle
que representa la zona clickable
de l'objecte:
Trasto tr=(Trasto)ob; //
Casting imprescindible!
Rectangle oc=tr.getOcupacio();
// Zona clickable de l'objecte
if (oc.contains(posX,posY)) { //
La zona clickable conté
//
el punt clickat?
trastoPescat=tr;
// Identifiquem quin és
aquest
//
objecte
break; //
Ja no cal seguir mirant. Trenquem el cicle
} |
En el cas que sí s'hagi produït, llavors identifica
l'objecte, en guarda la referència
(tr)
a la variable de classe
Trasto trastoPescat, i acaba el procés
d'identificació.
- El mètode
public void mouseReleased (MouseEvent e)
estableix com a null l'objecte identificat
pel mètode anterior.
- El mètode
public void mouseDragged (MouseEvent e)
canvia el valor de la variable
Dimension posicio de l'objecte identificat,
la referència del qual és
a la variable
de classe Trasto trastoPescat,
en funció del moviment del cursor
del mouse.
Llavors, mitjançant repaint(),
demana el repintat inmediat del canvas.
- El codi del document
HTML en el qual apareixerà l'applet
és aquest:
<HTML>
<HEAD>
</HEAD>
<BODY BGCOLOR="000000">
<CENTER>
<APPLET
code = "AppletNoTanFacil.class"
width = "500"
height = "300"
</APPLET>
</CENTER>
</BODY>
</HTML> |
|
|
|
|
Applets amb paràmetres: |
|
|
|
Un applet
té la capacitat de llegir paràmetres
externs (de la mateixa manera que una aplicació
Java els llegeix mitjançant el mètode
public static void main (String[] args)). El
mètode, que és de la classe
java.applet.Applet, és public
String getParameter(String nom).
Els paràmetres, que sempre es llegeixen
com a cadenes (strings),
han de ser al codi del document HTML que
conté l'applet, dintre de l'etiqueta
<APPLET>. La sintaxi es fa present a la
variació següent de l'exemple anterior. |
|
|
|
Anem a modificar l'exemple anterior de manera que el color
del fons (background) del canvas
sigui definit per uns certs paràmetres:
- Al codi del document
HTML, dins de l'etiqueta <APPLET>
hi afegim els paràmetres:
<HTML>
<HEAD>
</HEAD>
<BODY BGCOLOR="000000">
<CENTER>
<APPLET
code = "AppletNoTanFacil.class"
width = "500"
height = "300" |
<param
name="RGBr" value="255">
<param name="RGBg" value="255">
<param name="RGBb" value="220"> |
</APPLET>
</CENTER>
</BODY>
</HTML> |
Els noms dels paràmetres, "RGBr",
"RGBg" i "RGBb"
són, evidentment, arbitraris. Aquí hem posat aquests perquè
es refereixen a cadascun dels components,
vermell, verd
i blau, d'un color
RGB. Observeu-ne la sintaxi:
<param name="nom_del_paràmetre"
value="valor_del_paràmetre"> |
- Ara hem de canviar el codi de l'applet
per tal que sigui capaç de llegir els
paràmetres. Anem al mètode
constructor del canvas i hi
afegim:
int
rgbR=Integer.parseInt(applet.getParameter("RGBr"));
int rgbG=Integer.parseInt(applet.getParameter("RGBg"));
int rgbB=Integer.parseInt(applet.getParameter("RGBb"));
setBackground(new
Color(rgbR,rgbG,rgbB)); |
després de comentar o suprimir
la línia que definia el color del fons
(background)
//
setBackground(new Color(255,255,200)); |
El mètode que es crida és
public String getParameter(String nom)de applet,
que és l'applet que conté
el canvas. Com que el resultat n'és
una cadena (string)
i el necessitem com a int per a construir
el color, caldrà aplicar el mètode
static (de la classe
java.lang.Integer) public
static int parseInt(String st).
|
|
|
|
Ara per a molt atrevits/des! |
|
|
 |
L'ús de paràmetres
per a controlar el comportament dels applets
pot arribar a ser molt i molt sofisticat. Aquí proposem un exemple,
una variació de l'exemple anterior, mitjançant el qual els
objectes que es carreguen al vector
trastos es defineixen com a paràmetres: |
|
|
|
- Comencem per afegir el codi marcat en groc clar
al document HTML:
<HTML>
<HEAD>
</HEAD>
<BODY BGCOLOR="000000">
<CENTER>
<APPLET
code = "AppletNoTanFacil.class"
width = "500"
height = "300"
<param name="RGBr" value="255">
<param name="RGBg" value="255">
<param name="RGBb" value="220">
|
<param
name="trasto0" value="Rodoneta,30,50,12">
<param name="trasto1" value="Finestra,75,125,90,60">
<param name="trasto2" value="Rodoneta,245,175,19">
<param name="trasto3" value="Finestra,315,5,90,120">
<param name="trasto4"
value="Postal,295,145,189,149,imatges/bosch.jpg">
<param name="trasto5"
value="Postal,215,15,63,50,imatges/bosch.jpg"> |
</APPLET>
</CENTER>
</BODY>
</HTML> |
Observeu com el valor de cada paràmetre
és una cadena (string)
que conté el nom i totes les dades necessàries per a
construir un objecte de la classe
d'aquest nom. Observeu també la regla que hem seguit pels noms
de cada paràmetre, que després aprofitarem per
a llegir-los i per saber que ja no hi ha més paràmetres
d'aquesta mena.
- Al mètode constructor
del canvas, hi suprimim totes les línies
dedicades a omplir el vector amb objectes
i les substituïm per una única línia, la qual crida
a un nou mètode, public
void llegeixTrastos(), especialitzat en llegir
els paràmetres, interpretar-los, construir
els objectes corresponents i posar-los al vector
trastos.
public
ElMeuCanvas (AppletNoTanFacil ap) { //constructor
super();
applet=ap;
addMouseListener(this);
addMouseMotionListener(this);
trastos=new Vector(); |
llegeixTrastos(); |
int
rgbR=Integer.parseInt(applet.getParameter("RGBr"));
int rgbG=Integer.parseInt(applet.getParameter("RGBg"));
int rgbB=Integer.parseInt(applet.getParameter("RGBb"));
setBackground(new
Color(rgbR,rgbG,rgbB));
} |
- El mètode,
public void llegeixTrastos() aprofita el mètode
public String[] split (String str) de la classe
java.lang.String (vegeu-ne la documentació)
per partir la cadena llegida en trossos,
just on hi ha el caràcter ",":
public void llegeixTrastos ()
{
int i=0;
while (true) {
String
nom="trasto"+String.valueOf(i);
String
valor=applet.getParameter(nom);
if
(valor==null) {
break;
}
else {
String[]
trossos=valor.split(",");
if
(trossos[0].equals("Rodoneta")) {
int
x=Integer.parseInt(trossos[1]);
int
y=Integer.parseInt(trossos[2]);
int
r=Integer.parseInt(trossos[3]);
afegeixTrasto(new
Rodoneta(x,y,r));
}
else
if
(trossos[0].equals("Finestra")) {
int
x=Integer.parseInt(trossos[1]);
int
y=Integer.parseInt(trossos[2]);
int
a=Integer.parseInt(trossos[3]);
int
h=Integer.parseInt(trossos[4]);
afegeixTrasto(new
Finestra(x,y,a,h));
}
else
if
(trossos[0].equals("Postal")) {
int
x=Integer.parseInt(trossos[1]);
int
y=Integer.parseInt(trossos[2]);
int
a=Integer.parseInt(trossos[3]);
int
h=Integer.parseInt(trossos[4]);
Toolkit
toolkit=
Toolkit.getDefaultToolkit();
URL
url=getClass().getResource(
trossos[5]);
Image
imatge=toolkit.getImage(url);
MediaTracker
mediaTracker=
new
MediaTracker(this);
mediaTracker.addImage(imatge,0);
try
{
mediaTracker.waitForAll();
while(
!mediaTracker.checkAll(
))
{
}
}
catch (
InterruptedException e) {
}
afegeixTrasto(new
Postal(
x,y,a,h,imatge));
}
}
i++;
}
} |
|
|
Ara se us invita a modificar el document
HTML per tal de tenir diversos objectes i distribucions sobre el
canvas... |
|
|
|
Com continua això ara? |
|
|
 |
Ara segurament ja esteu en el punt en el qual començareu a queixar-vos
que construir una GUI (Graphic
User Interface) per a una aplicació Java
és una feina, si no titànica, prou complicada!
Anem a pams. Aquest mòdul i l'anterior han estat una introducció
a l'AWT (Abstract
Windows Toolkit) i, ambdós, tenien dos objectius didàctics:
- d'una banda, l'objectiu obvi d'introduir-vos en el maneig
de les classes de l'AWT per tal que
arribeu a ser capaços de construir GUIs...
- i de l'altra, donat que les classes de l'AWT
són molt elementals, aprofitar això per mostrar-vos i
fer-vos practicar alguns dels paradigmes
de la programació orientada a objectes
(OOPS)
Però l'AWT és només
una part del conjunt de les Java Foundation
Classes (JFC), les quals, segons
la pṛpia empresa Sun, "són
un conjunt de llibreries de classes Java,
part de la distribució J2SE
(Java 2 Standard Edition, que és
la que fem servir aquest curs) per a permetre la construcció
d'interfícies gràfiques
d'usuari (GUI)
i funcionalitat gràfica per a aplicacions
client ("Java applications")
basades en la tecnologia Java."
(vegeu http://java.sun.com/products/jfc/
)
Quant a la funcionalitat gràfica,
el conjunt JFC ens proporciona les següents
APIs:
- L'AWT (Abstract
Windows Toolkit), ja prou discutit aquí, que permet als
nostres programes d'integrar-se en el sistema
windows natiu de la plataforma en la qual s'executin (MS
Windows, Linux, Unix,
etc.),
- Java 2D, per a gràfics
bidimensionals amb cert grau de sofisticació, imatges, text i
impressió.
- Swing, que és
una extensió de l'AWT, la qual
ens proporciona una col·lecció molt important de classes
gens elementals, que inclouen d'origen moltes funcionalitats
que amb les classes de l'AWT caldria
construir a ma. Les classes de Swing
que són extensió de les de l'AWT
solen tenir el mateix nom que les de l'AWT,
però precedit d'una J: JLabel,
JApplet, JPanel,
etc. Els paquets que les contenen són
javax.swing.*.
Naturalment, si és que esteu seriosament interessats en aplicacions
gràfiques de Java, siguin applets
o aplicacions autònomes, us convindrà
un estudi detallat del paquet javax.swing.
A la pràctica 1 i als exercicis del mòdul 7 hi proposem l'ús
d'una classe de Swing. |
|
|
|
|
|
|
 |
|
|
|
|