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
Although any JComponent may be painted and thus used as a canvas, if you just want a straightforward drawing surface you will typically inherit from a JPanel. The only method you need to override is paintComponent( ), which is called whenever that component must be repainted (you normally don’t need to worry about this, as the decision is managed by Swing). When it is called, Swing passes a Graphics object to the method, and you can then use this object to draw or paint on the surface. t Bien que tout JComponent puisse être peint et donc utilisé en tant que canevas, si on désire la surface de dessin la plus simple, on hérite habituellement d'un JPanel. La seule méthode qu'on doit redéfinit est paintComponent(), qui est appelée chaque fois que le composant doit être redessiné (on ne doit normalement pas s'occuper de ceci, la décision étant prise par Swing). Lorsque cette méthode est appelée, Swing lui passe un objet Graphics, et on peut alors utiliser cet objet pour dessiner ou peindre sur la surface.
t t t
In the following example, all the intelligence concerning painting is in the SineDraw class; the SineWave class simply configures the program and the slider control. Inside SineDraw, the setCycles( ) method provides a hook to allow another object—the slider control, in this case—to control the number of cycles. t Dans l'exemple suivant, toute l'intelligence concernant le dessin est contenue dans la classe SineDraw; la classe SineWave configure simplement le programme et le curseur. Dans SineDraw, la méthode setCycles() fournit un moyen pour permettre à un autre objet (le curseur dans ce cas) de contrôler le nombre de cycles.
t t t
//: c13:SineWave.java // Drawing with Swing, using a JSlider. // <applet code=SineWave // width=700 height=400></applet> import javax.swing.*; import javax.swing.event.*; import java.awt.*; import com.bruceeckel.swing.*; class SineDraw extends JPanel { static final int SCALEFACTOR = 200; int cycles; int points; double[] sines; int[] pts; SineDraw() { setCycles(5); } public void setCycles(int newCycles) { cycles = newCycles; points = SCALEFACTOR * cycles * 2; sines = new double[points]; pts = new int[points]; for(int i = 0; i < points; i++) { double radians = (Math.PI/SCALEFACTOR) * i; sines[i] = Math.sin(radians); } repaint(); } public void paintComponent(Graphics g) { super.paintComponent(g); int maxWidth = getWidth(); double hstep = (double)maxWidth/(double)points; int maxHeight = getHeight(); for(int i = 0; i < points; i++) pts[i] = (int)(sines[i] * maxHeight/2 * .95 + maxHeight/2); g.setColor(Color.red); for(int i = 1; i < points; i++) { int x1 = (int)((i - 1) * hstep); int x2 = (int)(i * hstep); int y1 = pts[i-1]; int y2 = pts[i]; g.drawLine(x1, y1, x2, y2); } } } public class SineWave extends JApplet { SineDraw sines = new SineDraw(); JSlider cycles = new JSlider(1, 30, 5); public void init() { Container cp = getContentPane(); cp.add(sines); cycles.addChangeListener(new ChangeListener(){ public void stateChanged(ChangeEvent e) { sines.setCycles( ((JSlider)e.getSource()).getValue()); } }); cp.add(BorderLayout.SOUTH, cycles); } public static void main(String[] args) { Console.run(new SineWave(), 700, 400); } } ///:~ t
//: c13:SineWave.java
// Dessin avec Swing, en utilisant un JSlider.
// <applet code=SineWave
//  width=700 height=400></applet>
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import com.bruceeckel.swing.*;

class SineDraw extends JPanel {
  static final int SCALEFACTOR = 200;
  int cycles;
  int points;
  double[] sines;
  int[] pts;
  SineDraw() { setCycles(5); }
  public void setCycles(int newCycles) {
    cycles = newCycles;
    points = SCALEFACTOR * cycles * 2;
    sines = new double[points];
    pts = new int[points];
    for(int i = 0; i       double radians = (Math.PI/SCALEFACTOR) * i;
      sines[i] = Math.sin(radians);
    }
    repaint();
  }    
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    int maxWidth = getWidth();
    double hstep = (double)maxWidth/(double)points;
    int maxHeight = getHeight();
    for(int i = 0; i       pts[i] = (int)(sines[i] * maxHeight/2 * .95
                     + maxHeight/2);
    g.setColor(Color.red);
    for(int i = 1; i       int x1 = (int)((i - 1) * hstep);
      int x2 = (int)(i * hstep);
      int y1 = pts[i-1];
      int y2 = pts[i];
      g.drawLine(x1, y1, x2, y2);
    }
  }
}

public class SineWave extends JApplet {
  SineDraw sines = new SineDraw();
  JSlider cycles = new JSlider(1, 30, 5);
  public void init() {
    Container cp = getContentPane();
    cp.add(sines);
    cycles.addChangeListener(new ChangeListener(){
      public void stateChanged(ChangeEvent e) {
        sines.setCycles(
          ((JSlider)e.getSource()).getValue());
      }
    });
    cp.add(BorderLayout.SOUTH, cycles);
  }
  public static void main(String[] args) {
    Console.run(new SineWave(), 700, 400);
  }
} ///:~
t t t
All of the data members and arrays are used in the calculation of the sine wave points: cycles indicates the number of complete sine waves desired, points contains the total number of points that will be graphed, sines contains the sine function values, and pts contains the y-coordinates of the points that will be drawn on the JPanel. The setCycles( ) method creates the arrays according to the number of points needed and fills the sines array with numbers. By calling repaint( ) , setCycles( ) forces paintComponent( ) to be called so the rest of the calculation and redraw will take place. t Tous les membres de données et tableaux sont utilisés dans le calcul des points du sinus : cycles indique le nombre de périodes complètes de sinus désiré, points contient le nombre total de points qui sera tracé, sines contient les valeurs de la fonction sinus, et pts contient les coordonnées y des points qui seront tracés sur le JPanel. La méthode setCycles() construit le tableau selon le nombre de points nécessaires et remplit le tableau sines de valeurs. En appelant repaint(), setCycles force l'appel de paintComponent() , afin que le reste des calculs et le dessin aient lieu.
t t t
The first thing you must do when you override paintComponent( ) is to call the base-class version of the method. Then you are free to do whatever you like; normally, this means using the Graphics methods that you can find in the documentation for java.awt.Graphics (in the HTML documentation from java.sun.com) to draw and paint pixels onto the JPanel. Here, you can see that almost all the code is involved in performing the calculations; the only two method calls that actually manipulate the screen are setColor( ) and drawLine( ). You will probably have a similar experience when creating your own program that displays graphical data—you’ll spend most of your time figuring out what it is you want to draw, but the actual drawing process will be quite simple. t La première chose à faire lorsqu'on redéfinit paintComponent() est d'appeler la version de base de la méthode. Ensuite on peut faire ce que l'on veut; normalement cela signifie utiliser les méthodes de Graphics qu'on peut trouver dans la documentation de java.awt.Graphics (dans la documentation HTML de java.sun.com) pour dessiner et peindre des pixels sur le JPanel. On peut voir ici que la plupart du code concerne l'exécution des calculs, les deux seules méthodes qui manipulent effectivement l'écran sont setColor() et drawLine(). Vous aurez probablement la même sensation lorsque vous créerez votre propre programme d'affichage de données graphiques : vous passerez la plus grande partie du temps à déterminer ce qu'il faut dessiner, mais le dessin en lui-même sera assez simple.
t t t
When I created this program, the bulk of my time was spent in getting the sine wave to display. Once I did that, I thought it would be nice to be able to dynamically change the number of cycles. My programming experiences when trying to do such things in other languages made me a bit reluctant to try this, but it turned out to be the easiest part of the project. I created a JSlider (the arguments are the left-most value of the JSlider, the right-most value, and the starting value, respectively, but there are other constructors as well) and dropped it into the JApplet. Then I looked at the HTML documentation and noticed that the only listener was the addChangeListener, which was triggered whenever the slider was changed enough for it to produce a different value. The only method for this was the obviously named stateChanged( ), which provided a ChangeEvent object so that I could look backward to the source of the change and find the new value. By calling the sines object’s setCycles( ), the new value was incorporated and the JPanel redrawn. t Lorsque j'ai créé ce programme, j'ai passé le plus gros de mon temps à obtenir la courbe du sinus à afficher. Ceci fait, j'ai pensé que ce serait bien de pouvoir modifier dynamiquement le nombre de cycles. Mes expériences de programmation de ce genre de choses dans d'autres langages me rendaient un peu réticent, mais cette partie se révéla la partie la plus facile du projet. J'ai créé un JSlider (les arguments sont respectivement la valeur de gauche du JSlider, la valeur de droite, et la valeur initiale, mais il existe d'autres constructeurs) et je l'ai déposé dans le JApplet. Ensuite j'ai regardé dans la documentation HTML et j'ai vu que le seul listener était le addChangeListener, qui était déclenché chaque fois que le curseur était déplacé suffisamment pour produire une nouvelle valeur. La seule méthode pour cela était évidemment appelée stateChanged(), qui fournit un objet ChangeEvent, de manière à pouvoir rechercher la source de la modification et obtenir la nouvelle valeur.En appelant setCycles() des objets sines, la nouvelle valeur est prise en compte et le JPanel est redessiné.
t t t
In general, you will find that most of your Swing problems can be solved by following a similar process, and you’ll find that it’s generally quite simple, even if you haven’t used a particular component before. t En général, on verra que la plupart des problèmes Swing peuvent être résolus en suivant un processus semblable, et on verra qu'il est en général assez simple, même si on n'a pas utilisé auparavant un composant donné.
t t t
If your problem is more complex, there are other more sophisticated alternatives for drawing, including third-party JavaBeans components and the Java 2D API. These solutions are beyond the scope of this book, but you should look them up if your drawing code becomes too onerous.
t Si le problème est plus compliqué, il y a d'autres solutions plus sophistiquées, par exemple les composants JavaBeans de fournisseurs tiers, et l'API Java 2D. Ces solutions sortent du cadre de ce livre, mais vous devriez les prendre en considération si votre code de dessin devient trop coûteux.
t t t

