|
|
|
|
|
|
|
Controls de text:
JTextComponent |
|
|
|
|
|
Un objecte JLabel,
en certa forma, es pot considerar que és un control de text.
Passa que en un objecte JLabel el text és
estàtic i passiu: és sempre el mateix fins que, des de fora,
tot cridant el mètode setText(), no el
canviem. Això passa perquè els objectes JLabel
no estan preparats per emetre esdeveniments ("events")
relacionats amb el text. Els veritables controls de text, però,
tenen ja implementades funcionalitats que els fan actius. Tots els controls
de text deriven de la classe mare javax.swing.text.JTextComponent. |
|
|
|
|
|
Una línia
de text: JTextField |
|
|
|
|
|
|
Un objecte JTextField consisteix en una zona en la qual s'hi pot escriure
i editar text. Els objectes JTextField emeten un esdeveniment java.awt.event.ActionEvent
quen hom prem la tecla "Retorn". Els mètodes més
importants són aquests:
- public JTextField(int columnes):
Mètode constructor. Construeix un objecte JTextField
buit amb una amplada de columnes columnes.
- public JTextField(String text):
Mètode constructor. Construeix un objecte JTextField
en el qual hi apareix el text text.
- public JTextField(String text, int
columns): Mètode constructor. Construeix un objecte JTextField
en el qual hi apareix el text text. i que
presenta una amplada de columnes columnes.
- public void setText(String text),
(heredat de JTextComponent): Posa el text
text a la zona editable.
- public String getText(), (heredat
de JTextComponent): Retorna el text que hi
hagi a la zona editable.
|
|
|
|
|
 |
