|
|
|
|
Posar els botons |
|
|
|
|
|
|
Recorda la planificació
de la pràctica 1 quant als botons: |
|
|
|
|
|
Fase
del disseny de la o les GUIs (Graphics
User Interface: Interfícies gràfiques d'usuari) |
GUI
: Una sola finestra (JFrame), amb |
Un MonVisible, fill de JPanel,
on es visualitzen els estats del món,
Un JPanel amb quatre
JButtons per a les accions de "Pas a pas",
"Engegar/parar el procés continu",
"Extermini" i "Sortir".
El JButton "Pas a pas"
ha de quedar inhabilitat quan estigui en marxa el procés
continu, i
El JButton "Engegar/parar
el procés continu" ha de canviar d'etiqueta
segons el procés continu estigui actiu o no.
|
|
|
|
|
|
|
|
Són quatre botons que
posaràs just a sota del MonVisible. Com
que el layout és BorderLayout, la
posició corresponent és BorderLayout.SOUTH.
|
|
|
|
|
|
No és possible
col·locar directament tots quatre components (els quatre botons)
en aquesta posició: només n'hi pot haver un! Cal, primer,
col·locar-los en un contenidor, un JPanel
i, després, posar aquest JPanel a la posició BorderLayout.SOUTH. |
|
|
|
|
|
El codi per fer això té
el seu lloc lògic al mètode setControls()
del la classe Finestra. De moment, només
crearàs el JPanel que contindrà
els botons i el posaràs al seu lloc: |
|
|
|
|
 |
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Dimension;
import java.awt.BorderLayout;
/**
* La classe Finestra és la classe arrel de l'aplicació
del Joc
* de la Vida.
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Finestra extends JFrame {
/**
* L'objecte MonVisible que fa visibles
els éssers
* del món.
*/
protected MonVisible monVisible;
/**
* Mètode getter per a la variable
monVisible
* @return el MonVisible d'aquesta
finestra
*/
public MonVisible getMonVisible () {
return monVisible;
}
/**
* Mètode constructor per a
objectes de la classe Finestra.
*/
public Finestra () { // constructor
setConfiguracio();
setControls();
inicia();
}
/**
* Mètode que fixa les dimensions
del MonVisible.
* ATENCIÓ: CONTINGUT PROVISIONAL!
* @return les dimensions del
MonVisible
*/
public Dimension getDimensionsMonVisible
() {
return new Dimension(400,300);
}
/**
* Mètode que fixa els paràmetres
generals d'aquesta Finestra.
*/
private void setConfiguracio () {
setTitle("El
Joc de la Vida..."); // El títol
setResizable(true);
// La Finestra es podrà fer més gran
// o més petita amb el ratolí
setDefaultCloseOperation(EXIT_ON_CLOSE); //
La finestra es
//
tancarà amb el
// botó "X" de
//
tancar.
}
/**
* Mètode que crea i distribueix
els controls d'aquesta
* Finestra.
*/
private void setControls () {
monVisible=new MonVisible(this);
// Li passem aquesta
//
Finestra com a parà-
//
metre
getContentPane().add(monVisible,
BorderLayout.CENTER); // El posem a
//
la posició
//
CENTER
JPanel
panelBotons=new JPanel(); //
Creem el JPanel
//
Feina per fer: crear els botons i posar-los al JPanel
getContentPane().add(panelBotons, //
El posem a
BorderLayout.SOUTH); //
la posició
//
SOUTH
}
/**
* Mètode que inicia l'aplicació.
*/
private void inicia () {
pack(); // Adapta
les dimensions d'aquesta Finestra a allò
//
que es necessita, segons els components que
//
contingui.
show();
}
}
|
|
|
|
|
|
|
No oblidis que cal importar
la classe JPanel! |
|
|
|
|
|
Naturalment, si ara compiles
i crees una Finestra, encara no veuràs
el panelBotons perquè, com que està
buit, les seves dimensions són mínimes. |
|
|
|
|
|
Els botons |
|
|
|
|
|
|
Un botó és una instància de la classe javax.swing.JButton
(caldrà importar-la!). Per cada botó cal fixar
|
|
|
|
|
|
- el contenidor que el conté (!). En aquest
cas, es tracta del JPanel panelBotons.
- el text que presenta a l'usuari.
Aquí, excepte el segon, els textos són fixos: "Pas
a pas", "Extermini" i "Sortir".
En canvi, el segon botó, ha de canviar el text entre "Engegar
procés continu" i "Parar procés continu"
segons si el procés continu està parat o engegat. Cal,
doncs, guardar aquests dos textos en una matriu:
/**
* Etiquetes alternatives pel botó d'engegar i parar
el
* procés continu
*/
private String[] etiquetes={"Engegar procés continu",
"Parar procés continu"};
|
com a variable d'instància de la classe Finestra,
per tal de poder-los recuperar quan calgui canviar el text del botó
amb el mètode setText().
- l'objecte ActionListener que
s'encarregarà de gestionar els esdeveniments ActionEvent
que es produeixin en el botó. (Caldrà importar les classes
java.awt.event.ActionListener i java.awt.event.ActionEvent
a la classe Finestra) De les dues possibilitats
que s'expliquen a la pràctica
3 del mòdul 6, fer que la classe principal Finestra
sigui el listener dels botons, o bé, crear un objecte
java.awt.event.ActionListener per a cada botó,
aquí es fa servir la
segona.
- si l'aplicació canviarà l'estat d'activació
o el text d'algun dels botons. En el nostre cas, això passa amb
el botó "Pas a pas" (desactivat mentre el procés
continu és actiu) i amb el botó de comanament del procés
continu, que canvia de text segons ja s'ha dit més
amunt. Això obliga a fer aquests dos botons accessibles pels
mètodes de la classe Finestra i, per
tant, a declarar-los com a variables d'instància de la classe
Finestra:
/**
* Botó "Pas a pas"
*/
private JButton botoPasAPas;
/**
* Botó pel comanament del procés continu
*/
private JButton botoProcesContinu;
|
|
|
|
Ja veus que hi haurà dues
menes de botons: els que no canviaran mai ("Extermini"
i "Sortir") i els botons que sofriran canvis ("Pas
a pas" i "Engegar/parar el procés continu").
De tota manera, pots fer un parell de mètodes a la classe Finestra
que et crein els botons i tel's posin on toca: |
|
|
|
|
|
- un, per posar botons que siguin variables d'instància
(caldrà crear-los abans):
/**
* El procés d'afegir un botó a aquesta Finestra.
* @param botó que cal afegir.
* @param contenidor el Container que contindrà
el botó.
* @param text el text que fa d'etiqueta del botó.
* @param listener l'ActionListener que gestiona els
* esdeveniments que es generen en el botó
*/
private void afegeixBoto(JButton boto,
JPanel
contenidor,
String
text,
ActionListener
listener) {
boto.setText(text);
boto.addActionListener(listener);
contenidor.add(boto);
}
|
- i un altre que, tot aprofitant el mètode anterior,
crea el botó abans d'afegir-lo, i que servirà pels botons
que no sofreixen canvis
/**
* El procés d'afegir un botó a aquesta Finestra.
* @param contenidor el Container que contindrà
el botó.
* @param text el text que fa d'etiqueta del botó.
* @param listener l'ActionListener que gestiona els
* esdeveniments que es generen en el botó
*/
private void afegeixBoto(JPanel contenidor,
String
text,
ActionListener
listener) {
afegeixBoto(new JButton(),contenidor,text,listener);
}
|
|
|
|
|
|
|
Observa que ambdós mètodes
tenen el mateix nom, però no hi ha cap problema, la màquina
virtual de Java
els distingirà bé perquè la llista de paràmetres
de cadascun d'ells és diferent de la de l'altra. D'això se'n
diu sobrecàrrega de mètodes. |
|
|
|
|
|
Els botons... posem-los
d'una vegada! |
|
|
|
|
|
|
Sí, sí: ara mateix!
Ves al mètode setControls() de la classe
Finestra i afegeix-hi això: |
|
|
|
|
 |
/**
* Mètode que crea i distribueix
els controls d'aquesta
* Finestra.
*/
private void setControls () {
monVisible=new MonVisible(this);
// Li passem aquesta
//
Finestra com a parà-
//
metre
getContentPane().add(monVisible,
BorderLayout.CENTER);
// El posem a
//
la posició
//
CENTER
JPanel panelBotons=new
JPanel(); // Creem el JPanel
//
Col·locació del botó "Pas a pas"
botoPasAPas=new
JButton(); // Creem el botó
afegeixBoto(botoPasAPas,panelBotons,"Pas
a pas",
new
ActionListener() {
public
void actionPerformed(ActionEvent evt) {
//
Feina per fer: definir què fa
}
});
//
Col·locació del botó "Procés continu"
botoProcesContinu=new
JButton(); // Creem el botó
afegeixBoto(botoProcesContinu,panelBotons,etiquetes[0],
new
ActionListener() {
public
void actionPerformed(ActionEvent evt) {
//
Feina per fer: definir què fa
}
});
//
Col·locació del botó "Extermini".
No cal crear-lo abans
afegeixBoto(panelBotons,"Extermini",
new
ActionListener() {
public
void actionPerformed(ActionEvent evt) {
//
Feina per fer: definir què fa
}
});
//
Col·locació del botó "Sortir". No
cal crear-lo abans
afegeixBoto(panelBotons,"Sortir",
new
ActionListener() {
public
void actionPerformed(ActionEvent evt) {
//
Feina per fer: definir què fa
}
});
getContentPane().add(panelBotons,
// El posem a
BorderLayout.SOUTH); // la posició
//
SOUTH
}
|
|
|
|
|
|
 |
Ara, si no t'has
oblidat d'incorporar les noves variables d'instància botoPasAPas,
botoProcesContinu i etiquetes
i els dos mètodes afegeixBoto() i importar
les noves classes javax.swing.JButton, java.awt.event.ActionListener
i java.awt.event.ActionEvent, ja pots compilar
i veure, per fi!, els botons: |
|
|
|
|
|
|
|
|
|
|
|
Donem-los una mica de vida... |
|
|
|
|
|
|
De moment, que els botons funcionin
i facin tot el que han de fer no és possible: encara has d'escriure
una pila de codi! Però això no treu que ara ja puguis ferlos
una mica actius. |
|
|
|
|
|
- La actuació més senzilla és sobre
el botó "Sortir", el qual ja podrà fer
la seva feina, és a dir, sortir de l'aplicació. Es tracta
d'afegir la línia
afegeixBoto(panelBotons,"Sortir",
new
ActionListener() {
public
void actionPerformed(ActionEvent evt) {
System.exit(0);
}
});
|
i ja podràs sortir de l'aplicació tot prement aquest botó.
Compila i prova-ho!
- Els botons "Pas a pas" i "Extermini"
hauran d'esperar... què han de fer encara no està escrit!
- Tampoc no està escrit què ha de fer el
botó "Procés continu". Però que
ha de canviar de text i activar o desactivar el seu veí "Pas
a pas" segons el procés continu sigui actiu o no, ja
es pot fer. Necessitem una variable d'instància booleana que
digui si el procés continu és actiu o no:
/**
* Estat d'activitat del procés continu.
*/
boolean esProcesActiu=false;
|
Aleshores, el botó "Procés continu" ha
de canviar el valor de procesContinuActiu,
ha de canviar l'estat d'actiu del botóí "Pas a
pas" i ha de canviar el seu propi text:
afegeixBoto(botoProcesContinu,panelBotons,etiquetes[0],
new
ActionListener() {
public
void actionPerformed(ActionEvent evt) {
esProcesActiu=!esProcesActiu;
botoPasAPas.setEnabled(!esProcesActiu);
if (esProcesActiu) {
botoProcesContinu.setText(
etiquetes[1]);
}
else {
botoProcesContinu.setText(
etiquetes[0]);
}
//
Feina per fer: definir què fa
}
});
|
|
|
|
Compila i assaja: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|