page de garde les librairies awt et swing essi2, septembre 2002 [email protected]
TRANSCRIPT
Page de garde
Les librairies AWT et Swing
ESSI2, Septembre 2002
http://www.yannis.bres.name
Introduction
Les GUI en Java
Le JDK comporte de nombreuses classes permettant la construction de Graphical User Interfaces (interfaces homme/machine) très évoluées
De nombreux composants simples (étiquettes, boutons, cases à cocher, zones de texte, …) ou très évolués (arbres, tables, éditeur de texte formatté, …) sont disponibles
Introduction \ Deux packages
Deux packages
java.awt
Abstract Window Toolkit
Utilise les composant graphiques natifs (peers)
Comportements différents selon les plate-formes
Exécution assez rapide
javax.swing
100% pure Java
Librairie complètement écrite en Java
Construite au-dessus d’un sous-ensemble fiable (portable) de l’AWT
Librairie très puissante, composants très évolués (arbres, tables, …)
Séparation modèle-représentation, apparence modifiable (pluggable look-and-feels)
Exécution assez lente
Principes de base
Principes de base
Un composant graphique dérive de :
java.awt.Component ou javax.swing.JComponent
Les composant graphiques sont contenus par des java.awt.Container
Les composants s’ajoutent par :
Container.add( Component ) (placement non contraint)
Container.add( Component, Object ) (placement contraint)
Le placement des composants est géré par des java.awt.LayoutManager
Les containers ont chacun un Layout Manager par défaut
Le Layout Manager se modifie par setLayout( LayoutManager )
Théoriquement : pas de placement absolu
Les containers sont des composants !
Possibilité d'emboîter récursivement des containers
"Structures" à connaître
"Structures" à connaître
java.awt.Point, utilisée notamment pour les positions :
class java.awt.Point { public int x; public int y; …}
java.awt.Dimension :
class java.awt.Dimension { public int width; public int height; …}
"Structures" à connaître
"Structures" à connaître
java.awt.Rectangle, utilisée notamment pour les bounding boxes :
class java.awt.Rectangle { public int x; public int y; public int width; public int height; …}
java.awt.Insets indique les espaces que les composants doivent laisser sur les côtés :
class java.awt.Insets { public int top; public int left; public int bottom; public int right; …}
Première fenêtre
Première fenêtre
Première fenêtre
Première fenêtre
javax.swing.JFrame est la fenêtre de base Swing
Le container principal de javax.swing.JFrame s'obtient par :
getContentPane()
javax.swing.JLabel est une étiquette affichant du texte et/ou une icône
Une fois les composants ajoutés, pack() réalise la fenêtre
La fenêtre est rendue visible par setVisible( true )
Enfin, la fenêtre est détruite par dispose()
Première fenêtre \ 1ère méthode
Première fenêtre
1ère méthode (instanciation directe) :
JFrame frame= new JFrame( "Première fenêtre" );Container content_pane= frame.getContentPane();
Content_pane.add( new JLabel( "Hello World !", SwingConstants.CENTER ) );frame.pack();frame.setVisible( true ); ···frame.dispose();
Première fenêtre \ 2ème méthode
Première fenêtre
2ème méthode (spécialisation) :
public class Fenetre extends javax.swing.JFrame{ public Fenetre( String title ) { super( title ); Container content_pane= getContentPane(); content_pane.add( new JLabel( "Hello World !", SwingConstants.CENTER ) ); pack(); setVisible( true ); }}
new Fenetre( "Première fenêtre" );
Créer son composant
Créer son composant
Créer un objet dérivant de java.awt.Component ou javax.swing.JComponent
L'objet indique sa dimension préférée par la méthode :
java.awt.Dimension getPreferredSize()
L'objet se dessine dans les méthodes :
void paint( java.awt.Graphics g ) (Component)
void paintComponent( java.awt.Graphics g ) (JComponent)
g, le contexte graphique reçu, permet le dessin, l'affichage de texte, …
Pour les JComponents, il faut généralement commencer par appeler la méthode paintComponent(…) de la classe mère :
super.paintComponent( g )
Créer son composant
Exemple
Créer son composant
Exemple
public class DiagonalComponent extends javax.swing.JComponent{ public DiagonalComponent() { }
public Dimension getPreferredSize() { return new Dimension( 300, 240 ); }
public void paintComponent( Graphics g ) { g.drawLine( 0, 0, getWidth(), getHeight() ); g.drawLine( getWidth(), 0, 0, getHeight() ); }}
java.awt.Graphics
java.awt.Graphics, le contexte graphique
Le contexte graphique, java.awt.Graphics, permet :
De dessiner des figures simples et complexes vides :
drawLine(…), drawRect(…), drawOval(…), drawPolygon(…)
De dessiner des figures simples et complexes pleines :
fillRect(…), fillOval(…), fillPolygon(…)
D'afficher du texte :
drawString(…)
De changer la couleur, la fonte, le mode :
setColor(…), setFont(…), setPaintMode()/setXORMode(…)
D'afficher des images
…
L'affichage de texte en Java
L'affichage de texte en Java
Graphics.drawString(…) utilise la fonte préalablement définie par :
setFont( java.awt.Font )
Les fontes sont généralement créées par le constructeur :
Font( String name, int style, int size )
name : nom logique ("Monospaced", "SansSerif", …) ou nom de fonte
style : PLAIN, BOLD, ITALIC ou BOLD|ITALIC
size : taille en points
Les métriques de fontes s'obtiennent notamment par :
getFontMetrics() dans java.awt.Graphics
Les métriques de chaînes de caractères s'obtiennent notamment par :
getLineMetrics(…) dans java.awt.Font
L'affichage de texte en Java \ Métriques de fontes
Métriques de fontes
Une fonte est caractérisée par sa métrique :
java.awt.FontMetrics et java.awt.font.LineMetrics
Une métrique indique notamment les informations suivantes :
Containers et Layout Managers \ Les principaux containers
Les principaux containers
Les plus simples : java.awt.Panel, javax.swing.JComponent
javax.swing.Box
java.awt.ScrollPane et javax.swing.JScrollPane
javax.swing.JSplitPane
javax.swing.JTabbedPane
javax.swing.JDesktopPane et javax.swing.JInternalFrame
· · ·
Containers et Layout Managers \ Les Layout Managers
Les Layout Managers
Responsables :
Du placement relatif des composants dans un container
Du calcul des dimensions minimales et préférées des containers
…
Deux interfaces :
java.awt.LayoutManager (placements simples)
java.awt.LayoutManager2 (placements contraints)
Containers et Layout Managers \ java.awt.FlowLayout
java.awt.FlowLayout
Positionnement à la suite, "passage à la ligne automatique"
Alignements : centré, à gauche, à droite
Les composants ont des tailles quelconques
Surtout utilisé pour les boutons
Containers et Layout Managers \ java.awt.GridLayout
java.awt.GridLayout
Disposition matricielle
GridLayout( int rows, int columns )
add( new JLabel( "Label n°1", SwingConstants.CENTER ) );add( new JLabel( "Label n°2", SwingConstants.CENTER ) );· · ·
Les composants ont tous la même largeur et la même hauteur
Containers et Layout Managers \ java.awt.BorderLayout
java.awt.BorderLayout
Positionnement sur les quatre côtés d’un container ou au centre :
add( new JLabel( "NORTH", SwingConstants.CENTER ), BorderLayout.NORTH );· · ·
Containers et Layout Managers \ java.awt.GridBagLayout
java.awt.GridBagLayout
Le plus puissant de tous !
Mais aussi le plus complexe…
Le plan est découpée en lignes et colonnes
Chaque composant occupe une ou plusieurs cellules (en largeur comme en hauteur)
Suite aux retaillements :
La taille des cellules évolue proportionnellement à la demande
Les composants peuvent s'étendre dans les deux directions, une seule ou pas du tout
Les composants se positionnent dans leurs cellules à l'un des 8 points cardinaux ou au centre
Les contraintes de placements sont transmises par la "structure" :
java.awt.GridBagConstraints
Containers et Layout Managers \ java.awt.GridBagLayout
java.awt.GridBagLayout
Exemple :
Trois panneaux (listes déroulantes, cases à cocher, boutons) gérés respectivement par deux GridBagLayout et un FlowLayoutCes trois panneaux sont gérés par un troisième GridBagLayout
Containers et Layout Managers \ java.awt.GridBagLayout
java.awt.GridBagLayout
La "structure" java.awt.GridBagConstraints :
int gridx, int gridy
Coordonnées de la première cellule occupée par le composant
RELATIVE (défaut) pour une incrémentation automatique
int gridwidth, int gridheight
Nombre de cellules occupées par le composant
REMAINDER indique que le composant utilise le reste de la ligne/colonne
int fill (NONE, HORIZONTAL, VERTICAL, BOTH)
Détermine si le composant s'étend si la dimension de ses cellules augmente
int anchor (CENTER (défaut), NORTH, NORTHEAST, …)
Emplacement du composant dans ses cellules s'il ne s'étend pas complètement
double weightx, double weighty
Facteurs de distribution de l'espace entre colonnes/lignes
Les boîtes de dialogue
Les boîtes de dialogue
javax.swing.JDialog
Très similaires aux fenêtres standard javax.swing.JFrames :
Peuvent être modales (i.e. conserver le focus)
Sont généralement attachées à une autre JDialog ou JFrame
Les boîtes de dialogue communes
Les boîtes de dialogue communes
javax.swing.JOptionPane :
Affichage de messages
Questions simples (Oui/Non, Ok/Annuler, …)
Saisie de valeur unique
Les boîtes de dialogue communes
Les boîtes de dialogue communes
javax.swing.JFileChooser :
Sélection de fichier(s) (ouvrir, enregistrer sous, …)
Les boîtes de dialogue communes
Les boîtes de dialogue communes
javax.swing.JColorChooser :
Les bordures
Les bordures
Les JComponents peuvent se voir attribuer une bordure par :
setBorder( border )
Les bordures peuvent être composées
Les bordures
Les bordures
Les bordures sont des objets implémentants l'interface :
javax.swing.border.Border
Dans le package :
javax.swing.border
Dans le but de partager les bordures identiques, on ne construit pas les bordures à partir des constructeurs des classes, mais via la Factory :
javax.swing.BorderFactory :
static Border createLoweredBevelBorder()
static Border createEtchedBorder()
…
Les bordures affectent les Insets des composants qui en ont :
Pensez-y dans vos méthodes paintComponent( Graphics ) !
Composants \ Etiquettes
Les étiquettes
javax.swing.JLabel
Affiche une icône, du texte, ou les deux
Peut-être grisée
Peut-être associé à un composant et un mnémonique
Alignement vertical et horizontal (gauche/haut, centré, droite/bas)
…
Composants \ Boutons de commandes
Les boutons de commandes
javax.swing.JButton
Affiche une icône, du texte, ou les deux
Composants \ Cases à cocher
Les cases à cocher
javax.swing.JCheckBox
Composants \ Boutons radio
Les boutons radios
javax.swing.JRadioButton
Composants \ Boutons radio \ Exclusions entre boutons
Exclusions entre boutons
javax.swing.JButtonGroup
Permet la gestion d'exclusion mutuelles entre boutons
Généralement : JRadioButton, JRadioButtonMenuItem
Composants \ Boutons bascules
Les boutons bascules
javax.swing.JToggleButton
Composants \ Champs de texte
Les champs de texte
javax.swing.JTextField
Composants \ Zones de texte
Les zones de texte
javax.swing.JTextArea
Composants \ Listes
Les listes
javax.swing.JList
Composants \ Combos
Les combos
javax.swing.JComboBox
Composants \ Barres de progression
Les barres de progression
javax.swing.JProgressBar
Composants \ Glissières
Les glissières
javax.swing.JSlider
Composants \ Menus déroulants
Les menus déroulants
javax.swing.JMenu
Composants \ Menus flottants
Les menus flottants
javax.swing.JPopupMenu
Composants \ Barres d'outils
Les barres d'outils
javax.swing.JToolBar
Composants \ Info-bulles
Les info-bulles
javax.swing.JToolTip
Composants \ Arbres
Les arbres
javax.swing.JTree
Composants \ Tables
Les tables
javax.swing.JTable
Composants \ Editeurs de texte
Les éditeurs de texte
javax.swing.JTextComponent
Multiple Document Interface
Multiple Document Interface
Le JDesktopPane est un conteneur spécialisé pour des classes dérivées de JInternalFrame
Séparation données/composant
Séparation données/composant
Le composant agit comme interface entre l’utilisateur et les données : celles-ci sont gérées par des modèles
Le composant :
Interroge le modèle pour déterminer son état
Interroge le modèle pour afficher les données
Transmet au modèle les modifications à apporter aux données
Les modèles sont des interfaces ; des implémentations courantes sont fournies
Ex.: une JTable fait appel aux méthode suivante de TableModel :
public int getColumnCount()
public int getRowCount()
public Object getValueAt( int row, int col)
Communication entre composants
Communication entre composants
La classe AFrame, dérivant de JFrame, utilise un JButton :
AFrame connait JButton
AFrame communique avec le JButton en lui appliquant ses méthodes
JButton ne connaît (théoriquement) pas AFrame
Comment JButton communique avec AFrame ?
AFrame va se mettre à l’écoute du JButton
Communication entre composants \ Les Listeners
Les Listeners
De nombreux composants comportent des méthodes :
addXXXListener( XXXListener )
removeXXXListener( XXXListener )
XXXListener étant une interface déclarant un petit nombre de méthodes
Ces méthodes sont appelées lorsque l’objet a quelque chose à signaler à ses Listeners
Exemple :
public interface ActionListener extends java.util.EventListener{ public void actionPerformed( ActionEvent event );}
event permet de connaître la source de l’événement, le type d’action, …
Utilisable avec JButton :
button.addActionListener( ActionListener )
Communication entre composants \ Mise en œuvre des Listeners
Mise en œuvre des Listeners
1ère méthode implémentation directe de l’interface ActionListener
public class AFrame extends javax.swing.JFrame implements java.awt.event.ActionListener{ JButton button1, button2, ...; ··· button1.addActionListener( this ); button2.addActionListener( this ); ··· public void actionPerformed( ActionEvent event ) { if (event.getSource() == button1) ··· else if (event.getSource() == button2) ··· ... } ···}
Communication entre composants \ Mise en œuvre des Listeners
Mise en œuvre des Listeners
1ère méthode implémentation directe de l’interface ActionListener
Deux inconvénients majeurs :
La classe AFrame déclare publiquement "être" un ActionListener, alors qu’aucune autre classe qu’elle-même n’est capable de s’en servir comme ActionListener
L’identification de la source de l’action (button1, button2, …) impose une recherche linéaire parmi les sources potentielles
Communication entre composants \ Mise en œuvre des Listeners
Mise en œuvre des Listeners
2ère méthode création d’un objet implémentant l’interface ActionListener
public class AFrame extends javax.swing.JFrame{ JButton button1, button2, ...; ··· button1.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent event ) { ··· } } ); ··· button2.addActionListener( new ActionListener() ...}
Communication entre composants \ Les Adapters
Les Adapters
Lorsque les interfaces XXXListener comportent de nombreuses méthodes :
Il existe une classe XXXAdapter correspondante, implémentant XXXListener
Toutes les méthodes déclarées par l’interface ont un corps vide
Lorsqu’on n’utilisera qu’une petite partie des méthodes, on spécialisera donc l’Adapter
Communication entre composants \ Générer des événements
Générer des événements
Utiliser une interface existante ou définir le Listener (et éventuellement l’Adapter)
La classe JComponent déclare la variable
protected EventListenerList listenerList
EventListenerList maintient des paires (Classe de Listener , instance de Listener)
EventListenerList définit notamment les méthodes suivantes :
public void add( Class une_class, EventListener listener )
public void remove( Class une_class, EventListener listener )
public Object[] getListenerList()
getListenerList renvoie un tableau t à 2n éléments où, pour tout n :
t[n] est un objet Class
t[n+1] est l’instance de Listener correspondante
Communication entre composants \ Générer des événements
Générer des événements
Définir les méthodes suivantes, qui délèguent le travail à EventListenerList :
public void addListener( XXXListener listener )
public void removeListener( XXXListener listener )
Définir des méthodes fireYYY :
···YYYEvent yyy_event= new YYYEvent( this );···protected void fireYYY(){ Object[] listeners= listenerList.getListenerList();
for ( int i= listeners.length–2 ; i >= 0 ; i-= 2 ) { if (listeners[i] == XXXListener.class) ((FooListener)listeners[i+1]).yyy( yyy_event ); }}
Communication entre composants \ Listeners courants \ ActionListener
Listeners courants
actions
java.awt.event.ActionListener :
void actionPerformed( java.awt.ActionEvent )
Enregistré par addActionListener(…) auprès de :
javax.swing.JButton
javax.swing.JMenuItem
javax.swing.JToggleButton
…
javax.swing.AbstractButton
Communication entre composants \ Listeners courants \ ItemListener
Listeners courants
changements d’état
java.awt.event.ItemListener :
void itemStateChanged( java.awt.event.ItemEvent )
Enregistré par addItemListener(…) auprès de :
javax.swing.JButton
javax.swing.JMenuItem
javax.swing.JToggleButton
javax.swing.JComboBox
…
javax.swing.AbstractButton
Communication entre composants \ Listeners courants \ KeyListener
Listeners courants
événements clavier
java.awt.event.KeyListener :
void keyPressed( java.awt.event.KeyEvent )
void keyReleased( java.awt.event.KeyEvent )
void keyTyped( java.awt.event.KeyEvent )
Enregistré par addKeyListener(…) auprès de :
javax.swing.JComponent (en fait : java.awt.Component)
…
Communication entre composants \ Listeners courants \ MouseListener
Listeners courants
événements souris de base
java.awt.event.MouseListener :
void mouseClicked( java.awt.event.MouseEvent )
void mouseEntered( java.awt.event.MouseEvent )
void mouseExited( java.awt.event.MouseEvent )
void mousePressed( java.awt.event.MouseEvent )
void mouseReleased( java.awt.event.MouseEvent )
Enregistré par addMouseListener(…) auprès de :
javax.swing.JComponent (en fait : java.awt.Component)
…
Communication entre composants \ Listeners courants \ MouseMotionListener
Listeners courants
événements mouvements de souris
java.awt.event.MouseMotionListener :
void mouseDragged( java.awt.event.MouseEvent )
void mouseMoved( java.awt.event.MouseEvent )
Enregistré par addMouseMotionListener(…) auprès de :
javax.swing.JComponent (en fait : java.awt.Component)
…
Communication entre composants \ Listeners courants \ FocusListener
Listeners courants
focus
java.awt.event.FocusListener :
void focusGained( java.awt.event.FocusEvent )
void focusLost( java.awt.event.FocusEvent )
Enregistré par addFocusListener(…) auprès de :
javax.swing.JComponent (en fait : java.awt.Component)
…
Communication entre composants \ Listeners courants \ WindowListener
Listeners courants
événements liés aux fenêtres
java.awt.event.WindowListener :
void windowActivated( java.awt.event.WindowEvent )
void windowClosed( java.awt.event.WindowEvent )
void windowClosing( java.awt.event.WindowEvent )
void windowDeactivated( java.awt.event.WindowEvent )
void windowDeiconified( java.awt.event.WindowEvent )
void windowIconified( java.awt.event.WindowEvent )
void windowOpened( java.awt.event.WindowEvent )
Enregistré par addMouseListener(…) auprès de :
javax.swing.JFrame
javax.swing.JDialog
…java.awt.Window
Communication entre composants \ Listeners courants \ ComponentListener
Listeners courants
événements liés aux composants
java.awt.event.ComponentListener :
void componentHidden( java.awt.event.ComponentEvent )
void componentMoved( java.awt.event.ComponentEvent )
void componentResized( java.awt.event.ComponentEvent )
void componentShown( java.awt.event.ComponentEvent )
Enregistré par addComponentListener(…) auprès de :
javax.swing.JComponent (en fait : java.awt.Component)
…
Communication entre composants \ Gestion interne des événements
Gestion interne des événements
L'OS notifie la VM d'événements :
Déplacements et clicks souris, frappes clavier (événements d'inputs)
Perte, gain du focus
Portions d'écran à mettre à jour
…
La VM insère ces événements, ainsi que ceux générés par le programme, sous forme d'objets dans une queue (file) :
Communication entre composants \ Gestion interne des événements
Gestion interne des événements
Ces événements sont analysés par le dispatching thread
Thread : unité d'exécution qui s'exécute en parallèle d'autres, au sein d'un programme
Les événements d'inputs et de focus sont transmis aux composants, qui en informent leurs listeners
Les mises à jour de l'affichage sont transmises au RepaintManager, qui appelle les mé-thodes paint(…) des composants concernés, qui appellent enfin paintComponent(…)
Les événements de mise à jour de l'affichage ont la plus faible priorité…
Le RepaintManager
Le RepaintManager
javax.swing.RepaintManager
Responsable de :
La gestion des dirty regions de l'écran, à mettre à jour
La gestion du double-buffering
…
Une seule instance par application, renvoyée par :
RepaintManager.currentManager( null )
Optimisation possible de la mise à jour d'un composant complexe en :
1°/ Obtenant sa dirty region (un java.awt.Rectangle) par :
Rectangle RepaintManager.getDirtyRegion( JComponent )
2°/ Ne redessinant que ce qui doit l'être en contrôlant les intersections entre les bounding boxes et la dirty region avec :
boolean intersects( Rectangle )
Le RepaintManager
Le RepaintManager
javax.swing.RepaintManager
Pour les descendants de JComponent, les appels de méthodes lors de la mise à jour de l'affi-chage sont :
paint( Graphics )
paintComponent( Graphics )
paintBorder( Graphics )
paintChildren( Graphics )
La clipping area
La clipping area
Synonyme de dirty region pour un composant :
Zone en dehors de laquelle les ordres graphiques n'ont pas d'effet
S'obtient par le contexte graphique :
Rectangle getClipBounds()
Pluggable Look & Feel
Pluggable Look & Feel
L'AWT délégait l'affichage et le comportement à des composants pairs du système
Swing délégue l'affichage et le comportement à des composants Java pluggables
javax.swing.UIManager propose de nombreuses méthodes pour gérer les L&F :
Obtenir le L&F courant :
LookAndFeel getLookAndFeel()
Obtenir la classe du L&F implémentant le L&F de la plate-forme d'exécution :
String getSystemLookAndFeelClassName()
Obtenir la classe du L&F cross-platform :
String getCrossPlatformLookAndFeelClassName()
Lister les L&F installés :
UIManager.LookAndFeelInfo[] getInstalledLookAndFeels()
Pluggable Look & Feel
Modifier le Look & Feel
Les JComponents exhibent une méthode :
void setUI( ComponentUI new_ui )
Généralement, on change le L&F général :
UIManager.setLookAndFeel( new_LF_class_name );
Puis on lance une mise à jour de l'arbre des composants :
SwingUtilities.updateComponentTreeUI( component );
component devrait être un composant "racine" :
Component SwingUtilities.getRoot( Component component )
Les Applets
Les Applets
Une applet est une petite application en Java, destinée à être intégrée dans une page HTML
Une application standalone :
N'a pas d'exigence en terme de type (elle étend au minimum java.lang.Object)
N'a qu'un seul point d'entrée : public static main( String[] )
Une applet :
Doit au moins étendre java.applet.Applet ou javax.swing.JApplet
N'a pas de point d'entrée exigé
Graphe d'héritage : java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Panel
java.applet.Applet
javax.swing.JApplet
Les Applets \ Etat des applets
Etat des applets
Une applet peut être dans 4 états :
A chaque transition d'état une des méthodes suivante est invoquée :
public void init()
public void start()
public void stop()
public void destroy()
Les Applets \ Arguments des applets
Arguments des applets
Une application standalone reçoit les paramètres de la ligne de commande en argument de la méthode statique main sous forme de liste de valeurs de type String
Une applet reçoit les paramètres jouxtant le tag HTML sous forme d'ensemble de paires <nom,valeur> de type String, lisibles par la méthode :
public String getParameter( String parameter_name )
Les Applets \ Le tag <APPLET>
Le tag <APPLET>
Le tag <APPLET>, fonctionnant si la version de la JVM du navigateur est correcte :
<APPLET [CODEBASE= codebaseURL] CODE= appletFile [ALT= alternateText] [NAME= appletInstanceName] WIDTH= pixels HEIGHT= pixels [ALIGN= alignment] [VSPACE= pixels] [HSPACE= pixels]> [<PARAM NAME= appletParameter1 VALUE= value>] [<PARAM NAME= appletParameter2 VALUE= value>] ... [alternateHTML]</APPLET>
Les Applets \ Les plugins Java
Les plugins Java
Les navigateurs étant souvent en retard de plusieurs versions de JVM (+ M$ qui ne met volontairement pas à jour la JVM d’IE), Sun a développé une technique de plugins Java :
Les navigateurs n'exécutent plus l'applet, mais un plugin qui exécute lui-même l'applet
Le plugin peut-être téléchargé à la volée
Internet Explorer utilise le tag <OBJECT>, Netscape Navigator le tag <EMBED>…
Il faut donc faire trois versions de tags…
Les Applets \ Le tag <OBJECT>
Le tag <OBJECT> (Internet Explorer)
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" WIDTH= pixels HEIGHT= pixels CODEBASE= "http://java.sun.com/products/plugin/1.2.2/ jinstall-1_2_2-win.cab#Version=1,2,2,0"> [CODEBASE= codebaseURL] <PARAM NAME= CODE VALUE= appletFile> <PARAM NAME= "type" VALUE= "application/x-java-applet;version=1.2.2"> <PARAM NAME= "scriptable " VALUE="false"> [<PARAM NAME= CODEBASE VALUE= codebaseURL>] [<PARAM NAME= appletParameter1 VALUE= value>] [<PARAM NAME= appletParameter1 VALUE= value>] ... [<NOEMBED> alternateHTML] <NOEMBED></OBJECT>
Les Applets \ Le tag <EMBED>
Le tag <EMBED> (Netscape Navigator)
<EMBED type= "application/x-java-applet;version=1.2.2" CODE= appletFile WIDTH= pixels HEIGHT= pixels pluginspage= "http://java.sun.com/products/plugin/1.2.2/ plugin-install.html"> scriptable= false [<PARAM NAME= appletParameter1 VALUE= value>] [<PARAM NAME= appletParameter1 VALUE= value>] ... [<NOEMBED> alternateHTML </NOEMBED>]</EMBED>