Mòdul 6

Pràctica 1: Interfícies Gràfiques d'Usuari
Tornar presentació tema
Pràctica 1 Pràctica 2 Pràctica 3 Pràctica 4 Pràctica 5 Pràctica 6 Pràctica 6  
     
 

 

 
  Interfícies Gràfiques d'Usuari (GUI: Graphics User Interface)  
     
  Mesurat amb escala informàtica, ja fa "molt" de temps que una bona aplicació, un bon sistema operatiu, és força més apreciat pels seus potencials usuaris si la interacció d'aquests amb el software es fa de la manera tan intuïtiva que ofereix una interfície gràfica, amb els seus botons, icones, elements de selecció, etc. Sobre el vell MS-Dos es van construir les primeres versions de Windows (versions 3.x), Apple va presentar, des del principi, els seus Mac amb interfície gràfica, sobre el sistema operatiu Unix es van muntar els sistemes X-Windows, hi ha diversos sistemes gràfics per a Linux...  
     
  Es tracta, doncs, d'aprendre a vestir una aplicació Java amb una Interfície Gràfica d'Usuari (GUI: Graphics User Interface), és a dir, amb un conjunt de finestres i controls gràfics (icones, botons, etc.) mitjançant la qual l'usuari pot interactuar amb l'aplicació, fer-la servir, vaja!  
     
  Les eines: els paquets java.awt i javax.swing  
     
  Sun Microsystems, els autors i mantenidors del llenguatge Java i dels paquets de classes que formen el SDK (Standard Development Kit) ens proporcionen dos paquets de classes que serveixen per construir GUIs: java.awt i javax.swing. El paquet java.awt és el més primitiu i el primer que es va desenvolupar, però ben aviat, sobre algunes de les classes d'aquest paquet, es va desenvolupar el nou paquet javax.swing, amb moltes classes noves o millorades i que, de fet, ara és el paquet estàndar per construir GUIs i l'únic que es va actualizant amb noves versions.  
     
  La finestra principal  
     
  Bàsicament, una GUI consisteix en una o diverses finestres, les quals contenen els controls d'informació i de comanament de l'aplicació. El paquet javax.swing conté la classe JFrame, la qual representa una finestra. Comencem:  
     
Obre i crea un nou projecte que es dirà finestres. En aquest projecte crea la classe Finestra amb aquest codi:  
     
import javax.swing.JFrame;

/**
* Escriviu aquí una descripcìó de la classe Finestra
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/

public class Finestra extends JFrame {

}
 
     
  La teva classe Finestra hereda les propietats de JFrame i, com que JFrame és una classe del paquet javax.swing, cal que la primera línia del codi sigui  
     
 
import javax.swing.JFrame;
 
     
  per tal d'importar el paquet.  
     
  Ara pots compilar i crear un objecte de la classe Finestra: l'objecte es crea i no passa rés més... Cal configurar-la!  
     
  Configurar un JFrame:    
     
  La configuració general d'una finestra se sol fer en el seu mètode constructor. És aquí on pots determinar-ne el títol, les dimensions i fer-la visible. Només cal cridar l'execució dels mètodes adequats de la classe JFrame:  
     
import javax.swing.JFrame;

/**
* Escriviu aquí una descripcìó de la classe Finestra
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Finestra extends JFrame {


    /**
     * Mètode constructor per objectes de la classe Finestra.
     */

    public Finestra () {
        setTitle("Una finestra");
        setSize(300,200);
        show();
    }

}
 
     
  No cal explicar gaire coses:  
     
 
  • el mètode public void setTitle(String titol) ja es veu què fa: posar la cadena titol com a títol de la finestra

  • el mètode public void setSize(int amplada,int altura) determina les dimensions de la finestra; la unitat de mesura és el píxel.

  • el mètode public void show() fa que la finestra es faci visible i, si ja ho era, la posa al davant de tot de les altres finestres de la mateixa aplicació o d'altres aplicacions que pugui haver-hi obertes.
 
     