Ara pots veure com funciona.
Crea un nou projecte que es digui textos i escriu-hi
la classe TextSimple següent: |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextField;
import java.awt.GridLayout;
/**
* Escriviu aquí una descripcìó de la
classe TextSimple
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextSimple extends JFrame {
/**
* Mètode constructor per
a objectes de la classe TextSimple
*/
public TextSimple () {
setTitle("Exemple
de JTextField");
Container cnt=getContentPane();
cnt.setLayout(new
GridLayout(1,1));
//
Ara es construeix un objecte JTextField de 30 columnes:
JTextField textField=new
JTextField(30);
cnt.add(textField);
pack();
show();
}
}
|
|
|
|
|
|
|
En compilar i crear un
objecte TextSimple, obtindràs això: |
|
|
|
|
|
|
|
|
|
|
|
Ara es tracta que facis
funcionar alguns dels mètodes de la classe JTextField.
Afegeix un objecte JLabel i fes que la classe
TextSimple sigui sensible als esdeveniments ActionEvent
que emet l'objecte JTextField. Cal, per tant,
que la classe TextSimple implementi la interfície
(interface) java.awt.ActionListener: |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextField;
import java.awt.GridLayout;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/**
* Escriviu aquí una descripcìó de la
classe TextSimple
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextSimple extends JFrame implements ActionListener
{
/**
* El Jlabel
*/
JLabel label;
/**
* Mètode constructor per
a objectes de la classe TextSimple
*/
public TextSimple () {
setTitle("Exemple
de JTextField");
Container cnt=getContentPane();
cnt.setLayout(new
GridLayout(2,1));
// Ara es construeix
un objecte JTextField de 30 columnes:
JTextField textField=new
JTextField(30);
//
El JFrame ha d'escoltar al textField:
textField.addActionListener(this);
cnt.add(textField);
label=new JLabel();
cnt.add(label);
pack();
show();
}
/**
* Mètode que s'executa quan
textField emet un ActionEvent, és
* a dir, quan es prem la tecla "Retorn"
*/
public void actionPerformed (ActionEvent e)
{
}
}
|
|
|
|
|
|
|
Ara ja tens això: |
|
|
|
|
|
|
|
|
|
|
|
Però encara no passa res! Només falta omplir el mètode
public void actionPerformed (ActionEvent e).
Es tracta que, quan es premi la tecla "Retorn",
el text excrit aparegui al label i el textField
quedi en blanc:
|
|
|
|
|
|
<codi anterior>
/**
* Mètode que s'executa quan
textField emet un ActionEvent, és
* a dir, quan es prem la tecla "Retorn".
El text que hi ha a
* textField passa a label i textField
queda net.
*/
public void actionPerformed
(ActionEvent e) {
Object ob=e.getSource();
if
(ob instanceof JTextField) {
JTextField
textField=(JTextField)ob;
String
elText=textField.getText();
textField.setText("");
label.setText(elText);
}
}
}
|
|
|
|
|
|
|
Ara ja està: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
La classe JTextField
és útil, per tant, quan es tracta que l'aplicació rebi
textos curts entrats pel teclat. |
|
|
|
|
|
JPasswordField |
|
|
|
|
|
|
Una classe derivada de
la classe JTextField és la classe JPasswordField.
Es tracta que el text escrit a la zona corresponent no es vegi tal com l'usuari
el tecleja, sinó que quedi substituït per una sèrie d'asteriscs.
Crea una nova classe Contrassenya, amb el mateix
codi de la classe TextSimple, en la qual l'objecte
JTextField textField ara sigui un objecte JPasswordField: |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextField;
import java.awt.GridLayout;
import javax.swing.JLabel;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JPasswordField;
/**
* Escriviu aquí una descripcìó de la
classe TextSimple
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Contrassenya extends JFrame
implements ActionListener {
/**
* El Jlabel
*/
JLabel label;
/**
* Mètode constructor per
a objectes de la classe Contrassenya
*/
public Contrassenya () {
setTitle("Exemple
de JPasswordField");
Container cnt=getContentPane();
cnt.setLayout(new
GridLayout(2,1));
//
Ara es construeix un objecte JPasswordField de
// 30columnes:
JPasswordField
textField=new JPasswordField(30);
// El JFrame ha
d'escoltar al textField:
textField.addActionListener(this);
cnt.add(textField);
label=new JLabel();
cnt.add(label);
pack();
show();
}
/**
* Mètode que s'executa quan
textField emet un ActionEvent, és
* a dir, quan es prem la tecla "Retorn"
*/
public void actionPerformed (ActionEvent e)
{
Object ob=e.getSource();
if
(ob instanceof JTextField) {
JTextField
textField=(JTextField)ob;
String
elText=textField.getText();
textField.setText("");
label.setText(elText);
}
}
}
|
|
|
|
|
|
|
Observa que, com que
JPasswordField és una classe filla de la
classe JTextField, el mètode actionPerformed
continua funcionant sense fer-hi cap variació: un objecte JPasswordField
és, també, un objecte JTextField!
|
|
|
|
|
|
En compilar i crear un
objecte Contrassenya, pots veure'n el funcionament: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ara podries investigar
una mica més i fer que, en el mètode actionPerformed
de la classe Contrassenya, l'objecte que conté el text sigui un objecte
JPasswordField i no un simple JTextField: |
|
|
|
|
|
<codi anterior>
/**
* Mètode que s'executa quan
textField emet un ActionEvent, és
* a dir, quan es prem la tecla "Retorn".
El text que hi ha a
* textField passa a label i textField
queda net.
*/
public void actionPerformed (ActionEvent e)
{
Object ob=e.getSource();
if
(ob instanceof JPasswordField) {
JPasswordField
textField=(JPasswordField)ob;
String
elText=textField.getText();
textField.setText("");
label.setText(elText);
}
}
}
|
|
|
|
|
|
|
Què passa? Malgrat
que el codi es deixa compilar i que tot segueix funcionant perfectament
com abans, el compilador javac.exe et treu
un missatge d'advertiment: |
|
|
|
|
|
Avisos de la darrera compilació
...\textos\Contrassenya.java:53:
warning: getText() in javax.swing.JPasswordField has been deprecated
|
|
|
|
|
|
Què vol dir això? |
|
|
|
|
|
Simplement, és un avís que Sun
Microsystems, en alguna propera versió de Java,
ja no inclourà el mètode getText()
a la classe JPasswordField i, que, per tant,
si la teva aplicació el fa servir, ja no funcionarà amb
noves versions de Java.
Què fer?
Només cal anar a la documentació de la classe JPasswordField,
veure què diu del mètode getText():
|
|
|
|
|
|
getText
public String getText()
Deprecated. As
of Java 2 platform v1.2, replaced by getPassword.
|
|
|
|
|
|
Això vol dir que,
en lloc del mètode getText(), cal fer servir
el mètode public char[] getPassword(),
però, atenció! que aquest mètode no ens torna pas una
cadena (String), sinó una matriu de caràcters
(char[]). Si vols salvar l'aplicació Contrassenya,
cal que construeixis una cadena a partir de la matriu de caràcters
(recorda
la pràctica 6 del mòdul 3) amb el mètode constructor
de la classe String public
String(char[] caracters): |
|
|
|
|
|
<codi anterior>
/**
* Mètode que s'executa quan
textField emet un ActionEvent, és
* a dir, quan es prem la tecla "Retorn".
El text que hi ha a
* textField passa a label i textField
queda net.
*/
public void actionPerformed (ActionEvent e)
{
Object ob=e.getSource();
if
(ob instanceof JPasswordField) {
JPasswordField
textField=(JPasswordField)ob;
char[]
elText=textField.getPassword();
textField.setText("");
label.setText(new
String(elText));
}
}
}
|
|
|
|
|
|
|
És fàcil
imaginar per què això és així: els objectes
de la classe JPasswordField es faran servir de
manera gairebé exclusiva a que els usuaris d'una certa aplicació
hi entrin la seva contrassenya. El mètode getPassword()
recull aquesta contrassenya directament com a matriu de caràcters,
apta per les manipulacions d'encriptació i desencriptació
que puguin venir després; recollir la contrassenya com a objecte
String obligaria a despecejar-la en caràcters
abans de poder-la manipular. |
|
|
|
|
|
JTextArea |
|
|
|
|
|
|
La classe JTextArea,
filla també de la classe javax.swing.text.JTextComponent,
té una funcionalitat semblant a la classe JTextField,
amb la diferència que ara disposem de vàries línies
de text en lloc de només una. Això implica algunes complicacions
que cal analitzar. De passada veuràs com funcionen els esdeveniments
javax.swing.event.CaretEvent que qualsevol classe
filla de javax.swing.text.JTextComponent, és
capaç d'emetre. |
|
|
|
|
 |