Dialog Boxes

t

Boîtes de dialogue

t t t
A dialog box is a window that pops up out of another window. Its purpose is to deal with some specific issue without cluttering the original window with those details. Dialog boxes are heavily used in windowed programming environments, but less frequently used in applets. t Une boîte de dialogue est une fenêtre qui est issue d'une autre fenêtre. Son but est de traiter un problème spécifique sans encombrer la fenêtre d'origine avec ces détails. Les boîtes de dialogue sont fortement utilisées dans les environnements de programmation à fenêtres, mais moins fréquemment utilisées dans les applets.
t t t
To create a dialog box, you inherit from JDialog, which is just another kind of Window, like a JFrame. A JDialog has a layout manager (which defaults to BorderLayout) and you add event listeners to deal with events. One significant difference when windowClosing( ) is called is that you don’t want to shut down the application. Instead, you release the resources used by the dialog’s window by calling dispose( ). Here’s a very simple example: t Pour créer une boîte de dialogue, il faut hériter de JDialog, qui est simplement une sorte de Window, comme les JFrames. Un JDialog possède un layout manager (qui est par défaut le BorderLayout) auquel on ajoute des listeners d'événements pour traiter ceux-ci. Il y a une différence importante : on ne veut pas fermer l'application lors de l'appel de windowClosing(). Au lieu de cela, on libère les ressources utilisées par la fenêtre de dialogue en appelant dispose(). Voici un exemple très simple :
t t t
//: c13:Dialogs.java // Creating and using Dialog Boxes. // <applet code=Dialogs width=125 height=75> // </applet> import javax.swing.*; import java.awt.event.*; import java.awt.*; import com.bruceeckel.swing.*; class MyDialog extends JDialog { public MyDialog(JFrame parent) { super(parent, "My dialog", true); Container cp = getContentPane(); cp.setLayout(new FlowLayout()); cp.add(new JLabel("Here is my dialog")); JButton ok = new JButton("OK"); ok.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ dispose(); // Closes the dialog } }); cp.add(ok); setSize(150,125); } } public class Dialogs extends JApplet { JButton b1 = new JButton("Dialog Box"); MyDialog dlg = new MyDialog(null); public void init() { b1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ dlg.show(); } }); getContentPane().add(b1); } public static void main(String[] args) { Console.run(new Dialogs(), 125, 75); } } ///:~ t
//: c13:Dialogs.java
// Création et utilisation de boîtes de dialogue.
// <applet code=Dialogs width=125 height=75>
// </applet>
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import com.bruceeckel.swing.*;