Ara compila el projecte i construeix un objecte Finestra. Has d'obtenir això:  
     
 
 
     
  Components i contenidors    
     
  Ara que la finestra ja està en funcionament, ja es pot començar a posar-hi els controls. Però, per fer-ho cal tenir molt clara l'arquitectura que preveu Java per a aquesta tasca i un ha de familiaritzar-se amb l'argot corresponent. Hi ha dos conceptes bàsics:  
     
 
  • Un component (anglès: "Component") és qualsevol objecte capaç de ser afegit, junt amb d'altres components, a una altra mena d'objectes-receptacle, que se'n diuen contenidors. Tots aquests objectes component són fills de la classe java.awt.Component i, en particular, els del paquet javax.swing, són fills de la classe javax.swing.JComponent (classe filla de java.awt.Component).

  • Un contenidor (anglès: "Container") és qualsevol objecte capaç de rebre components, distribuir-los adequadament i presentar-los a la pantalla. Els contenidors són fills de la classe java.awt.Container.
 
     
  L'arbre d'herència d'aquestes classes és aquest:  
     
          java.lang.Object
                |
                +--java.awt.Component
                        |
                        +--java.awt.Container
                                |
                                +--javax.swing.JComponent
 
     
  A dalt de tot hi ha la classe java.lang.Object, que és la mare de totes les classes de Java. Directament, en deriva la classe java.awt.Component i d'ella la classe java.awt.Container. Observa que, d'aquesta disposició de l'arbre, en resulta que tot contenidor és, també un component, cosa que permetrà posar contenidors dintre d'altres contenidors en un ordre de jerarquia tan llarg com calgui.  
     
  El contenidor d'un JFrame    
     
  Els objectes de la classe javax.swing.JFrame, com és la Finestra que acabes de crear, porten incorporat un contenidor per tal que hi puguis posar els components que vulguis. Aquest contenidor s'obté tot demanant el mètode de la classe JFrame  
     
  public Container getContentPane()  
     
  i és en aquest objecte Container que hem de posar els components.  
     
  Layout managers    
     
 

Bé, bé, però, com es posen els components en un contenidor?

 
     
  La resposta no és gens simple i, prèviament, cal haver assimilat el concepte de layout manager. Som-hi, doncs:  
     
  "Write once, run anywhere". Ja saps que una aplicació Java ha de ser independent del maquinari. I, ara, això té molta importància aquí: la GUI de les teves aplicacions no pot pressuposar res, per exemple, sobre el tamany o la resolució en píxels de la pantalla del ordinador en la qual s'executaran. Per tant, no es una bona cosa pensar: "Vull un botó de 90 x 40 a la posició 145, 230" i, de fet, les classes de java.awt i de javax.swing ja s'encarreguen d'impedir tan com poden que el programador se'n surti si pensa les coses així...

Cal aprendre a pensar en termes de "layouts". Un layout és un esquema general de disposició a la pantalla dels components d'un contenidor. El layout manager (que, com era d'esperar, és un objecte d'alguna classe que representi layout managers) corresponent s'encarrega automàticament de donar les dimensions adequades als components i d'alinear-los segons les disponibilitats.

 
     
  Els layout managers disponibles al paquet java.awt són aquests:  
     
 
  • java.awt.BorderLayout

  • java.awt.CardLayout

  • java.awt.FlowLayout

  • java.awt.GridBagLayout

  • java.awt.GridLayout
 
     
  dels quals te n'invitem a veure'n la documentació ara mateix.  
     
  En resum: si vols disposar elements per a una GUI, aquests elements han de ser derivats de la classe java.awt.Component, o d'alguna de les seves classes filles (tots els controls ho són!). El lloc per disposar-los ha de ser una classe derivada de java.awt.Container (o d'alguna de les seves classes filles) provista del layout manager que més s'adigui als teus desitjos de programador.
 
     
  Per a usos corrents, el contenidor adequat és gairebé sempre de la classe javax.swing.JPanel.
 
     
  BorderLayout    
     
  El contenidor que, per defecte, va amb un JFrame i que s'obté mitjançant el mètode getContentPane() incorpora, també per defecte, un objecte java.awt.BorderLayout com a layout manager. Aquest layout manager admet fins a cinc components i els disposa així:
 
     
 
 
     
 

