t
t
t
t
t t   13) Création de fenêtres & d'Applets
tttt
t
carrea) Préface carreb) Avant-propos carre1) Introduction sur les &laqo; objets » carre2) Tout est &laqo; objet » carre3) Contrôle du flux du programme carre4) Initialization & Cleanup carre5) Cacher l'implémentation carre6) Réutiliser les classes carre7) Polymorphisme carre8) Interfaces & classes internes carre9) Stockage des objets carre10) Error Handling with Exceptions carre11) Le système d’E/S de Java carre12) Identification dynamique de type 13) Création de fenêtres & d'Applets carre14) Les &laqo; Threads » multiples carre15) Informatique distribuée carreA) Passage et retour d'objets carreB) L'Interface Java Natif (JNI) carreC) Conseils pour une programation stylée en Java carreD) Resources
Texte original t Traducteur : P. Boite
t
t
///
Ce chapitre contient 14 pages
1 2 3 4 5 6 7 8 9 10 11 12 13 14
\\\
t t t
t t t
t
t t t
Listener interface
w/ adapter
Methods in interface
ActionListener actionPerformed(ActionEvent)
AdjustmentListener adjustmentValueChanged(
AdjustmentEvent)
ComponentListener
ComponentAdapter
componentHidden(ComponentEvent)
componentShown(ComponentEvent)
componentMoved(ComponentEvent)
componentResized(ComponentEvent)
ContainerListener
ContainerAdapter
componentAdded(ContainerEvent)
componentRemoved(ContainerEvent)
FocusListener
FocusAdapter
focusGained(FocusEvent)
focusLost(FocusEvent)
KeyListener
KeyAdapter
keyPressed(KeyEvent)
keyReleased(KeyEvent)
keyTyped(KeyEvent)
MouseListener
MouseAdapter
mouseClicked(MouseEvent)
mouseEntered(MouseEvent)
mouseExited(MouseEvent)
mousePressed(MouseEvent)
mouseReleased(MouseEvent)
MouseMotionListener
MouseMotionAdapter
mouseDragged(MouseEvent)
mouseMoved(MouseEvent)
WindowListener
WindowAdapter
windowOpened(WindowEvent)
windowClosing(WindowEvent)
windowClosed(WindowEvent)
windowActivated(WindowEvent)
windowDeactivated(WindowEvent)
windowIconified(WindowEvent)
windowDeiconified(WindowEvent)
ItemListener itemStateChanged(ItemEvent)
t
Interface listener et adapter Méthodes de l'interface
ActionListener actionPerformed(ActionEvent)
AdjustmentListener adjustmentValueChanged( AdjustmentEvent)
ComponentListener ComponentAdapter componentHidden(ComponentEvent) componentShown(ComponentEvent) componentMoved(ComponentEvent) componentResized(ComponentEvent)
ContainerListener ContainerAdapter componentAdded(ContainerEvent) componentRemoved(ContainerEvent)
FocusListener FocusAdapter focusGained(FocusEvent) focusLost(FocusEvent)
KeyListener KeyAdapter keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent)
MouseListener MouseAdapter mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent)
MouseMotionListener MouseMotionAdapter mouseDragged(MouseEvent) mouseMoved(MouseEvent)
WindowListener WindowAdapter windowOpened(WindowEvent) windowClosing(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) windowIconified(WindowEvent) windowDeiconified(WindowEvent)
ItemListener itemStateChanged(ItemEvent)
t t t
This is not an exhaustive listing, partly because the event model allows you to create your own event types and associated listeners. Thus, you’ll regularly come across libraries that have invented their own events, and the knowledge gained in this chapter will allow you to figure out how to use these events. t Ce n'est pas une liste exhaustive, en partie du fait que le modèle d'événements nous permet de créer nos propres types d'événements et listeners associés. De ce fait, on rencontrera souvent des bibliothèques qui ont inventé leurs propres événements, et la connaissance acquise dans ce chapitre nous permettra de comprendre l'utilisation de ces événements.
t t t

Using listener adapters for simplicity

t

Utilisation de listener adapters pour simplifier

