AWT (Abstract Window Toolkit) est l'ensemble des classes Java originales qui permet de faire des interfaces graphiques. Ces classes sont situées dans le package java.awt. AWT repose sur les widgets systèmes. Par widget on entend les boutons, les menus, etc...
Pour être portable au niveau également de l'apparence, et bien dégager la notion de modèle (par exemple une structure d'arbre) par rapport à son rendu (comment l'arbre va être affiché à l'écran), les classes Swing ont été créées. Ces classes sont dans le package javax.swing.
Le passage de AWT à Swing se fait facilement. Pour beaucoup de classes il suffit de rajouter un J devant le nom. Par exemple en AWT on dispose de Applet, Panel, Frame. Les classes équivalentes sont disponibles en Swing : JApplet, JPanel, JFrame. De plus on trouve des nouveaux composants très pratiques, comme par exemple : JTree pour afficher un arbre, JTabbedPane pour afficher des onglets.
Dans cette section plusieurs images proviennent de l'URL:
JApplet : Cette classe est une sous classe de java.applet.Applet. Elle permet de faire des applets où les composants sont des widgets Swing et non AWT. Son usage est similaire à celui de java.applet.Applet.
JDialog : C'est la classe swing qui permet de créer des dialogues sur mesure. Pour des dialogues simples on préfèrera utiliser la classe JOptionPane. Typiquement l'image ci-contre est obtenue à l'aire de JOptionPane. Il existe une classe toute faite pour obtenir une boite de dialogue permettant de choisir un fichier JFileChooser.
JFrame : C'est la classe qui remplace Frame dans l'AWT. Il s'agit d'une fenêtre avec les boutons standards.
JPanel : Il s'agit d'une classe destinée à contenir d'autres classes. Les attributs généralement modifiés sont la couleur du fond, les bords, ainsi que l'appel à la méthode void setLayout(LayoutManager mgr) pour gérer la manière dont les composants sont placés.
JScrollPane : Permet de visualiser un objet trop grand. Au lieu d'écrire directement dans un JPanel :
textArea = new JTextArea(5, 30); add(textArea, BorderLayout.CENTER);On peut le mettre préalablement dans un JScrollPane :
textArea = new JTextArea(5, 30); JScrollPane scrollPane = new JScrollPane(textArea); add(scrollPane, BorderLayout.CENTER);
JTabbedPane : Permet de mettre plusieurs JPanel dans des onglets. La méthode pour ajouter des onglets est add :
JTabbedPane tabbedPane = new JTabbedPane();
ImageIcon icon = createImageIcon("images/middle.gif");
JComponent panel1 = makeTextPanel("Panel #1");
tabbedPane.addTab("One", icon, panel1, "Does nothing");
...
JToolBar : Permet de créer une barre de boutons. Les boutons sont des instances de JButton. Un ActionListener leur est attribué. Il suffit de les ajouter dans la toolbar à l'aide de la commande add.
public class RecupereLesActions implements ActionListener {
public void actionPerformed(ActionEvent e) {
...
}
}
JToolBar toolBar = new JToolBar();
JButton button = new JButton();
RecupereLesActions recupereLesActions = new RecupereLesActions();
button.addActionListener(recupereLesActions);
toolBar.add(button);
JSplitPane : Permet d'affichier deux JPanels séparés verticalement ou horizontalement.
JSplitPane hSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
panel1,
panel2);
JInternalFrame : Permet d'affichier une fenêtre dans un JFrame.
JLayeredPane : Permet d'afficher des JPanels à différents niveaux.
JRootPane : C'est la structure à la base des composants Swing pouvant contenir des menus. Le JRootPane n'est pas l'objet dans lequel on ajoute des composants rootPane. add(child); est impossible, à la place on fera rootPane. getContentPane(). add(child);. Les JRootPane ne sont pas crées tout seuls, mais viennent en général avec des composants existants.
rootPane.getContentPane().setLayout(new BoxLayout());
JButton : représente les boutons. Cette classe partage la classe abstraite AbstractButton avec entre autres : JCheckBox, JRadioButton, JMenuButton, JCheckBoxMenuItem, JRadioButtonMenuItem.
public class ButtonDemo extends JPanel
implements ActionListener {
protected JButton b1, b2, b3;
public ButtonDemo() {
// ...
b1 = new JButton("MonBouton");
b1.setActionCommand("disable");
b1.setActionListener(this);
add(b1);
}
public void actionPerformed(ActionEvent e) {
if ("disable".equals(e.getActionCommand())) {
...
}
}
}
JComboBox : Permet de faire une liste dans laquelle l'utilisateur va pouvoir faire un seul choix. Il existe une forme éditable pour rajouter des items à la volée dans la liste.
JList : Permet d'afficher une liste d'objets, où l'utilisateur peut choisir plusieurs items.
JMenu : Permet de faire des menus. Les menus sont généralement ajoutés dans une barre de menus (JMenuBar) et comportent de items de type JMenuItem. L'exercice 1 détaille comment relier les menus aux actions à effectuer.
JSlider : Permet de rentrer une valeur numérique comprise entre deux bornes.
JSpinner : ressemble à une combo box mais sans partie dépliable qui peux recouvrir d'autres composants.
JTextField : permet de rentrer un champ texte.
JLabel : permet d'afficher une chaîne de caractères.
JProgressBar : Affiche une barre de progression.
JToolTip : Affiche des indications sur un composant.
JColorChooser : Dialogue permettant de choisir une couleur.
JFileChooser : Dialogue permettant de choisir un fichier. Une utilisation de cette classe est demandée dans l'exercice 1.
JTable : Permet d'afficher un tableau
JText :
JTree :
Plusieurs composants swing sont implémentés suivant l'architecture Model View Controler (MVC), c'est à dire que les fonctionnalités suivantes sont implémentées de manière séparées :
Les rôles view et controler sont souvent joués par les mêmes entités.
Le modèle s'obtient en général par la méthode getModel (par exemple dans JTree, JSlider, JTabbedPane ...).
Pour plus de détails :
L'exercice 2 donne une illustration d'un usage fréquent de l'architecture MVC.
Pour pouvoir gérer les évènements qui se produisent il faut implémenter l'interface correspondant à l'évènement.
class Toto implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent e) {
// ...
}
}
et pour enregistrer une instance de Toto auprès
d'une instance de JTextField :
JTextField text = new JTextField(); Toto toto = new Toto(); text.addActionListener(toto);
class Toto implements javax.swing.event.ChangeListener {
public void stateChanged(javax.swing.event.ChangeEvent e) {
// ...
}
}
et pour enregistrer une instance de Toto auprès
d'une instance de JSlider :
JSlider slider = new JSlider(javax.swing.JSlider.HORIZONTAL,0,50,100); Toto toto = new Toto(); slider.addChangeListener(toto);
Voici une liste non exhaustive des évènements possibles:
Un tableau récapitulatif est présent à l'URL :
Q1 Le but de cette question est de rajouter un menu qui permet de sortir. Il faut rajouter un menu Fichier avec un item Quitter qui permet de fermer.
On va pour cela créer une classe nommée DrawingPanel qui ``enrobe'' la classe Drawing. On utilisera le squelette suivant :
package ex1;
public class DrawingPanel extends javax.swing.JPanel
{
Drawing drawing = null;
class QuitAction extends javax.swing.AbstractAction {
QuitAction() { super("quit"); }
public void actionPerformed(java.awt.event.ActionEvent e) {
quit();
}
}
DrawingPanel() {
// ...
}
public void quit() {
System.exit(0);
}
public javax.swing.JMenuBar createMenuBar() {
// ...
}
public static void main(String [] argv) {
javax.swing.JFrame frame = new javax.swing.JFrame("Drawing");
frame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
DrawingPanel d = new DrawingPanel();
frame.setContentPane((javax.swing.JComponent)d);
frame.setJMenuBar(d.createMenuBar());
frame.pack();
frame.setVisible(true);
}
}
Indications : dans la méthode createMenuBar on créé
une instance de javax.swing.JMenuBar dans laquelle
on a ajouté une instance de javax.swing.JMenu
dans laquelle on a ajouté une instance de javax.swing.JMenuItem.
On aura utilisé la méthde addActionListener sur l'instance
de javax.swing.JMenuItem pour associer l'action correspondante.
Q2 Ajouter un item ouvrir dans le menu pour ouvrir un fichier. Indication : utiliser la classe javax.swing.JFileChooser pour choisir le fichier à ouvrir, appeler la méthode loadImage de la classe ex1.Drawing pour charger l'image.
Q3 Si cela n'a pas déjà été fait à la question 1, mettre l'instance de ex1.Drawing dans un javax.swing.JScrollPane pour pouvoir visualiser les images de taille importantes.
L'idée de l'exercice est de montrer qu'il est facile de remplacer un modèle existant par un modèle ayant de nouvelles fonctionnalités.
Q1 Créer une classe ex2.CustomSlider qui permet de choisir un entier à l'aide d'une classe JSlider et affiche la valeur dans un JTextField, comme illustré ci-dessous.
Q2 On souhaite qu'une modification du JTextField permette de modifier la position du slider. Indication : utiliser la méthode addActionListener sur le JTextField pour récupérer les changements.
Q3 On souhaite maintenant que la partie modèle stocke un double et non un int.
Téléchargez la classe CustomRangeModel à l'url :
On remarquera que CustomRangeModel implémente BoundedRangeModel. On peut donc s'en servir comme modèle pour n'importe quel JSlider.Replacer le modèle du JSlider grâce au constructeur JSlider(BoundedRangeModel brm). Adapter les méthodes précédemment écrites pour pouvoir rentrer des données de type double dans le JTextField.