i, quan vulguis afegir els teus components, cal fer servir el mètode

 
     
  public void add(Component component,String posicio)  
     
  del contenidor que s'obté amb getComponentPane(). El paràmetre posicio és un dels cinc valors static:  
     
 
  • BorderLayout.NORTH

  • BorderLayout.SOUTH

  • BorderLayout.EAST

  • BorderLayout.WEST

  • BorderLayout.CENTER
 
     
  Posa tot això en marxa: a la classe Finestra afegeix-li aquest codi:  
     
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JButton;
import java.awt.BorderLayout;


/**
* Escriviu aquí una descripcìó de la classe Finestra
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Finestra extends JFrame {

    /**
     * Mètode constructor per objectes de la classe Finestra.
     */
    public Finestra () {
        setTitle("Una finestra");
        setSize(300,200);

        Container cnt=getContentPane();
        cnt.add(new JButton("Botó nord"),BorderLayout.NORTH);
        cnt.add(new JButton("Botó sud"),BorderLayout.SOUTH);
        cnt.add(new JButton("Botó est"),BorderLayout.EAST);
        cnt.add(new JButton("Botó oest"),BorderLayout.WEST);
        cnt.add(new JButton("Botó centre"),BorderLayout.CENTER);
        show();
    }

}
 
     
  Observa que has de començar per demanar el contenidor del JFrame amb la línia  
     
 
        Container cnt=getContentPane();
 
     
  cosa que obliga a importar la classe java.awt.Container del paquet java.awt just al començament del codi:  
     
 
import java.awt.Container;
 
     
  Després només cal afegir els components amb el mètode add del contenidor cont:  
     
 
        cnt.add(new JButton("Botó nord"),BorderLayout.NORTH);
        cnt.add(new JButton("Botó sud"),BorderLayout.SOUTH);
        cnt.add(new JButton("Botó est"),BorderLayout.EAST);
        cnt.add(new JButton("Botó oest"),BorderLayout.WEST);
        cnt.add(new JButton("Botó centre"),BorderLayout.CENTER);
 
     
