utilisation des composants swing - wordpress.com...le browser web ne possède pas forcément la...
Post on 10-Jun-2020
1 Views
Preview:
TRANSCRIPT
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 1
1 DEFINITION DE L'EXEMPLE .................................................................................. 4
2 CONSTRUIRE LES FENETRES: LAYOUTS ET MISES EN PAGE ........................ 5
3 JOPTIONPANE ET BOITES DE DIALOGUES ...................................................... 11
4 IMAGES ET ICONES ............................................................................................. 12
5 QUELQUES ASTUCES D'UTILISATION DES COMPOSANTS SWING............... 14
6 UTILISER UNE JCOMBOBOX OU UNE JLIST .................................................... 17
7 UTILISER UNE JTABLE ........................................................................................ 21
Le travail sur cet exemple suppose connu le fonctionnement des composants java.swing de base
(frames, textFields, boutons)et des listeners usuels (ActionListener, WindowListener,
KeyListener)
Si nécessaire, voir le support "IHM 1ère étape" et "IHM 2ème étape"
Plan détaillé
1 DEFINITION DE L'EXEMPLE .................................................................................. 4
2 CONSTRUIRE LES FENETRES: LAYOUTS ET MISES EN PAGE ........................ 5
2.1 Les principaux layouts ....................................................................................................... 5
2.2 Les "top level containers" ................................................................................................. 6
2.3 La fenêtre principale et ses panneaux .............................................................................. 8
2.4 Le panneau PnlCreation pour la création des contacts .................................................. 9
2.5 La gestion des événements ............................................................................................... 10
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 2
3 JOPTIONPANE ET BOITES DE DIALOGUES ...................................................... 11
3.1 Afficher une boite de message ......................................................................................... 11
4 IMAGES ET ICONES ............................................................................................. 12
5 QUELQUES ASTUCES D'UTILISATION DES COMPOSANTS SWING............... 14
5.1 Précautions d’utilisation .................................................................................................. 14
5.2 Menus ................................................................................................................................ 14
5.3 Définir l'icône de l'application ........................................................................................ 14
5.4 La gestion du focus ........................................................................................................... 15
5.5 définir un bouton comme le bouton par défaut ............................................................. 15
5.6 définir d’un raccourci clavier .......................................................................................... 15
5.7 utilisation de HTML pour définir le label d’un bouton ............................................... 15
5.8 Les info-bulles ................................................................................................................... 16
5.9 Le "look and feel" ............................................................................................................ 16
6 UTILISER UNE JCOMBOBOX OU UNE JLIST .................................................... 17
6.1 ComboBox qui affiche des textes .................................................................................... 17
6.2 ComboBox qui affiche des objets .................................................................................... 18
6.3 ComboBox avec images .................................................................................................... 19
6.4 ComboBox avec DataModel ............................................................................................ 20
7 UTILISER UNE JTABLE ........................................................................................ 21
7.1 Une JTable simple (mais limitée) .................................................................................... 22
7.2 Le TableModel .................................................................................................................. 23
7.2.1 Le pattern MVC .......................................................................................................... 23
7.2.2 Une table générée (avec NetBeans ); le TableModel ................................................. 23
7.3 Personnaliser la JTable .................................................................................................... 24
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 3
7.3.1 Contrôle de l'affichage; TableColumnModel ............................................................. 24
7.3.2 Contrôler la présentation avec Renderer et Editor ......................................................... 25
7.4 Traiter les sélections de l'utilisateur ............................................................................... 26
7.4.1 Sélection simple ou sélection multiple: ListSelectionModel ............................. 26
7.4.2 Traitement des sélections: ListSelectionListener ........................................... 26
7.5 Ajouter modifier ou supprimer des lignes ..................................................................... 27
7.6 Détecter les modification du contenu de la table ........................................................... 27
7.7 Implémenter un TableModel ........................................................................................... 28
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 4
1 Définition de l'exemple
L'application crée et gère une liste de
contacts
un contact comporte
- un nom
- une ville
- un email
on lui ajoutera ensuite
- une date de validation
- une photo
la fenêtre comporte 2 onglets,
le 1er pour créer un contact
le contact créé est ajouté à la liste
le 2ème pour lister, supprimer ou modifier
les contacts
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 5
2 Construire les fenêtres: layouts et mises en page
2.1 Les principaux layouts
Le layout définit la façon dont les composants (champs, boutons, panneaux imbriqués…) seront
placés dans le container (la fenêtre, le panneau conteneur…)
Le but est de créer une mise en page qui restera lisible quelle que soit la taille et la résolution de
l'écran lors de l'exécution.
On va voir les principaux layouts
BorderLayout
les éléments sont placés en centre, nord, sud, est, ouest
avec NetBeans, on définit la
propriété Direction du
composant
GridLayout
les éléments sont placés sur une grille dont toutes les cellules ont la même taille
ici, on veut placer les boutons les uns en dessous des autres sur le panneau Est
on définit le layout du panneau comme
GridLayout
on définie la grille avec 1 colonne et
plusieurs lignes
le vertical gap est l'espace entre les boutons
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 6
FlowLayout
dans le panneau Nord, on fixe le layout à FlowLayout (en
fait, c'est le layout par défaut pour les JPanel)
ici on a placé successivement un label, puis 2 boutons
BoxLayout
un petit peu plus complexe que le GridLayout, il permet d'avoir des cellules de tailles différentes
Layout nul
Si on définit un layout nul, les composants sont placés manuellement par une instruction telle que boutonOK.setBounds(x, y, largeur, hauteur)
ou boutonOK.setLocation(x, y)
Layout par défaut
si on ne définit pas de layout, le layout par défaut est appliqué:
- pour une JFrame: border layout
- pour un JPanel: flow layout
2.2 Les "top level containers"
Le Top level container est la fenêtre qui contiendra les composants et éventuellement les
containers de niveau inférieur.
un top level container peut être une JApplet, une JDialog, une JFrame
un composant est un JTextField, un JButton, etc.
un container de niveau inférieur est par exemple un JPanel ou l’un de ses dérivés
Le JRootPane : les “top-level Swing containers” contiennent un JRootPane, qui lui-même
contient
un ContentPane : le fond de la fenêtre à l’exclusion de la zone de menu
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 7
un MenuBar : la ligne de menu
un GlassPane : permet d’intercepter les événements sur un ensemble de composants,
d’afficher une image en sur-impression sur plusieurs composants…
Voir http://java.sun.com/docs/books/tutorial/uiswing/components/rootpane.html pour plus de
détails.
On fixe le layout et on ajoute les composants dans le JRootPane:
Dans le top level container , pour le layout this.getContentPane().setLayout(null);
et pour les composants: this.getContentPane().add(jButton1, null);
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 8
2.3 La fenêtre principale et ses panneaux
la fenêtre conserve son BorderLayout par défaut
elle contient
- un panneau de contrôle à l'est (pour les boutons)
- un panneau à onglets JTabbedPane au centre, pour
la saisie et l'affichage des données
le panneau est peut avoir un GridLayout, avec une
colonne et plusieurs lignes
il contient des boutons qui seront utilisés
ultérieurement pour connecter l'application à la base
de données
on peut obtenir un espace autour des boutons en définissant une bordure pour le panneau de
contrôle:
choix d'une bordure vide
dimensions de la
bordure
le panneau à onglets contient 2 panneaux vides, qui recevront ensuite le panneau de saisie et le
panneau d'affichage des données
est
centre
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 9
les libellés sur les onglets sont définis par la propriété Tab Title du panneau vide placé dans le
TabbedPanel
On obtient une fenêtre principale composée ainsi
et qui doit ressembler à
2.4 Le panneau PnlCreation pour la création des contacts
On définit le panneau de saisie comme un composant séparé, qui pourra ensuite être placé dans le
panneau à onglet de la fenêtre principale, ou dans tout autre type de fenêtre
création du panneau
on crée un composant JPanel indépendant par un clic droit sur le projet, puis New > JPanel Form
le panneau PnlCreation contient
o son propre panneau de contrôle, pour les
boutons Effacer, Valider, etc.
o et un panneau pour les
champs de saisie
dessin des composants dans le
panneau de saisie
Le panneau de saisie est simple; il
contient 3 textFields et 3 labels; il peut
être défini avec un layout nul
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 10
dessin des composants dans le panneau de contrôle
il est organisé exactement comme le panneau de contrôle de la fenêtre principale
instanciation du panneau dans la fenêtre principale
dans le constructeur de la frame, après l'appel à initComponents(): public class FrameContacts extends javax.swing.JFrame {
public FrameContacts() {
initComponents();
PnlCreation pnlCreation = new PnlCreation();
jPanel1.add(pnlCreation);
}
2.5 La gestion des événements
La gestion des principaux événements a été détaillée dans le support "IHM 2ème étape"
Il faut au minimum
que le bouton Valider crée une instance de la classe Contact à partir du contenu des champs
de saisie
pour l'instant on se contente d'afficher l'instance créée avec un System.out.println()
ensuite on va ajouter le contact dans le panneau de liste des contatcs
que le bouton Effacer vide les champs
on peut aussi remettre le focus sur le 1er champ avec champNom.requesFocus()
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 11
3 JOptionPane et boites de dialogues
3.1 Afficher une boite de message
On peut créer et afficher avec une seule instruction une boite de
message: MessageDialog: JOptionPane.showMessageDialog(
null, // fenêtre parent
"icone d'application non trouvée");
Il y a aussi une boite de message ConfirmDialog: int choix = JOptionPane.showConfirmDialog
(this, "voulez-vous continuer?");
if (choix == JOptionPane.YES_OPTION) traiter…
Enfin la InputDialog permet de saisir une donnée. String txt = JOptionPane.showInputDialog(this, "nom d'hôte?");
On peut aussi instancier la boite de message pour la personnaliser JOptionPane pane = new JOptionPane("continuer?",
JOptionPane.WARNING_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
Si la JOptionPane a été instanciée, on l'affiche dans une boite de dialogue: JDialog dialog = pane.createDialog(this, "continuer l'opération");
dialog.show();
Object selectedValue = pane.getValue();
if(selectedValue == null)return JOptionPane.CLOSED_OPTION;
return ((Integer)selectedValue).intValue();
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 12
4 Images et Icones
Un composant Swing (un bouton, un label, etc.) peut afficher une icône aussi bien qu’un texte
l’icône est un fichier gif ou jpeg
le chargement est automatiquement contrôlé par le composant (par un MediaTracker –voir le
chapitre sur les images)
ImageIcon icone = new ImageIcon("images/img.gif");
...
label1 = new JLabel("un texte", icone, JLabel.CENTER);
le constructeur prend en paramètre un nom de fichier, ou une URL, une image, un tableau
d’octets.
Emplacement du fichier d’image
on peut donner un chemin absolu ; cela n'est généralement pas pratique
un chemin relatif s’applique par rapport au répertoire de lancement de la machine virtuelle ;
c’est suffisant la plupart du temps
pour être sûr d’accéder à un chemin relatif par rapport au répertoire de l’application, utiliser URL url = this.getClass()getRessource(“images/img.gif”);
ou InputStream is = this.getClass().getResourceAsStream(“images/img.gif”);
is.read(tableauDeBytes);
// par ex., pour fixer l’icone de la fenêtre réduite
this.setIconImage(new ImageIcon(tableauDeBytes).getImage());
pour une applet on utilisera Applet ::getCodeBase( ) ou getDocumentBase( )
(voir le chapitre concernant les applets et leur environnement
pour plus d’information sur les icones:
http://java.sun.com/docs/books/tutorial/uiswing/misc/icon.html
pour récupérer une bibliothèque d'icones http://java.sun.com/developer/techDocs/hi/repository/
Un label composé d’une
image et d’un texte, ou
d’un texte seul, ou d’une
image seule
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 13
un extrait de la bibliothèque
fond transparent :
un fond transparent permet par exemple de voir l’image collée sur le panneau de fond, à travers
un autre composant setOpaque(false)
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 14
5 Quelques astuces d'utilisation des composants Swing
5.1 Précautions d’utilisation
Mélange de composants awt et Swing
Le mélange de composants awt et Swing peut poser des problèmes d’affichage quand un
Swing est posé sur un awt
=> faire une IHM homogène, tout awt ou tout Swing
Utilisation des Swing dans une applet
Le browser web ne possède pas forcément la bibliothèque javax.swing
en intranet ou extranet on peut configurer les browsers
en y ajoutant le package javax.swing
ou en installant java plug in
ou accepter un temps de chargement initial un peu long
en internet il vaut sans doute mieux utiliser awt, sauf cas particulier
5.2 Menus
Les items de menus ont les mêmes extensions de fonctionnalités que les boutons
En plus des items de menus standard, on peut utiliser
JCheckBoxMenuItem : un item de menu avec une case à cocher
JRadioButtonMenuItem : un item de menu avec un radioButton
Les modifications sur ces items peuvent être suivis grâce à un ItemListener
5.3 Définir l'icône de l'application
Pour personnaliser l'icône de votre application:
try {
byte[] icone;
// récupère une image placée dans le répertoire du .class
java.io.InputStream inputstreamIcon =
this.getClass().getResourceAsStream("appIcone.gif");
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 15
int iIconSize = inputstreamIcon.available();
// dimensionne le tablea d'octets à la taille de l'icone
icone = new byte[iIconSize];
inputstreamIcon.read(icone);
this.setIconImage(new ImageIcon(icone).getImage());
} catch(Exception ex) {
// l'icone par défaut sera utilisée
}
5.4 La gestion du focus
Simplifiée grâce à la méthode unChamp.setNextFocusableComponent( autreChamp )
5.5 définir un bouton comme le bouton par défaut
getRootPane().setDefaultButton(unBouton);
le bouton apparait comme sélectionné
lorsque le panneau qui contient le bouton a le focus, la frappe sur <Entrée> équivaut au
clic sur le bouton
5.6 définir d’un raccourci clavier
leBouton.setMnemonic(KeyEvent.VK_B);
définit alt-B comme le raccourci clavier
5.7 utilisation de HTML pour définir le label d’un bouton
permet de définir la police d’affichage
permet des labels multi-lignes
etc.
exemple:
b1 = new JButton("<html>
<font size=-1><b><u>D</u>isable</b>"+ " middle button</font>",
leftButtonIcon);
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 16
5.8 Les info-bulles
La définition d’une info-bulle se fait par une simple instruction ; par
exemple pour un bouton :
bouton.setToolTipText("mnemonic=D" ) ;
5.9 Le "look and feel"
Les swing utilisent un standard d'affichage dit "metal".
On peut modifier le look and feel (PLAF: plugable look and feel) et utiliser le look and feel du
poste de travail sur lequel l'application est exécutée, avec l'instruction
public static void main(String[] args) {
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) { ...
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 17
6 Utiliser une JComboBox ou une JList
On prendra ici des exemples de ComboBox; la combo permet soit de choisir dans une liste, soit
de saisir une nouvelle valeur absente de la liste.
La JList et la JComboBox ont des fonctionnements proches
la JCombo permet de choisir ou de saisir, mais ne permet pas la sélection multiple
la JList permet de choisir, mais pas de saisir; elle permet la sélection multiple
6.1 ComboBox qui affiche des textes
Voir l’exemple « combosimple / ComboDeString.java »
Cette première comboBox affiche des chaînes de caractères
La comboBox peut être éditable ou non :
jComboEditeurs.setEditable(true);
permet de saisir au lieu de choisir dans la liste
vaut false par défaut
Traitement des ActionEvents (ActionListener):
l’ActionListener interceptera aussi bien la frappe d’une nouvelle valeur dans la zone de texte (si
la combo est éditable) que le choix dans la liste existante jComboEditeurs.getSelectedItem()
permet de récupérer soit l'item choisi soit le texte frappé
l’ItemListener interceptera la sélection ou la désélection d’un élément de la liste
la constante ItemEvent.SELECTED permettra de distinguer les deux cas
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 18
6.2 ComboBox qui affiche des objets
Voir l’exemple « comboObjets / ComboDeChoses.java »
Objectif:
au lieu de stocker dans la liste de la combo des chaînes de
caractères qui désignent les objets, on peut stocker les
références aux objets eux-mêmes
avantages:
lorsque le programme gère une collection d’objets, on peut les afficher directement, au
lieu d’afficher des nmes et de gérer une correspondance nom objet
le lien entre le choix fait par l’utilisateur dans la liste et l’objet sélectionné se fera
directement
ceci permettra dans l'étape suivante d'afficher des icônes représentant les objets
L’exemple définit une classe Chose, qui possède un nom et un numéro
lorsqu’on saisit un nom dans le textField, une instance de Chose est ajoutée à
la liste:
void jButton1_actionPerformed(ActionEvent e) {
jCombo.addItem(new Chose(jtfTitre.getText()));
// pour rendre visible l'item ajouté:
jCombo.setSelectedIndex(jCombo.getItemCount()-1);
affichage dans la combo :
l’affichage utilise la méthode toString( ) définie pour la classe
redéfinir toString( ) dans la classe Chose pour avoir un affichage personnalisé public String toString(){ return numéro +"-" + nom; }
lien entre le choix fait par l’utilisateur dans la liste et l’objet sélectionné :
on peut récupérer facilement la référence à l'objet affiché, à partir de l'ActionListener de la
combo
void jCombo_actionPerformed(ActionEvent e) {
Chose laChose = null;
// attention aux EventAction qui ne retournent pas l'instance de Chose
if (jCombo.getSelectedItem() instanceof Chose) {
laChose = (Chose)jCombo.getSelectedItem();
Chose
_____________
numéro
nom
_____________
Chose(String
_nom)
toString() :
String
getNom() :
String
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 19
6.3 ComboBox avec images
Voir l’exemple « comboImages / ComboImages.java »
Objectif
afficher les objets dans la combo avec leur icône
l'exemple utilise la collection d'icônes fournies avec les
composants Swing sur le site java.sun.com
1. la classe Chose est définie avec un nom, un numéro et une image
(une javax.swing.ImageIcon, précisément)
2. l’affichage par défaut de l’objet utiliserait la méthode toString( ); on modifie l’affichage en
définissant un Renderer
le BasicComboBoxRenderer est une sous-classe de JLabel
il peut afficher une image en plus ou à la place du résultat de toString( )
il comporte une méthode getListCellRendererComponent, qui définit le mode
d'affichage de l'objet contenu dans la combo:
2.1. exemple de définition d'un renderer
class ChoseRenderer extends BasicComboBoxRenderer {
// il y a une seule méthode à définir
public Component getListCellRendererComponent(
JList list,
Object value, int index,
boolean isSelected, boolean cellHasFocus) {
// on récupère la référence à l'objet affiché par la combo
Chose c = (Chose)value;
// on définit le mode d'affichage
this.setIcon(c.icone);
this.setText(c.nom);
this.setBackground(isSelected? Color.white: Color.lightGray);
this.setAlignmentX(Component.CENTER_ALIGNMENT);
return this;
}
}
2.2. attachement du renderer à la combo:
jComboEditeurs.setRenderer(new ChoseRenderer());
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 20
6.4 ComboBox avec DataModel
voir l'exemple ComboEtModele.java
Les composants Swing qui affichent des listes de données (JList, JComboBox, JTable, JTree,
etc.) permettent de séparer l’affichage (la « vue ») de la liste en mémoire (le « modèle »).
C’est une application de l’architecture Modèle-Vue-Contrôleur.
objectif
la liste d'objets affichés par le composant Swing devient indépendante du composant lui-même;
on peut par exemple
- remplacer une liste par une autre en remplaçant le data modèle
- utiliser les propriétés de la liste pour contrôler le contenu
méthode
1. créer le data modèle et l'attacher à la combo:
on définit un Vector qui stocke les instances de Chose : Vector liste1 = new Vector();
DefaultComboBoxModel modèle1;
liste1.add(new Chose(userDir, "Open.gif"));
...
jComboEditeurs = new JComboBox(modèle1);
DefaultComboBoxModel est l'implémentation par défaut fournie pour les combo boxes;
elle peut utiliser un Vector ou un tableau d'objets.
2. remplacer une liste par une autre en remplaçant le data modèle
on substitue une liste d'éléments à une autre par l'instruction setModel() jComboEditeurs.setModel(modèle1);
3.utiliser les propriétés de la liste pour contrôler le contenu de la combo
dans l'exemple, on veut ajouter au modèle la chose sélectionnée par l'utilisateur, si elle n est pas
déjà présente dans le data modèle // construire la chose, à partir de la sélection faite par l'utilisateur
Chose nouveau = new Chose("uneImage.gif");
// si la chose n'est pas déjà présente dans le modèle, l'ajouter
DefaultComboBoxModel modèle = (DefaultComboBoxModel)jCombo.getModel();
int index = modèle.getIndexOf(nouveau);
// indexOf() utilise Chose::equals()
if (modèle.getIndexOf(nouveau) < 0) {
jComboEditeurs.addItem(nouveau);
}
la méthode indexOf(), qui permet de savoir si l'objet est déjà présent dans le data modèle, utilise
l'implémentation de la méthode equals() fournie pour la classe Chose..
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 21
7 Utiliser une JTable
La réalisation du second panneau de l'exercice utilise une JTable basée sur un TableModel
On crée un JPanel spécifique, PnlListe,
comme on l'a fait pour le panneau de saisie
le panneau contient deux sous-panneaux, un
JPanel pour les boutons, un JScrollPane pour les données
La JTable est placée dans le JScrollPane qui fournit ascenseur et translateur, et assure
l'affichage des titres de colonnes
on obtient quelque chose comme
Les pages suivantes donnent les indications pour réaliser la JTable
le panneau PnlListe,
placé dans le
JTabbedPane
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 22
7.1 Une JTable simple (mais limitée)
La création d'une JTable peut être très simple:
public class DemoJTable1 extends javax.swing.JPanel {
JTable table;
public DemoJTable1() {
setLayout(new java.awt.BorderLayout());
- on définit un tableau de String (ou un Vector) pour les titres des colonnes Vector titres = new Vector();
titres.add("numéro");
titres.add("nom");
- et un tableau à 2 dimensions ou un Vector de vectors pour les données Vector data = new Vector()
for(int i=0;i<4;i++) {
Vector ligne = new Vector();
ligne.add(new Integer(i+100));
ligne.add(new String("nom-" + i));
ligne.add(new Boolean(true));
ligne.add(null);
data.add(ligne);
}
- la JTable est créée à partir de la liste des données et de celle des titres table = new javax.swing.JTable(data, titres);
- enfin elle set placée dans un JScrollPane, qui gère les ascenseurs et affiche les titres des
colonnes JScrollPane scrollPane = new JScrollPane(table);
add(scrollPane);
Titres des colonnes
Si la JTable n'est pas placée dans un JScrollPane, il faut afficher explicitement les titres avec container.setLayout(new BorderLayout());
container.add(table.getTableHeader(), BorderLayout.PAGE_START);
container.add(table, BorderLayout.CENTER);
Limites de la méthode: avec une JTable créée par table = new javax.swing.JTable(data, titres);
- toutes les données sont affichées comme des chaînes de caractères
- toutes les données sont éditables
- toutes les données doivent être placées dans le Vector ou le tableau de données
Pour éviter ces limitations, on définit un TableModel qui contient les données en mémoire, et la
JTable est basée sur le TableModel
le code de l'exemple
est dans
DemoJTable1.java
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 23
7.2 Le TableModel
7.2.1 Le pattern MVC
On dit que les composants Swing s'appuient sur le Design Pattern (le patron –ou modèle- de
conception) MVC (Modèle-Vue-Contrôleur) parce qu'il sépare d'un côté la vue affichée (le
tableau) et de l'autre les données à afficher (le modèle).
On exécutera la plupart des opérations utiles sur le modèle, et non sur la vue.
7.2.2 Une table générée (avec NetBeans ); le TableModel
Si on génère la JTable dans l'éditeur graphique (ici avec NetBeans 4.1), Netbeans génère
automatiquement un TableModel
On peut éditer le modèle à partir de la
propriété Model de la JTable
NetBeans génère le TableModel sous
forme de classe incluse:
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{new Integer(200), "Munich", new Boolean(true), null},
{new Integer(110), "Barcelone", null, null},
…
},
new String [] {
"numéro", "nom", "validé", "photo"
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 24
}
) {
Class[] types = new Class [] {
java.lang.Integer.class, java.lang.String.class,
java.lang.Boolean.class, java.lang.Object.class
};
boolean[] canEdit = new boolean [] {
false, true, true, false
};
Noter
les colonnes sont typées (Integer, Boolean)
la JTable utilise des éditeurs par défaut pour les types les plus usuels: Integer, Boolean,
etc.
la JTable signale les données invalides (texte dans une colonne numérique)
la saisie d'une donnée invalide est signalée
et empêche de passer à une autre cellule
Pour l'instant le résultat est proche du précédent, mais on va
pouvoir
- personnaliser l'affichage
- et mettre à jour les données
Noter: on peut aussi créer le modèle sans données et même sans titres de colonnes: modele = new javax.swing.table.DefaultTableModel(
titresColonnes, nombreDeLignes);
modele = new javax.swing.table.DefaultTableModel(
nombreDeLignes, nombreDeColonnes);
7.3 Personnaliser la JTable
7.3.1 Contrôle de l'affichage; TableColumnModel
on récupère le TableColumnModel de la table:
javax.swing.table.TableColumnModel colonnes = table.getColumnModel();
contrôle de la largeur des colonnes
le ColumnModel permet de définir la largeur des colonnes
// définition des largeurs de colonnes
// colonnes.getColumn(0).setMaxWidth(80);
colonnes.getColumn(0).setPreferredWidth(80);
si l'utilisateur redimensionne la table, les proportions des colonnes sont
le code de l'exemple
est dans DemoJTable3
exemple
TableModeleGenere.java
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 25
respectées
setAutoResizeMode() avec les constantes JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS,
AUTO_RESIZE_NEXT_COLUMN, AUTO_RESIZE_OFF déterminent l'impact du redimensionnement
d'une colonne sur les autres colonnes
le ColumnModel permet aussi d'ajouter, supprimer, déplacer dynamiquement des colonnes: addColumn(), moveColumn(),removeColumn()
7.3.2 Contrôler la présentation avec Renderer et Editor
Jusqu'ici, on a utilisé l'affichage par défaut des String, nombres, booléens.
On peut aussi implémenter un Renderer spécifique et l'attacher à une colonne
Exemple: pour afficher une date formatée on pourra utiliser colonneDate.setCellRenderer(new DefaultTableCellRenderer() {
DateFormat formatter;
public void setValue(Object value) {
if (formatter==null) {
formatter = DateFormat.getDateInstance();
}
setText((value == null) ? "" : formatter.format(value));
}
});
(le tutorial de Sun utilise dans ce cas une classe statique, pour éviter les appels répétés à DateFormat.getDateInstance()
voir http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#renderer )
Implémenter un Editor pour modifier une cellule
Exemple: une Combo Box
ici, on utilise une comboBox comme éditeur pour la
colonne "catégorie" public class DemoJTable3 extends
javax.swing.JPanel {
// définition d'un renderer spécifique
javax.swing.table.TableColumn categ
= table.getColumnModel().getColumn(2);
javax.swing.JComboBox comboBox =
new javax.swing.JComboBox();
comboBox.addItem("luxe");
comboBox.addItem("standard");
comboBox.addItem("spécial");
categ.setCellEditor(new javax.swing.DefaultCellEditor(comboBox));
voir DemoJTable3
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 26
7.4 Traiter les sélections de l'utilisateur
7.4.1 Sélection simple ou sélection multiple: ListSelectionModel
Par défaut l'utilisateur peut sélectionner une ligne, ou plusieurs lignes contiguës
On peut modifier le mode de sélection avec tableau.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION); // une seule ligne
ou ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); // sélection libre
7.4.2 Traitement des sélections: ListSelectionListener
On peut ajouter un ListSelectionListener, pour intervenir quand l'utilisateur sélectionne une
ligne (voir détail en annexe)
Le ListSelectionListener reçoit un ListSelectionEvent avec les méthodes int getFirstIndex()
int getLastIndex()
boolean getValueIsAdjusting()
si l'événement fait partie d'une séquence de changements
une fois connue la ligne sélectionnée, on utilisera les méthodes sur le TableModel
getValueAt(row, col), insertRow(rang, Object[]), removeRow(rang), etc.
Exemple tiré du tutorial de Sun
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
// dans le constructeur
initComponents();
modele = (DefaultTableModel)tableau.getModel();
…
// listeener de sélection
ListSelectionModel ligneSelModel = tableau.getSelectionModel();
ligneSelModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
//si l'événement fait partie d'une séquence de changements
if (e.getValueIsAdjusting()) return;
ListSelectionModel lsm =
(ListSelectionModel)e.getSource();
if (lsm.isSelectionEmpty()) {
//no rows are selected
interface ListSelectionListener {
void valueChanged(ListSelectionEvent e);
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 27
} else {
int selectedRow = lsm.getMinSelectionIndex();
affiche("sélection " +
tableau.getModel().getValueAt(selectedRow, 1));
}
}
});
7.5 Ajouter modifier ou supprimer des lignes
Les modifications du contenu du tableau, et la plupart des autres opérations vont se faire sur le
modèle du tableau, pas sur le tableau lui-même;
On va donc récupérer la référence au modèle, avec
public class FrameListe extends javax.swing.JFrame {
DefaultTableModel modele;
public FrameListe() {
initComponents();
modele = (DefaultTableModel)jTable1.getModel();
}
L'ajout ou la suppression d'une ligne sont très simples à partir de là:
on supprimera une ligne sélectionnée avec modele.removeRow(tableau.getSelectedRow());
il est seulement prudent de se protéger du cas où l'utilisateur n'aura pas sélectionné la ligne à
supprimer: if (tableau.getSelectedRow() == -1) // message…
on ajoutera une ligne vide en fin de tableau, ou juste avant la ligne sélectionnée avec modele.addRow(new Vector());
ou modele.insertRow(tableau.getSelectedRow(), new Vector());
7.6 Détecter les modifications du contenu de la table
Pour traiter les modifications faites par l'utilisateur (par exemple les vérifier, ou les enregistrer
dans la base de données, etc.) on utilisera un Listener de modification du contenu:
qui intercepte un TableModelEvent avec les méthodes
interface TableModelListener {
void tableChanged(TableModelEvent e);
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 28
int getColumn()
int getFirstRow()
int getLastRow()
int getType()
par exemple tableau.getModel().addTableModelListener(
new TableModelListener() {
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
affiche("nouvelle valeur " + model.getValueAt(row, column));
}
}
);
7.7 Implémenter un TableModel
Enfin, si le DefaultTableModel ne suffit pas, on peut définir son propre modèle.
Au lieu d'étendre javax.swing.table.DefaultTableModel
(c'est le moyen utilisé plus haut, dans le § "Un tableau généré avec NetBeans")
on peut
étendre javax.swing.table.AbstarctTableModel
en implémentant getRowCount(),getColumnCount() et getValueAt()
ou implémenter l'interface TableModel
Surcharger AbstractTableModel permet
- d'utiliser un type quelconque de collection
- de définir quelles colonnes (ou même quelles cellules particulières) sont éditables
- etc.
exemple d'implémentation public class ModeleTable extends javax.swing.table.AbstractTableModel {
String[] nomsColonnes = {"numéro", "nom", "dispo."};
java.util.ArrayList<java.util.ArrayList> data = new
java.util.ArrayList<java.util.ArrayList>();
public ModeleTable() {
// les données
int nbLignes = 3;
for(int i=0;i<nbLignes;i++) {
java.util.ArrayList ligne = new java.util.ArrayList();
ligne.add(new Integer(i+100));
ligne.add(new String("xxx-" + i));
ligne.add(new Boolean(true));
data.add(ligne);
}
}
le code de l'exemple est dans
DemoJTable3/ModeleTable.java
Utilisation des composants Swing
H.ZINSOU Utilisation des Swing v4.doc ___________________________________________________________________________
Page SWING 29
public String getColumnName(int col) {
return nomsColonnes[col].toString();
}
public int getRowCount() { return data.size(); }
public int getColumnCount() { return nomsColonnes.length; }
public Object getValueAt(int ligne, int col) {
java.util.ArrayList dataLigne = data.get(ligne);
return dataLigne.get(col);
}
public boolean isCellEditable(int ligne, int col) {
if (col == 0) return false;
return true;
}
public void setValueAt(Object obj, int ligne, int col) {
data.get(ligne).set(col, obj);
// data[ligne][col] = obj;
fireTableCellUpdated(ligne, col);
}
}
______________________________________
top related