class MyDialog extends JDialog {
  public MyDialog(JFrame parent) {
    super(parent, "My dialog", true);
    Container cp = getContentPane();
    cp.setLayout(new FlowLayout());
    cp.add(new JLabel("Here is my dialog"));
    JButton ok = new JButton("OK");
    ok.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e){
        dispose(); // Ferme le dialogue
      }
    });
    cp.add(ok);
    setSize(150,125);
  }
}

public class Dialogs extends JApplet {
  JButton b1 = new JButton("Dialog Box");
  MyDialog dlg = new MyDialog(null);
  public void init() {
    b1.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e){
        dlg.show();
      }
    });
    getContentPane().add(b1);
  }
  public static void main(String[] args) {
    Console.run(new Dialogs(), 125, 75);
  }
} ///:~
t t t
Once the JDialog is created, the show( ) method must be called to display and activate it. For the dialog to close, it must call dispose( ). t Une fois le JDialog créé, la méthode show() doit être appelée pour l'afficher et l'activer. Pour que le dialogue se ferme, il faut appeler dispose().
t t t
You’ll see that anything that pops up out of an applet, including dialog boxes, is “untrusted.” That is, you get a warning in the window that’s been popped up. This is because, in theory, it would be possible to fool the user into thinking that they’re dealing with a regular native application and to get them to type in their credit card number, which then goes across the Web. An applet is always attached to a Web page and visible within your Web browser, while a dialog box is detached—so in theory, it could be possible. As a result it is not so common to see an applet that uses a dialog box. t On remarquera que tout ce qui sort d'une applet, y compris les boîtes de dialogue, n'est pas digne de confiance. C'est à dire qu'on obtient un avertissement dans la fenêtre qui apparaît. Ceci est dû au fait qu'en théorie il serait possible de tromper l'utilisateur et lui faire croire qu'il a à faire avec une de ses applications normales et de le faire taper son numéro de carte de crédit, qui partirait alors sur le Web. Une applet est toujours attachée à une page Web et visible dans un navigateur, tandis qu'une boîte de dialogue est détachée, et tout ceci est donc possible en théorie. Le résultat est qu'il n'est pas fréquent de voir une applet qui utilise une boîte de dialogue.
t t t
The following example is more complex; the dialog box is made up of a grid (using GridLayout) of a special kind of button that is defined here as class ToeButton. This button draws a frame around itself and, depending on its state, a blank, an “x,” or an “o” in the middle. It starts out blank, and then depending on whose turn it is, changes to an “x” or an “o.” However, it will also flip back and forth between “x” and “o” when you click on the button. (This makes the tic-tac-toe concept only slightly more annoying than it already is.) In addition, the dialog box can be set up for any number of rows and columns by changing numbers in the main application window. t L'exemple suivant est plus complexe; la boîte de dialogue est composée d'une grille (en utilisant GridLayout) d'un type de bouton particulier qui est défini ici comme la classe ToeButton. Ce bouton dessine un cadre autour de lui et, selon son état, un blanc, un x ou un o au milieu. Il démarre en blanc, et ensuite, selon à qui c'est le tour, se modifie en x ou en o. Cependant, il transformera le x en o et vice versa lorsqu'on clique sur le bouton (ceci rend le principe du tic-tac-toe seulement un peu plus ennuyeux qu'il ne l'est déjà). De plus, la boîte de dialogue peut être définie avec un nombre quelconque de rangées et de colonnes dans la fenêtre principale de l'application.
t t t
//: c13:TicTacToe.java // Demonstration of dialog boxes // and creating your own components. // <applet code=TicTacToe // width=200 height=100></applet> import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*; public class TicTacToe extends JApplet { JTextField rows = new JTextField("3"), cols = new JTextField("3"); static final int BLANK = 0, XX = 1, OO = 2; class ToeDialog extends JDialog { int turn = XX; // Start with x's turn // w = number of cells wide // h = number of cells high public ToeDialog(int w, int h) { setTitle("The game itself"); Container cp = getContentPane(); cp.setLayout(new GridLayout(w, h)); for(int i = 0; i < w * h; i++) cp.add(new ToeButton()); setSize(w * 50, h * 50); // JDK 1.3 close dialog: //#setDefaultCloseOperation( //# DISPOSE_ON_CLOSE); // JDK 1.2 close dialog: addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e){ dispose(); } }); } class ToeButton extends JPanel { int state = BLANK; public ToeButton() { addMouseListener(new ML()); } public void paintComponent(Graphics g) { super.paintComponent(g); int x1 = 0; int y1 = 0; int x2 = getSize().width - 1; int y2 = getSize().height - 1; g.drawRect(x1, y1, x2, y2); x1 = x2/4; y1 = y2/4; int wide = x2/2; int high = y2/2; if(state == XX) { g.drawLine(x1, y1, x1 + wide, y1 + high); g.drawLine(x1, y1 + high, x1 + wide, y1); } if(state == OO) { g.drawOval(x1, y1, x1 + wide/2, y1 + high/2); } } class ML extends MouseAdapter { public void mousePressed(MouseEvent e) { if(state == BLANK) { state = turn; turn = (turn == XX ? OO : XX); } else state = (state == XX ? OO : XX); repaint(); } } } } class BL implements ActionListener { public void actionPerformed(ActionEvent e) { JDialog d = new ToeDialog( Integer.parseInt(rows.getText()), Integer.parseInt(cols.getText())); d.setVisible(true); } } public void init() { JPanel p = new JPanel(); p.setLayout(new GridLayout(2,2)); p.add(new JLabel("Rows", JLabel.CENTER)); p.add(rows); p.add(new JLabel("Columns", JLabel.CENTER)); p.add(cols); Container cp = getContentPane(); cp.add(p, BorderLayout.NORTH); JButton b = new JButton("go"); b.addActionListener(new BL()); cp.add(b, BorderLayout.SOUTH); } public static void main(String[] args) { Console.run(new TicTacToe(), 200, 100); } } ///:~ t
//: c13:TicTacToe.java
// Démonstration de boîtes de dialogue
// et création de vos propres composants.
// <applet code=TicTacToe
//  width=200 height=100></applet>
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.bruceeckel.swing.*;