t t t
In the table above, you can see that some listener interfaces have only one method. These are trivial to implement since you’ll implement them only when you want to write that particular method. However, the listener interfaces that have multiple methods can be less pleasant to use. For example, something you must always do when creating an application is provide a WindowListener to the JFrame so that when you get the windowClosing( ) event you can call System.exit( ) to exit the application. But since WindowListener is an interface, you must implement all of the other methods even if they don’t do anything. This can be annoying. t Dans le tableau ci-dessus, on peut voir que certaines interfaces listener ne possèdent qu'une seule méthode. Celles-ci sont triviales à implémenter puisqu'on ne les implémentera que lorsqu'on désire écrire cette méthode particulière. Par contre, les interfaces listener qui ont plusieurs méthodes peuvent être moins agréables à utiliser. par exemple, quelque chose qu'il faut toujours faire en créant une application est de fournir un WindowListener au JFrame de manière à pouvoir appeler System.exit() pour sortir de l'application lorsqu'on reçoit l'événement windowClosing(). Mais comme WindowListener est une interface, il faut implémenter chacune de ses méthodes même si elles ne font rien. Cela peut être ennuyeux.
t t t
To solve the problem, some (but not all) of the listener interfaces that have more than one method are provided with adapters, the names of which you can see in the table above. Each adapter provides default empty methods for each of the interface methods. Then all you need to do is inherit from the adapter and override only the methods you need to change. For example, the typical WindowListener you’ll use looks like this (remember that this has been wrapped inside the Console class in com.bruceeckel.swing): t Pour résoudre le problème, certaines (mais pas toutes) des interfaces listener qui ont plus d'une méthode possèdent des adaptateurs [adapters], dont vous pouvez voir les noms dans le tableau ci-dessus. Chaque adaptateur fournit des méthodes vides par défaut pour chacune des méthodes de l'interface. Ensuite il suffit d'hériter de cet adaptateur et de redéfinir uniquement les méthodes qu'on doit modifier. Par exemple, le WindowListener qu'on utilisera normalement ressemble à ceci (souvenez-vous qu'il a été encapsulé dans la classe Console de com.bruceeckel.swing) :
t t t
class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } } t
class MyWindowListener extends WindowAdapter {
  public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
t t t
The whole point of the adapters is to make the creation of listener classes easy. t Le seul but des adaptateurs est de faciliter la création des classes listener.
t t t
There is a downside to adapters, however, in the form of a pitfall. Suppose you write a WindowAdapter like the one above: t Il y a cependant un désavantage lié aux adaptateurs, sous la forme d'un piège. Supposons qu'on écrive un WindowAdapter comme celui ci-dessus :
t t t
class MyWindowListener extends WindowAdapter { public void WindowClosing(WindowEvent e) { System.exit(0); } } t
class MyWindowListener extends WindowAdapter {
  public void WindowClosing(WindowEvent e) {
System.exit(0);
}
}
t t t
This doesn’t work, but it will drive you crazy trying to figure out why, since everything will compile and run fine—except that closing the window won’t exit the program. Can you see the problem? It’s in the name of the method: WindowClosing( ) instead of windowClosing( ). A simple slip in capitalization results in the addition of a completely new method. However, this is not the method that’s called when the window is closing, so you don’t get the desired results. Despite the inconvenience, an interface will guarantee that the methods are properly implemented.
t Ceci ne marche pas, mais il nous rendra fous à comprendre pourquoi, car tout va compiler et s'exécuter correctement, sauf que la fermeture de la fenêtre ne fera pas sortir du programme. Voyez-vous le problème ? Il est situé dans le nom de la méthode : WindowClosing() au lieu de windowClosing(). Une simple erreur de majuscule se traduit par l'ajout d'une méthode nouvelle. Ce n'est cependant pas cette méthode qui est appelée lorsque la fenêtre est fermée, de sorte qu'on n'obtient pas le résultat attendu. En dépit de cet inconvénient, une interface garantit que les méthodes sont correctement implémentées.
t t t

Tracking multiple events

t

Surveiller plusieurs événements

t t t
To prove to yourself that these events are in fact being fired, and as an interesting experiment, it’s worth creating an applet that tracks extra behavior in a JButton (other than just whether it’s pressed or not). This example also shows you how to inherit your own button object because that’s what is used as the target of all the events of interest. To do so, you can just inherit from JButton.[69] t Pour nous prouver que ces événements sont bien déclenchés, et en tant qu'expérience intéressante, créons une applet qui surveille les autres comportement d'un JButton, autres que le simple fait qu'il soit appuyé ou pas. Cet exemple montre également comment hériter de notre propre objet bouton, car c'est ce qui est utilisé comme cible de tous les événements intéressants. Pour cela, il suffit d'hériter de JButton name="fnB69" href="#fn69">[69].
t t t
The MyButton class is an inner class of TrackEvent, so MyButton can reach into the parent window and manipulate its text fields, which is what’s necessary to be able to write the status information into the fields of the parent. Of course this is a limited solution, since myButton can be used only in conjunction with TrackEvent. This kind of code is sometimes called “highly coupled”: t La classe MyButton est une classe interne de TrackEvent, de sorte que MyButton peut aller dans la fenêtre parent et manipuler ses champs textes, ce qu'il faut pour pouvoir écrire une information d'état dans les champs du parent. Bien sûr ceci est une solution limitée, puisque MyButton peut être utilisée uniquement avec TrackEvent. Ce genre de code est parfois appelé "fortement couplé" :
t t t
//: c13:TrackEvent.java // Show events as they happen. // <applet code=TrackEvent // width=700 height=500></applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.*; import com.bruceeckel.swing.*; public class TrackEvent extends JApplet { HashMap h = new HashMap(); String[] event = { "focusGained", "focusLost", "keyPressed", "keyReleased", "keyTyped", "mouseClicked", "mouseEntered", "mouseExited","mousePressed", "mouseReleased", "mouseDragged", "mouseMoved" }; MyButton b1 = new MyButton(Color.blue, "test1"), b2 = new MyButton(Color.red, "test2"); class MyButton extends JButton { void report(String field, String msg) { ((JTextField)h.get(field)).setText(msg); } FocusListener fl = new FocusListener() { public void focusGained(FocusEvent e) { report("focusGained", e.paramString()); } public void focusLost(FocusEvent e) { report("focusLost", e.paramString()); } }; KeyListener kl = new KeyListener() { public void keyPressed(KeyEvent e) { report("keyPressed", e.paramString()); } public void keyReleased(KeyEvent e) { report("keyReleased", e.paramString()); } public void keyTyped(KeyEvent e) { report("keyTyped", e.paramString()); } }; MouseListener ml = new MouseListener() { public void mouseClicked(MouseEvent e) { report("mouseClicked", e.paramString()); } public void mouseEntered(MouseEvent e) { report("mouseEntered", e.paramString()); } public void mouseExited(MouseEvent e) { report("mouseExited", e.paramString()); } public void mousePressed(MouseEvent e) { report("mousePressed", e.paramString()); } public void mouseReleased(MouseEvent e) { report("mouseReleased", e.paramString()); } }; MouseMotionListener mml = new MouseMotionListener() { public void mouseDragged(MouseEvent e) { report("mouseDragged", e.paramString()); } public void mouseMoved(MouseEvent e) { report("mouseMoved", e.paramString()); } }; public MyButton(Color color, String label) { super(label); setBackground(color); addFocusListener(fl); addKeyListener(kl); addMouseListener(ml); addMouseMotionListener(mml); } } public void init() { Container c = getContentPane(); c.setLayout(new GridLayout(event.length+1,2)); for(int i = 0; i < event.length; i++) { JTextField t = new JTextField(); t.setEditable(false); c.add(new JLabel(event[i], JLabel.RIGHT)); c.add(t); h.put(event[i], t); } c.add(b1); c.add(b2); } public static void main(String[] args) { Console.run(new TrackEvent(), 700, 500); } } ///:~ t
//: c13:TrackEvent.java
// Montre les evenements lorsqu'ils arrivent.
// <applet code=TrackEvent
//  width=700 height=500></applet>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import com.bruceeckel.swing.*;

public class TrackEvent extends JApplet {
HashMap h = new HashMap();
String[] event = {
   "focusGained", "focusLost", "keyPressed",
   "keyReleased", "keyTyped", "mouseClicked",
   "mouseEntered", "mouseExited","mousePressed",
   "mouseReleased", "mouseDragged", "mouseMoved"
};
MyButton
b1 = new MyButton(Color.blue, "test1"),
b2 = new MyButton(Color.red, "test2");
  class MyButton extends JButton {
   void report(String field, String msg) {
((JTextField)h.get(field)).setText(msg);
}    
FocusListener fl = new FocusListener() {
    public void focusGained(FocusEvent e) {
   report("focusGained", e.paramString());
}
    public void focusLost(FocusEvent e) {
   report("focusLost", e.paramString());
}
};
KeyListener kl = new KeyListener() {
    public void keyPressed(KeyEvent e) {
   report("keyPressed", e.paramString());
}
    public void keyReleased(KeyEvent e) {
   report("keyReleased", e.paramString());
}
    public void keyTyped(KeyEvent e) {
   report("keyTyped", e.paramString());
}
};
MouseListener ml = new MouseListener() {
    public void mouseClicked(MouseEvent e) {
   report("mouseClicked", e.paramString());
}
    public void mouseEntered(MouseEvent e) {
   report("mouseEntered", e.paramString());
}
    public void mouseExited(MouseEvent e) {
   report("mouseExited", e.paramString());
}
    public void mousePressed(MouseEvent e) {
   report("mousePressed", e.paramString());
}
    public void mouseReleased(MouseEvent e) {
   report("mouseReleased", e.paramString());
}
};
MouseMotionListener mml =
    new MouseMotionListener() {
    public void mouseDragged(MouseEvent e) {
   report("mouseDragged", e.paramString());
}
    public void mouseMoved(MouseEvent e) {
   report("mouseMoved", e.paramString());
}
};
   public MyButton(Color color, String label) {
    super(label);
setBackground(color);
addFocusListener(fl);
addKeyListener(kl);
addMouseListener(ml);
addMouseMotionListener(mml);
}
}  
  public void init() {
Container c = getContentPane();
c.setLayout(new GridLayout(event.length+1,2));
   for(int i = 0; i JTextField t = new JTextField();
t.setEditable(false);
c.add(new JLabel(event[i], JLabel.RIGHT));
c.add(t);
h.put(event[i], t);
}
c.add(b1);
c.add(b2);
}
  public static void main(String[] args) {
Console.run(new TrackEvent(), 700, 500);
}
} ///:~
t t t
In the MyButton constructor, the button’s color is set with a call to SetBackground( ). The listeners are all installed with simple method calls. t Dans le constructeur de MyButton, la couleur des boutons est positionnée par un appel à SetBackground(). Les listeners sont tous installés par de simples appels de méthodes.
t t t
The TrackEvent class contains a HashMap to hold the strings representing the type of event and JTextFields where information about that event is held. Of course, these could have been created statically rather than putting them in a HashMap, but I think you’ll agree that it’s a lot easier to use and change. In particular, if you need to add or remove a new type of event in TrackEvent, you simply add or remove a string in the event array—everything else happens automatically. t La classe TrackEvent contient une HashMap pour contenir les chaînes représentant le type d'événement et les JTextFields dans lesquels l'information sur cet événement est conservée. Bien sûr, ceux-ci auraient pu être créés en statique plutôt qu'en les mettant dans une HashMap, mais je pense que vous serez d'accord que c'est beaucoup plus facile à utiliser et modifier. En particulier, si on a besoin d'ajouter ou supprimer un nouveau type d'événement dans TrackEvent, il suffit d'ajouter ou supprimer une chaîne dans le tableau event, et tout le reste est automatique.
t t t
When report( ) is called it is given the name of the event and the parameter string from the event. It uses the HashMap h in the outer class to look up the actual JTextField associated with that event name, and then places the parameter string into that field. t Lorsque report() est appelé on lui donne le nom de l'événement et la chaîne des paramètres de cet événement. Il utilise le HashMap h de la classe externe pour rechercher le JTextField associé à l'événement portant ce nom, et place alors la chaîne des paramètres dans ce champ.
t t t
This example is fun to play with since you can really see what’s going on with the events in your program.
t Cet exemple est amusant à utiliser car on peut réellement voir ce qui se passe avec les événements dans son programme.
t t t

A catalog of Swing components

t

Un catalogue de composants Swing

t t t
Now that you understand layout managers and the event model, you’re ready to see how Swing components can be used. This section is a nonexhaustive tour of the Swing components and features that you’ll probably use most of the time. Each example is intended to be reasonably small so that you can easily lift the code and use it in your own programs. t Maintenant que nous connaissons les layout managers et le modèle d'événements, nous sommes prêts pour voir comment utiliser les composants Swing. Cette section est une visite non exhaustive des composants Swing et des fonctionnalités que vous utiliserez probablement la plupart du temps. Chaque exemple est conçu pour être de taille raisonnable de manière à pouvoir facilement récupérer le code dans d'autres programmes.
t t t
You can easily see what each of these examples looks like while running by viewing the HTML pages in the downloadable source code for this chapter. t Vos pouvez facilement voir à quoi ressemble chacun de ces exemples en fonctionnement, en visualisant les pages HTML dans le code source téléchargeable de ce chapitre.
t t t
Keep in mind: t
Gardez en tête :
t t t
  1. The HTML documentation from java.sun.com contains all of the Swing classes and methods (only a few are shown here).
  2. Because of the naming convention used for Swing events, it’s fairly easy to guess how to write and install a handler for a particular type of event. Use the lookup program ShowAddListeners.java from earlier in this chapter to aid in your investigation of a particular component.
  3. When things start to get complicated you should graduate to a GUI builder.
t
  1. La documentation HTML de java.sun.com comprend toutes les classes et méthodes de Swing (seules quelques-unes sont montrées ici),
  2. Grâce aux conventions de nommage utilisées pour les événements Swing, il est facile de deviner comment écrire et installer un gestionnaire d'un événement de type donné. Utilisez le programme de recherche ShowAddListeners.java introduit plus avant dans ce chapitre pour faciliter votre investigation d'un composant particulier.
  3. Lorsque les choses deviendront compliquées, passez à un GUI builder.
t t t

Buttons

t

Boutons

t t t
Swing includes a number of different types of buttons. All buttons, check boxes, radio buttons, and even menu items are inherited from AbstractButton (which, since menu items are included, would probably have been better named “AbstractChooser” or something equally general). You’ll see the use of menu items shortly, but the following example shows the various types of buttons available: t Swing comprend un certain nombre de boutons de différents types. Tous les boutons, boîtes à cocher [check boxes], boutons radio [radio buttons], et même les éléments de menus [menu items] héritent de AbstractButton(qui, vu qu'ils comprennent les éléments de menus, auraient probablement été mieux nommés AbstractChooser ou quelque chose du genre). Nous verrons l'utilisation des éléments de menus bientôt, mais l'exemple suivant montre les différents types de boutons existants :
t t t
//: c13:Buttons.java // Various Swing buttons. // <applet code=Buttons // width=350 height=100></applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.plaf.basic.*; import javax.swing.border.*; import com.bruceeckel.swing.*; public class Buttons extends JApplet { JButton jb = new JButton("JButton"); BasicArrowButton up = new BasicArrowButton( BasicArrowButton.NORTH), down = new BasicArrowButton( BasicArrowButton.SOUTH), right = new BasicArrowButton( BasicArrowButton.EAST), left = new BasicArrowButton( BasicArrowButton.WEST); public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(jb); cp.add(new JToggleButton("JToggleButton")); cp.add(new JCheckBox("JCheckBox")); cp.add(new JRadioButton("JRadioButton")); JPanel jp = new JPanel(); jp.setBorder(new TitledBorder("Directions")); jp.add(up); jp.add(down); jp.add(left); jp.add(right); cp.add(jp); } public static void main(String[] args) { Console.run(new Buttons(), 350, 100); } } ///:~ t
//: c13:Buttons.java
// Divers boutons Swing.
// <applet code=Buttons
//  width=350 height=100></applet>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.plaf.basic.*;
import javax.swing.border.*;
import com.bruceeckel.swing.*;

public class Buttons extends JApplet {
JButton jb = new JButton("JButton");
BasicArrowButton
up = new BasicArrowButton(
BasicArrowButton.NORTH),
down = new BasicArrowButton(
BasicArrowButton.SOUTH),
right = new BasicArrowButton(
BasicArrowButton.EAST),
left = new BasicArrowButton(
BasicArrowButton.WEST);
  public void init() {
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(jb);
cp.add(new JToggleButton("JToggleButton"));
cp.add(new JCheckBox("JCheckBox"));
cp.add(new JRadioButton("JRadioButton"));
JPanel jp = new JPanel();
jp.setBorder(new TitledBorder("Directions"));
jp.add(up);
jp.add(down);
jp.add(left);
jp.add(right);
cp.add(jp);
}
  public static void main(String[] args) {
Console.run(new Buttons(), 350, 100);
}
} ///:~
t t t
This begins with the BasicArrowButton from javax.swing.plaf.basic, then continues with the various specific types of buttons. When you run the example, you’ll see that the toggle button holds its last position, in or out. But the check boxes and radio buttons behave identically to each other, just clicking on or off (they are inherited from JToggleButton). t On commence par le BasicArrowButtonde javax.swing.plaf.basic, puis on continue avec les divers types de boutons. Si vous exécutez cet exemple, vous verrez que le toggle button (bouton inverseur) garde sa dernière position, enfoncé ou relâché. Mais les boîtes à cocher et les boutons radio se comportent de manière identique, on les clique pour les (dé)sélectionner (ils sont hérités de JToggleButton).
t t t

Button groups

t

Groupes de boutons

t t t
If you want radio buttons to behave in an “exclusive or” fashion, you must add them to a “button group.” But, as the example below demonstrates, any AbstractButton can be added to a ButtonGroup. t Si on désire des boutons radio qui se comportent selon un "ou exclusif", il faut les ajouter à un groupe de boutons. Mais, comme l'exemple ci-dessous le montre, tout AbstractButton peut être ajouté à un ButtonGroup.
t t t
To avoid repeating a lot of code, this example uses reflection to generate the groups of different types of buttons. This is seen in makeBPanel( ), which creates a button group and a JPanel. The second argument to makeBPanel( ) is an array of String. For each String, a button of the class represented by the first argument is added to the JPanel: t Pour éviter de répéter beaucoup de code, cet exemple utilise la réflexion pour générer les groupes de différents types de boutons. Ceci peut se voir dans makeBPanel(), qui crée un groupe de boutons et un JPanel. Le second argument de makeBPanel() est un tableau de String. Pour chaque String, un bouton de la classe désignée par le premier argument est ajouté au JPanel :
t t t
//: c13:ButtonGroups.java // Uses reflection to create groups // of different types of AbstractButton. // <applet code=ButtonGroups // width=500 height=300></applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.border.*; import java.lang.reflect.*; import com.bruceeckel.swing.*; public class ButtonGroups extends JApplet { static String[] ids = { "June", "Ward", "Beaver", "Wally", "Eddie", "Lumpy", }; static JPanel makeBPanel(Class bClass, String[] ids) { ButtonGroup bg = new ButtonGroup(); JPanel jp = new JPanel(); String title = bClass.getName(); title = title.substring( title.lastIndexOf('.') + 1); jp.setBorder(new TitledBorder(title)); for(int i = 0; i < ids.length; i++) { AbstractButton ab = new JButton("failed"); try { // Get the dynamic constructor method // that takes a String argument: Constructor ctor = bClass.getConstructor( new Class[] { String.class }); // Create a new object: ab = (AbstractButton)ctor.newInstance( new Object[]{ids[i]}); } catch(Exception ex) { System.err.println("can't create " + bClass); } bg.add(ab); jp.add(ab); } return jp; } public void init() { Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(makeBPanel(JButton.class, ids)); cp.add(makeBPanel(JToggleButton.class, ids)); cp.add(makeBPanel(JCheckBox.class, ids)); cp.add(makeBPanel(JRadioButton.class, ids)); } public static void main(String[] args) { Console.run(new ButtonGroups(), 500, 300); } } ///:~ t
//: c13:ButtonGroups.java
// Utilise la reflexion pour creer des groupes
// de differents types de AbstractButton.
// <applet code=ButtonGroups
//  width=500 height=300></applet>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.border.*;
import java.lang.reflect.*;
import com.bruceeckel.swing.*;

public class ButtonGroups extends JApplet {
  static String[] ids = {
   "June", "Ward", "Beaver",
   "Wally", "Eddie", "Lumpy",
};
  static JPanel
makeBPanel(Class bClass, String[] ids) {
ButtonGroup bg = new ButtonGroup();
JPanel jp = new JPanel();
String title = bClass.getName();
title = title.substring(
title.lastIndexOf('.') + 1);
jp.setBorder(new TitledBorder(title));
   for(int i = 0; i AbstractButton ab = new JButton("failed");
    try {
     // Obtient la méthode de construction dynamique
     // qui demande un argument String :
   Constructor ctor = bClass.getConstructor(
      new Class[] { String.class });
     // Creation d'un nouve objet :
   ab = (AbstractButton)ctor.newInstance(
      new Object[]{ids[i]});
} catch(Exception ex) {
   System.err.println("can't create " +
     bClass);
}
bg.add(ab);
jp.add(ab);
}
   return jp;
}
  public void init() {
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(makeBPanel(JButton.class, ids));
cp.add(makeBPanel(JToggleButton.class, ids));
cp.add(makeBPanel(JCheckBox.class, ids));
cp.add(makeBPanel(JRadioButton.class, ids));
}
  public static void main(String[] args) {
Console.run(new ButtonGroups(), 500, 300);
}
} ///:~
t t t
t t t
t t
\\\
///
t t t
t
     
Sommaire Le site de Bruce Eckel