Els components afegits són objectes de la classe javax.swing.JButton (que cal importar!) en les posicions determinades per les constants de java.awt.BorderLayout (que també cal importar!). El resultat ha de ser aquest:  
     
 
 
     
  Instructius experiments amb BorderLayout:    
     
  1. Comença per escursar el text dels cinc botons: en lloc de "Botó nord", "Botó est", etc. posa-hi només les inicials, és a dir "N", "E", etc.:

    import javax.swing.JFrame;
    import java.awt.Container;
    import javax.swing.JButton;
    import java.awt.BorderLayout;

    /**
    * Escriviu aquí una descripcìó de la classe Finestra
    *
    * @author (el vostre nom)
    * @version (un número de versió o la data)
    */
    public class Finestra extends JFrame {

        /**
         * Mètode constructor per objectes de la classe Finestra.
         */
        public Finestra () {
            setTitle("Una finestra");
            setSize(300,200);
            Container cnt=getContentPane();

            cnt.add(new JButton("N"),BorderLayout.NORTH);
            cnt.add(new JButton("S"),BorderLayout.SOUTH);
            cnt.add(new JButton("E"),BorderLayout.EAST);
            cnt.add(new JButton("O"),BorderLayout.WEST);
            cnt.add(new JButton("C"),BorderLayout.CENTER);
            show();
        }

    }

    Obtindràs això:


    i estaràs veient com el layout manager s'ho fa per adaptar les dimensions dels components a les necessitats!

  2. Ara canvia les dimensions de la finestra:

    import javax.swing.JFrame;
    import java.awt.Container;
    import javax.swing.JButton;
    import java.awt.BorderLayout;

    /**
    * Escriviu aquí una descripcìó de la classe Finestra
    *
    * @author (el vostre nom)
    * @version (un número de versió o la data)
    */
    public class Finestra extends JFrame {

        /**
         * Mètode constructor per objectes de la classe Finestra.
         */
        public Finestra () {
            setTitle("Una finestra");
            
    setSize(500,100);
            Container cnt=getContentPane();
            cnt.add(new JButton("N"),BorderLayout.NORTH);
            cnt.add(new JButton("S"),BorderLayout.SOUTH);
            cnt.add(new JButton("E"),BorderLayout.EAST);
            cnt.add(new JButton("O"),BorderLayout.WEST);
            cnt.add(new JButton("C"),BorderLayout.CENTER);
            show();
        }

    }

    amb aquest resultat:


  3. I, encara, torna als textos inicials, i suprimeix la determinació de les dimensions:

    import javax.swing.JFrame;
    import java.awt.Container;
    import javax.swing.JButton;
    import java.awt.BorderLayout;

    /**
    * Escriviu aquí una descripcìó de la classe Finestra
    *
    * @author (el vostre nom)
    * @version (un número de versió o la data)
    */
    public class Finestra extends JFrame {

        /**
         * Mètode constructor per objectes de la classe Finestra.
         */
        public Finestra () {
            setTitle("Una finestra");
            
    //setSize(500,100);
            Container cnt=getContentPane();

            cnt.add(new JButton("Botó nord"),BorderLayout.NORTH);
            cnt.add(new JButton("Botó sud"),BorderLayout.SOUTH);
            cnt.add(new JButton("Botó est"),BorderLayout.EAST);
            cnt.add(new JButton("Botó oest"),BorderLayout.WEST);
            cnt.add(new JButton("Botó centre"),BorderLayout.CENTER);
            show();
        }

    }

    i, aleshores...


    Eeeeep! clar! sense dimensions tenim dimensions 0 x 0... Cal tornar a posar la línia que establia les dimensions de la finestra, no?

  4. Doncs no, no: no cal. És més, millor no posar-la mai, de no ser que la naturalesa de les coses ens hi obligui. Què fer, doncs?

    Simplement, deixar que el layout manager faci la seva feina i, just abans de cridar al mètode show(), que fa visible la finestra, cridar el mètode pack(), el qual dóna les dimensions necessàries als components i redimensiona la finestra segons les necessitats del layout manager:

    import javax.swing.JFrame;
    import java.awt.Container;
    import javax.swing.JButton;
    import java.awt.BorderLayout;

    /**
    * Escriviu aquí una descripcìó de la classe Finestra
    *
    * @author (el vostre nom)
    * @version (un número de versió o la data)
    */
    public class Finestra extends JFrame {

        /**
         * Mètode constructor per objectes de la classe Finestra.
         */
        public Finestra () {
            setTitle("Una finestra");
            //setSize(500,100);
            Container cnt=getContentPane();
            cnt.add(new JButton("Botó nord"),BorderLayout.NORTH);
            cnt.add(new JButton("Botó sud"),BorderLayout.SOUTH);
            cnt.add(new JButton("Botó est"),BorderLayout.EAST);
            cnt.add(new JButton("Botó oest"),BorderLayout.WEST);
            cnt.add(new JButton("Botó centre"),BorderLayout.CENTER);

            pack();
            show();
        }

    }

    A veure, a veure...


    Ara està tot bé!
 
     
  Una mica més d'experimentació et convencerà de les propietats del layout manager BorderLayout:  
     
 
  • les dimensions del JButton s'adapten a les necessitats: un botó té les dimensions mínimes per tal que hi càpiga el text que ha de mostrar

  • java.awt.BorderLayout ignora les dimensions horitzontals dels components situats a "NORTH" i "SOUTH", però en respecta les verticals.

  • java.awt.BorderLayout ignora les dimensions verticals dels components situats a "EAST" i "WEST", però en respecta les horitzontals.

  • java.awt.BorderLayout ignora tant les dimensions horitzontals com les verticals del component situat a "CENTER".
 
     
  FlowLayout    
     
  java.awt.BorderLayout és el layout manager per defecte del contenidor d'un JFrame, però pots canviar-lo. Inmediatament després de la línia:  
     
 
        Container cnt=getContentPane();
 
     
  insertem la línia:  
     
 
        cnt.setLayout(new FlowLayout());
 
     
 