public class TicTacToe extends JApplet {
  JTextField
    rows = new JTextField("3"),
    cols = new JTextField("3");
  static final int BLANK = 0, XX = 1, OO = 2;
  class ToeDialog extends JDialog {
    int turn = XX; // Démarre avec x a jouer
    // w = nombre de cellules en largeur
    // h = nombre de cellules en hauteur
    public ToeDialog(int w, int h) {
      setTitle("The game itself");
      Container cp = getContentPane();
      cp.setLayout(new GridLayout(w, h));
      for(int i = 0; i         cp.add(new ToeButton());
      setSize(w * 50, h * 50);
      // fermeture du dialogue en JDK 1.3 :
      //#setDefaultCloseOperation(
      //#  DISPOSE_ON_CLOSE);
      // fermeture du dialogue en JDK 1.2 :
      addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e){
          dispose();
        }
      });    
    }
    class ToeButton extends JPanel {
      int state = BLANK;
      public ToeButton() {
        addMouseListener(new ML());
      }
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int x1 = 0;
        int y1 = 0;
        int x2 = getSize().width - 1;
        int y2 = getSize().height - 1;
        g.drawRect(x1, y1, x2, y2);
        x1 = x2/4;
        y1 = y2/4;
        int wide = x2/2;
        int high = y2/2;
        if(state == XX) {
          g.drawLine(x1, y1,
            x1 + wide, y1 + high);
          g.drawLine(x1, y1 + high,
            x1 + wide, y1);
        }
        if(state == OO) {
          g.drawOval(x1, y1,
            x1 + wide/2, y1 + high/2);
        }
      }
      class ML extends MouseAdapter {
        public void mousePressed(MouseEvent e) {
          if(state == BLANK) {
            state = turn;
            turn = (turn == XX ? OO : XX);
          }
          else
            state = (state == XX ? OO : XX);
          repaint();
        }
      }
    }
  }
  class BL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      JDialog d = new ToeDialog(
        Integer.parseInt(rows.getText()),
        Integer.parseInt(cols.getText()));
      d.setVisible(true);
    }
  }
  public void init() {
    JPanel p = new JPanel();
    p.setLayout(new GridLayout(2,2));
    p.add(new JLabel("Rows", JLabel.CENTER));
    p.add(rows);
    p.add(new JLabel("Columns", JLabel.CENTER));
    p.add(cols);
    Container cp = getContentPane();
    cp.add(p, BorderLayout.NORTH);
    JButton b = new JButton("go");
    b.addActionListener(new BL());
    cp.add(b, BorderLayout.SOUTH);
  }
  public static void main(String[] args) {
    Console.run(new TicTacToe(), 200, 100);
  }
} ///:~
t t t
Because statics can only be at the outer level of the class, inner classes cannot have static data or static inner classes. t Comme les statics peuvent être uniquement au niveau le plus extérieur de la classe, les classes internes ne peuvent pas avoir de données static ni de classes internes static.
t t t
The paintComponent( ) method draws the square around the panel, and the “x” or the “o.” This is full of tedious calculations, but it’s straightforward. t La méthode paintComponent() dessine le carré autour du panneau, et le x ou le o. C'est rempli de calculs fastidieux, mais c'est direct.
t t t
A mouse click is captured by the MouseListener, which first checks to see if the panel has anything written on it. If not, the parent window is queried to find out whose turn it is and that is used to establish the state of the ToeButton. Via the inner class mechanism, the ToeButton then reaches back into the parent and changes the turn. If the button is already displaying an “x” or an “o” then that is flopped. You can see in these calculations the convenient use of the ternary if-else described in Chapter 3. After a state change, the ToeButton is repainted. t Les clics de souris sont capturés par le MouseListener, qui vérifie d'abord si le panneau a déjà quelque chose d'écrit sur lui. Si ce n'est pas le cas, on recherche la fenêtre parente pour déterminer à qui est le tour, et on positionne l'état du ToeButton en conséquence. Le ToeButton retrouve le parent par le mécanisme de la classe interne, et passe au tour suivant. Si le bouton affiche déjà un x ou un o, son affichage est inversé. On peut voir dans ces calculs l'usage pratique du if-else ternaire décrit au Chapitre 3. On repeint le ToeButton chaque fois qu'il change d'état.
t t t
The constructor for ToeDialog is quite simple: it adds into a GridLayout as many buttons as you request, then resizes it for 50 pixels on a side for each button. t Le constructeur de ToeDialog est assez simple : il ajoute à un GridLayout autant de boutons que demandé, puis redimensionne chaque bouton à 50 pixels.
t t t
TicTacToe sets up the whole application by creating the JTextFields (for inputting the rows and columns of the button grid) and the “go” button with its ActionListener. When the button is pressed, the data in the JTextFields must be fetched, and, since they are in String form, turned into ints using the static Integer.parseInt( ) method.
t TicTacToe installe l'ensemble de l'application par la création de JTextFields (pour entrer le nombre de rangées et colonnes de la grille de boutons) et le bouton «go» avec son ActionListener. Lorsqu'on appuie sur le bouton, les données dans les JTextFields doivent être récupérées et, puisqu'elles sont au format String, transformées en ints en utilisant la méthode statique Integer.parseInt().
t t t