En el projecte textos
i escriu-hi la classe TextLlarg següent:
|
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
/**
* Escriviu aquí una descripcìó de la
classe TextLlarg
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextLlarg extends JFrame {
/**
* Mètode constructor per
a objectes de la classe TextLlarg
*/
public TextLlarg () {
setTitle("Exemple
de JTextArea");
Container cnt=getContentPane();
//
Ara es construeix un objecte JTextArea de 4 files i 30
// columnes:
JTextArea textArea=new
JTextArea(4,30);
cnt.add(textArea,BorderLayout.CENTER);
pack();
show();
}
}
|
|
|
|
|
|
|
Obtindràs això: |
|
|
|
|
|
|
|
|
|
|
|
Però, però...
no talla les línies! No, no les talla: si vols que ho faci, has de
cridar al mètode public void setLineWrap(boolean
talla_les_linies) de la classe JTextArea
i fer que talla_les_linies sigui true: |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
/**
* Escriviu aquí una descripcìó de la
classe TextLlarg
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextLlarg extends JFrame {
/**
* Mètode constructor per
a objectes de la classe TextLlarg
*/
public TextLlarg () {
setTitle("Exemple
de JTextArea");
Container cnt=getContentPane();
// Ara es construeix
un objecte JTextArea de 4 files i 30
// columnes:
JTextArea textArea=new
JTextArea(4,30);
//
Que talli les línies!
textArea.setLineWrap(true);
cnt.add(textArea,BorderLayout.CENTER);
pack();
show();
}
}
|
|
|
|
|
|
|
Ara talla bé les
línies: |
|
|
|
|
|
|
|
|
|
|
|
però, quan les
quatre línies disponibles s'acaben ja no pots veure allò que
escrius! Solució: en lloc d'afegir directament al contenidor del
JFrame TextLlarg l'objecte TextArea,
cal afegir-lo a un objecte javax.swing.JScrollPane
i, aquest és el que has d'afegir al contenidor: |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
/**
* Escriviu aquí una descripcìó de la
classe TextLlarg
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextLlarg extends JFrame {
/**
* Mètode constructor per
a objectes de la classe TextLlarg
*/
public TextLlarg () {
setTitle("Exemple
de JTextArea");
Container cnt=getContentPane();
// Ara es construeix
un objecte JTextArea de 4 files i 30
// columnes:
JTextArea textArea=new
JTextArea(4,30);
// Que talli les
línies!
textArea.setLineWrap(true);
JScrollPane
jsp=new JScrollPane(textArea);
cnt.add(jsp,BorderLayout.CENTER);
pack();
show();
}
}
|
|
|
|
|
|
|
Apareix una barra de
desplaçament vertical (Scrollbar) que permet accedir a tot el text: |
|
|
|
|
|
|
|
|
|
|
|
Ara veuràs com
es pot recuperar aquest text amb el mètode getText().
Afegiràs un botó el qual, en prémer-lo, ens donarà
el text a la finestra de comanaments. Però, com que l'objecte JTextArea
ha de ser accessible per un altre mètode a part del constructor,
aquest objecte ha de ser un camp de la classe TextLlarg. |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
/**
* Escriviu aquí una descripcìó de la
classe TextLlarg
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextLlarg extends JFrame
implements ActionListener {
/**
* L'objecte JTextArea
*/
JTextArea textArea;
/**
* Mètode constructor per
a objectes de la classe TextLlarg
*/
public TextLlarg () {
setTitle("Exemple
de JTextArea");
Container cnt=getContentPane();
//
Ara es construeix l'objecte JTextArea de 4 files i 30
// columnes:
textArea=new
JTextArea(4,30);
// Que talli les
línies!
textArea.setLineWrap(true);
JScrollPane jsp=new
JScrollPane(textArea);
cnt.add(jsp,BorderLayout.CENTER);
//
Afegim un botó
JButton
boto=new JButton("Exportar el text");
boto.addActionListener(this);
cnt.add(boto,BorderLayout.SOUTH);
pack();
show();
}
/**
* Mètode que s'executa quan
es prem el botó
*/
public void actionPerformed (ActionEvent
e) {
Object ob=e.getSource();
if
(ob instanceof JButton) {
String
elText=textArea.getText();
System.out.println(elText);
}
}
}
|
|
|
|
|
|
|
El resultat és: |
|
|
|
|
|
|
|
|
|
|
|
I, en prémer el
botó, |
|
|
|
|
|
|
|
|
|
|
|
Esdeveniments
javax.swing.event.CaretEvent: |
|
|
|
|
|
Tots els objectes de
les classes derivades de javax.swing.text.JTextComponent
són capaços d'emetre esdeveniments javax.swing.event.CaretEvent
quan hi ha alguna variació en el text que conté el JTextComponent.
Naturalment, tot seguint l'esquema esdeveniment-oient (event-listener)
hi ha disponible la interfície (interface) javax.swing.event.CaretListener
que han d'implementar els objectes oïdors dels esdeveniments
javax.swing.event.CaretEvent. |
|
|
|
|
|
Comença per implementar
la interfície CaretListener a la classe
TextLLarg: |
|
|
|
|
 |
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.CaretEvent;
/**
* Escriviu aquí una descripcìó de la
classe TextLlarg
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextLlarg extends JFrame
implements ActionListener,
CaretListener
{
/**
* L'objecte JTextArea
*/
JTextArea textArea;
/**
* Mètode constructor per
a objectes de la classe TextLlarg
*/
public TextLlarg () {
setTitle("Exemple
de JTextArea");
Container cnt=getContentPane();
// Ara es construeix
l'objecte JTextArea de 4 files i 30
// columnes:
textArea=new JTextArea(4,30);
// Que talli les
línies!
textArea.setLineWrap(true);
textArea.addCaretListener(this);
JScrollPane jsp=new
JScrollPane(textArea);
cnt.add(jsp,BorderLayout.CENTER);
// Afegim un botó
JButton boto=new
JButton("Exportar el text");
boto.addActionListener(this);
cnt.add(boto,BorderLayout.SOUTH);
pack();
show();
}
/**
* Mètode que s'executa quan
es prem el botó
*/
public void actionPerformed (ActionEvent
e) {
Object ob=e.getSource();
if
(ob instanceof JButton) {
String
elText=textArea.getText();
System.out.println(elText);
}
}
/**
* Mètode que s'executa quan
textArea emet un CaretEvent, és
* a dir, quan hi ha una variació
en el text
*/
public void
caretUpdate (CaretEvent e) {
Object ob=e.getSource();
if
(ob instanceof JTextArea) {
//
falta dir què cal fer
}
}
}
|
|
|
|
|
|
|
Ara cal decidir què
fer quan hi ha l'emissió de l'esdeveniment CaretEvent:
cal omplir el mètode caretUpdate(). Pots
posar-hi un JLabel i recollir-hi el text com en
el cas de la classe TextSimple: |
|
|
|
|
|
import javax.swing.JFrame;
import java.awt.Container;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import javax.swing.JScrollPane;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.CaretEvent;
import javax.swing.JLabel;
/**
* Escriviu aquí una descripcìó de la
classe TextLlarg
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class TextLlarg extends JFrame
implements ActionListener,
CaretListener
{
/**
* L'objecte JTextArea
*/
JTextArea textArea;
/**
* El Jlabel
*/
JLabel label;
/**
* Mètode constructor per
a objectes de la classe TextLlarg
*/
public TextLlarg () {
setTitle("Exemple
de JTextArea");
Container cnt=getContentPane();
// Ara es construeix
l'objecte JTextArea de 4 files i 30
// columnes:
textArea=new JTextArea(4,30);
// Que talli les
línies!
textArea.setLineWrap(true);
textArea.addCaretListener(this);
JScrollPane jsp=new
JScrollPane(textArea);
cnt.add(jsp,BorderLayout.CENTER);
// Afegim un botó
JButton boto=new
JButton("Exportar el text");
boto.addActionListener(this);
cnt.add(boto,BorderLayout.SOUTH);
label=new
JLabel(" ");
cnt.add(label,BorderLayout.NORTH);
pack();
show();
}
/**
* Mètode que s'executa quan
es prem el botó
*/
public void actionPerformed (ActionEvent
e) {
Object ob=e.getSource();
if
(ob instanceof JButton) {
String
elText=textArea.getText();
System.out.println(elText);
}
}
/**
* Mètode que s'executa quan
textArea emet un CaretEvent, és
* a dir, quan hi ha una variació
en el text
*/
public void caretUpdate (CaretEvent e)
{
Object ob=e.getSource();
if
(ob instanceof JTextArea) {
String
elText=textArea.getText();
label.setText(elText);
}
}
}
|
|
|
|
|
|
|
Compila i crea un objecte
TextLlarg: cada vegada que escrius un caràcter,
el text actual es reflexa al label: |
|
|
|
|
|
|
|
|
|
|
|
I ara... un exercici! |
|
|
|
|
|
 |
Es
tracta que facis una petita aplicació,el funcionament del qual ha
de ser com el que veuràs quan facis
clic aquí. Les regles del joc han de ser: |
|
|
|
|
|
- La finestra de l'aplicació ha de ser, com fins
ara, un objecte JFrame. Els controls han d'estar
distribuïts segons un objecte BorderLayout.
- A la posició nord
hi has de posar un objecte JTextField, a la
posició central
hi haurà un objecte JTextArea i, a
la posició sud,
un objecte JLabel.
- Cada vegada que l'usuari premi la tecla "Retorn",
el text que hi hagi a l'objecte JTextField
s'afegirà al que ja hi hagi a l'objecte JTextArea
i l'objecte JTextField quedarà en blanc,
a l'espera que hom hi torni a escriure més text.
|