la qual determina que, ara, el contenidor cnt té una instància de java.awt.FlowLayout com a layout manager. També cal que canviem les línies

 
     
 
        cnt.add(new JButton("Botó nord"));
        cnt.add(new JButton("Botó sud"));
        cnt.add(new JButton("Botó est"));
        cnt.add(new JButton("Botó oest"));
        cnt.add(new JButton("Botó centre"));
 
     
  perquè el layout manager FlowLayout no demana posicions. I, naturalment, cal importar la classe java.awt.FlowLayout! El codi és:  
     
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JButton;
import java.awt.FlowLayout;

/**
* Escriviu aquí una descripcìó de la classe Finestra
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Finestra extends JFrame {

    /**
     * Mètode constructor per objectes de la classe Finestra.
     */
    public Finestra () {
        setTitle("Una finestra");
        //setSize(500,100);
        Container cnt=getContentPane();
        cnt.setLayout(new FlowLayout());
        cnt.add(new JButton("Botó nord"));
        cnt.add(new JButton("Botó sud"));
        cnt.add(new JButton("Botó est"));
        cnt.add(new JButton("Botó oest"));
        cnt.add(new JButton("Botó centre"));
        pack();
        show();
    }

}
 
     
  i el resultat és:  
     
 
     
  tot mostrant les característiques d'aquest layout manager:  
     
 
  • Les dimensions, tant horitzontals com verticals, dels components es respecten.

  • Els components es disposen cadascun a continuació de l'anterior, de la mateixa manera que les paraules d'un text. Quan s'esgota l'espai horitzontal, s'inicia una nova línia.
 
     
  En efecte, si ara mires de canviar les dimensions de la finestra amb el ratolí, veuràs què passa:  
     
 
     
  GridLayout    
     
  És el tercer dels layout managers més usats.  
     
 
  • el layout manager  java.awt.GridLayout disposa els components en una matriu rectangular de files files i columnes columnes. El mètode constructor és: public GridLayout(int files,int columnes).

  • No es respecten cap de les dimensions dels components. Les dimensions es forcen per tal que totes les cel·les de la matriu siguin iguals
 
     
  Per fer-ne la prova, substitueix la línia  
     
 
        cnt.setLayout(new FlowLayout());
 
     
  per la línia  
     
 
        cnt.setLayout(new GridLayout(3,2));
 
     
  i obtindràs això:  
     
 
     
  i, amb  
     
 
        cnt.setLayout(new GridLayout(4,2));
 
     
  això:  
     
 
     
  Combinacions de Layout Managers:    
     
  Naturalment, aquests layout managers es poden combinar per donar lloc a estructures més complexes. La classe javax.swing.JPanel és filla de javax.swing.JComponent, la qual és filla de java.awt.Container. Per tant, javax.swing.JPanel és un contenidor (pot admetre components) i també és un component i, per tant, pot ser incorporat a un contenidor. Això vol dir que podem prendre una instància de javax.swing.JPanel, dotar-la del layout manager que ens interessi (per defecte és java.awt.FlowLayout) posar-hi els components que calgui i posar-ho tot plegat com a component a algun contenidor de la nostra finestra, que ja tindrà el seu propi layout manager. En el codi de la classe FinestraComplexa següent:
 
     
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;