File dialogs

t

Dialogues pour les fichiers [File dialogs]

t t t
Some operating systems have a number of special built-in dialog boxes to handle the selection of things such as fonts, colors, printers, and the like. Virtually all graphical operating systems support the opening and saving of files, however, and so Java’s JFileChooser encapsulates these for easy use. t Certains systèmes d'exploitation ont des boîtes de dialogue standard pour gérer certaines choses telles que les fontes, les couleurs, les imprimantes, et cetera. En tout cas, pratiquement tous les systèmes d'exploitation graphiques fournissent les moyens d'ouvrir et de sauver les fichiers, et le JFileChooser de Java les encapsule pour une utilisation facile.
t t t
The following application exercises two forms of JFileChooser dialogs, one for opening and one for saving. Most of the code should by now be familiar, and all the interesting activities happen in the action listeners for the two different button clicks: t L'application suivante utilise deux sortes de dialogues JFileChooser, un pour l'ouverture et un pour la sauvegarde. La plupart du code devrait maintenant être familière, et toute la partie intéressante se trouve dans les action listeners pour les différents clics de boutons :
t t t
//: c13:FileChooserTest.java // Demonstration of File dialog boxes. import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.bruceeckel.swing.*; public class FileChooserTest extends JFrame { JTextField filename = new JTextField(), dir = new JTextField(); JButton open = new JButton("Open"), save = new JButton("Save"); public FileChooserTest() { JPanel p = new JPanel(); open.addActionListener(new OpenL()); p.add(open); save.addActionListener(new SaveL()); p.add(save); Container cp = getContentPane(); cp.add(p, BorderLayout.SOUTH); dir.setEditable(false); filename.setEditable(false); p = new JPanel(); p.setLayout(new GridLayout(2,1)); p.add(filename); p.add(dir); cp.add(p, BorderLayout.NORTH); } class OpenL implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); // Demonstrate "Open" dialog: int rVal = c.showOpenDialog(FileChooserTest.this); if(rVal == JFileChooser.APPROVE_OPTION) { filename.setText( c.getSelectedFile().getName()); dir.setText( c.getCurrentDirectory().toString()); } if(rVal == JFileChooser.CANCEL_OPTION) { filename.setText("You pressed cancel"); dir.setText(""); } } } class SaveL implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser c = new JFileChooser(); // Demonstrate "Save" dialog: int rVal = c.showSaveDialog(FileChooserTest.this); if(rVal == JFileChooser.APPROVE_OPTION) { filename.setText( c.getSelectedFile().getName()); dir.setText( c.getCurrentDirectory().toString()); } if(rVal == JFileChooser.CANCEL_OPTION) { filename.setText("You pressed cancel"); dir.setText(""); } } } public static void main(String[] args) { Console.run(new FileChooserTest(), 250, 110); } } ///:~ t
//: c13:FileChooserTest.java
// Démonstration de boîtes de dialogues de fichiers.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import com.bruceeckel.swing.*;