/**
* Escriviu aquí una descripcìó de la classe FinestraComplexa
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/

public class FinestraComplexa extends JFrame {

    /**
     * Mètode constructor d'objectes de la classe FinestraComplexa
     */

    public FinestraComplexa () { // constructor
        setTitle("Una finestra complicada");
        // El contenidor arrel ja té, per defecte BorderLayout
        // com a layout manager.
        Container cnt=getContentPane();
        // Un JPanel, amb FlowLayout per defecte, per posar-lo
        // al nord

        JPanel panelNord=new JPanel();
        panelNord.add(new JButton("Botó N1"));
        panelNord.add(new JButton("Botó N2"));
        panelNord.add(new JButton("Botó N3"));
        panelNord.add(new JButton("Botó N4"));
        panelNord.add(new JButton("Botó N5"));
        panelNord.add(new JButton("Botó N6"));
        cnt.add(panelNord,BorderLayout.NORTH);
        // Un JButton sol, per posar-lo a l'oest
        cnt.add(new JButton("Botó oest"),BorderLayout.EAST);
        // Un JPanel, amb GridLayout de tres files i dues
        // columnes, per posar-lo al centre
        JPanel panelCentre=new JPanel();
        panelCentre.setLayout(new GridLayout(3,2));

        panelCentre.add(new JButton("Botó C1"));
        panelCentre.add(new JButton("Botó C2"));
        panelCentre.add(new JButton("Botó C3"));
        panelCentre.add(new JButton("Botó C4"));
        panelCentre.add(new JButton("Botó C5"));
        panelCentre.add(new JButton("Botó C6"));
        cnt.add(panelCentre,BorderLayout.CENTER);

        // Un JPanel, amb GridLayout de d'una fila i quatre
        // columnes, per posar-lo al sud
        JPanel panelSud=new JPanel();
        panel
Sud.setLayout(new GridLayout(1,4));
        panel
Sud.add(new JButton("Botó S1"));
        panel
Sud.add(new JButton("Botó S2"));
        panel
Sud.add(new JButton("Botó S3"));
        panel
Sud.add(new JButton("Botó S4"));
        cnt.add(panelSud,BorderLayout.SOUTH);
        // L'est el deixem buit
        pack();
        show();
    }

}
 
     
  hi ha tres JPanel que actuen de contenidors, posats com a components al contenidor arrel de la finestra. Pots identificar la posició dels tres JPanel del codi a la finestra que s'obté?  
     
 
     
  El cursor del ratolí  
     
  A vegades convé que el cursor del ratolí, en estar sobre un cert component, no presenti l'aspecte de la sageta habitual. El SDK de Java preveu catorze aspectes diferents pel cursor del ratolí:  
     
 
Cursor per defecte: Cursor.DEFAULT_CURSOR
Cursor ma Cursor.HAND_CURSOR
Cursor de moviment Cursor.MOVE_CURSOR
Cursor de creu Cursor.CROSSHAIR_CURSOR
Cursor de text Cursor.TEXT_CURSOR
Cursor d'espera Cursor.WAIT_CURSOR
Cursor de redimensió al nord Cursor.N_RESIZE_CURSOR
Cursor de redimensió al nordoest Cursor.NW_RESIZE_CURSOR
Cursor de redimensió a l'oest Cursor.W_RESIZE_CURSOR
Cursor de redimensió al sudoest Cursor.SW_RESIZE_CURSOR
Cursor de redimensió al sud Cursor.S_RESIZE_CURSOR
Cursor de redimensió al sudest Cursor.SE_RESIZE_CURSOR
Cursor de redimensió a l'est Cursor.E_RESIZE_CURSOR
Cursor de redimensió al nordest Cursor.NE_RESIZE_CURSOR
 
     
  A la columna de la dreta hi ha els camps static int de la classe java.awt.Cursor que serveixen per identificar el cursor que es vulgui implementar. Per construir un objecte de la classe java.awt.Cursor, el mètode constructor és:  
     
 
public Cursor (int identificadorTipusCursor)
 
     
  i el paràmetre és un dels valors de la columna de la dreta de la taula anterior.  
     
  Per fer que el cursor així construït sigui el cursor que apareixerà quan estigui sobre cert component (java.awt.Component, classe mare de tots els objectes components d'una GUI), el mètode a executar és el de la classe java.awt.Component  
     
 
public void setCursor (Cursor cursor)
 
     
Pots provar ara com funciona això. A la classe FinestraComplexa d'abans afegeix-li un cursor per a cadascun dels JPanels que la componen:  
     

import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;

import java.awt.Cursor;

/**
* Escriviu aquí una descripcìó de la classe FinestraComplexa
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class FinestraComplexa extends JFrame {

    /**
     * Mètode constructor d'objectes de la classe FinestraComplexa
     */
    public FinestraComplexa () { // constructor
        setTitle("Una finestra complicada amb canvis de cursors");
        // El contenidor arrel ja té, per defecte BorderLayout
        // com a layout manager.
        Container cnt=getContentPane();
        // Un JPanel, amb FlowLayout per defecte, per posar-lo
        // al nord
        JPanel panelNord=new JPanel();

        // El cursor ma pel panel del nord
        panelNord.setCursor(new Cursor(Cursor.HAND_CURSOR));
        panelNord.add(new JButton("Botó N1"));
        panelNord.add(new JButton("Botó N2"));
        panelNord.add(new JButton("Botó N3"));
        panelNord.add(new JButton("Botó N4"));
        panelNord.add(new JButton("Botó N5"));
        panelNord.add(new JButton("Botó N6"));
        cnt.add(panelNord,BorderLayout.NORTH);
        // Un JButton sol, per posar-lo a l'oest
        cnt.add(new JButton("Botó oest"),BorderLayout.EAST);
        // Un JPanel, amb GridLayout de tres files i dues
        // columnes, per posar-lo al centre
        JPanel panelCentre=new JPanel();
        // El cursor d'espera pel panel del centre
        panelCentre.setCursor(new Cursor(Cursor.WAIT_CURSOR));
        panelCentre.setLayout(new GridLayout(3,2));
        panelCentre.add(new JButton("Botó C1"));
        panelCentre.add(new JButton("Botó C2"));
        panelCentre.add(new JButton("Botó C3"));
        panelCentre.add(new JButton("Botó C4"));
        panelCentre.add(new JButton("Botó C5"));
        panelCentre.add(new JButton("Botó C6"));
        cnt.add(panelCentre,BorderLayout.CENTER);
        // Un JPanel, amb GridLayout de d'una fila i quatre
        // columnes, per posar-lo al sud
        JPanel panelSud=new JPanel();
        // El cursor de moviment pel panel del sud
        panelSud.setCursor(new Cursor(Cursor.MOVE_CURSOR));
        panelSud.setLayout(new GridLayout(1,4));
        panelSud.add(new JButton("Botó S1"));
        panelSud.add(new JButton("Botó S2"));
        panelSud.add(new JButton("Botó S3"));
        panelSud.add(new JButton("Botó S4"));
        cnt.add(panelSud,BorderLayout.SOUTH);
        // L'est el deixem buit
        pack();
        show();
    }

}

 
     
  En compilar i crear un nou objecte FinestraComplexa, veuràs com el cursor canvia al moure el ratolí sobre cadascún dels tres JPanels, components d'aquesta finestra. En canvi, sobre el botó de l'oest, el cursor és el de defecte:  
     
 
     
 
 
     
 
 
     
 
 
     
  Un exercici...  
     
Ara has de ser capaç d'escriure una classe amb una combinació adequada de JPanels i layout managers que obri una finestra exactament com aquesta:  
     
 
     
  Com sempre, si no te'n surts (ei! només si no te'n surts, eh?) aquí tens la solució de l'exercici.  
     
    Tornar al principi