public class FileChooserTest extends JFrame {
  JTextField
    filename = new JTextField(),
    dir = new JTextField();
  JButton
    open = new JButton("Open"),
    save = new JButton("Save");
  public FileChooserTest() {
    JPanel p = new JPanel();
    open.addActionListener(new OpenL());
    p.add(open);
    save.addActionListener(new SaveL());
    p.add(save);
    Container cp = getContentPane();
    cp.add(p, BorderLayout.SOUTH);
    dir.setEditable(false);
    filename.setEditable(false);
    p = new JPanel();
    p.setLayout(new GridLayout(2,1));
    p.add(filename);
    p.add(dir);
    cp.add(p, BorderLayout.NORTH);
  }
  class OpenL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      JFileChooser c = new JFileChooser();
      // Démontre le dialogue "Open" :
      int rVal =
        c.showOpenDialog(FileChooserTest.this);
      if(rVal == JFileChooser.APPROVE_OPTION) {
        filename.setText(
          c.getSelectedFile().getName());
          dir.setText(
            c.getCurrentDirectory().toString());
      }
      if(rVal == JFileChooser.CANCEL_OPTION) {
        filename.setText("You pressed cancel");
        dir.setText("");
      }
    }
  }
  class SaveL implements ActionListener {
    public void actionPerformed(ActionEvent e) {
      JFileChooser c = new JFileChooser();
      // Démontre le dialogue "Save" :
      int rVal =
        c.showSaveDialog(FileChooserTest.this);
      if(rVal == JFileChooser.APPROVE_OPTION) {
        filename.setText(
          c.getSelectedFile().getName());
          dir.setText(
            c.getCurrentDirectory().toString());
      }
      if(rVal == JFileChooser.CANCEL_OPTION) {
        filename.setText("You pressed cancel");
        dir.setText("");
      }
    }
  }
  public static void main(String[] args) {
    Console.run(new FileChooserTest(), 250, 110);
  }
} ///:~
t t t
t t t
t t
\\\
///
t t t
t
     
Sommaire Le site de Bruce Eckel