IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

L'impression en java


précédentsommairesuivant

III. L'API java existante

Le but de ce chapitre est de présenter succinctement l'API mise à la disposition d'un développeur voulant réaliser une impression en Java. Ce n'est en aucun cas une documentation complète.

III-A. Quoi imprimer ?

Pour l'impression, il faut tout d'abord un contenu. Pour cela, Java propose plusieurs interfaces dont Printable.

III-A-1. L'interface Printable

Cette interface ne définit qu'une seule méthode :

Méthode de rendu d'une page à imprimer.

 
Sélectionnez
int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException
Paramètres
  • graphics: Contexte graphique pour le rendu de la page à imprimer.
  • pageFormat: Informations sur le format de la page à imprimer comme la taille et l'orientation.
  • pageIndex: Index de la page à imprimer
Valeur retournée
  • Retourne Printable.PAGE_EXISTS si le rendu de la page s'est bien déroulée et Printable.NO_SUCH_PAGE si pageIndex spécifie une page non existante.
Exceptions
  • PrinterException : Lancée quand l'impression est interrompue.





Ainsi pour vouloir imprimer une page contenant un simple rectangle entourant la page, suivie d'une page contenant une ellipse de même dimension, il suffit d'implémenter cette interface comme ceci :

 
Sélectionnez
import java.awt.Color;
import java.awt.Graphics;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

public class PrintRectangle implements Printable {
   
   /** Constructeur par défaut de PrintRectangle */
   public PrintRectangle() {
   }


   public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
      // Par défaut, retourne NO_SUCH_PAGE => la page n'existe pas
      int retValue = Printable.NO_SUCH_PAGE;
      switch(pageIndex){
         case 0 : {
            // Dessin de la première page
            // Récupère la dimension de la zone imprimable
            double xLeft  = pageFormat.getImageableX();
            double yTop   = pageFormat.getImageableY();
            double width  = pageFormat.getImageableWidth();
            double height = pageFormat.getImageableHeight();
            
            // Dessine le rectangle
            graphics.setColor(Color.BLACK);
            graphics.drawRect((int)xLeft,
                              (int)yTop,
                              (int)width,
                              (int)height);
            // La page est valide
            retValue = Printable.PAGE_EXISTS;
            break;
         }
         case 1 : {
            // Dessin de la seconde page
            // Récupère la dimension de la zone imprimable
            double xLeft  = pageFormat.getImageableX();
            double yTop   = pageFormat.getImageableY();
            double width  = pageFormat.getImageableWidth();
            double height = pageFormat.getImageableHeight();
            
            // Dessine l'ellipse
            graphics.setColor(Color.BLACK);
            graphics.drawOval((int)xLeft,
                              (int)yTop,
                              (int)width,
                              (int)height);
            // La page est valide
            retValue = Printable.PAGE_EXISTS;
            break;
         }
      }
      return retValue;
   }
   
}

Cette implémentation teste d'abord l'index de la page à imprimer transmis à la méthode print.
Pour la première page (pageIndex = 0), les informations sur la zone imprimable de la page sont récupérées à l'aide du paramètre pageFormat, puis un rectangle est dessiné à l'aide du contexte graphique transmis. La seconde page fait la même opération en remplaçant le rectangle par une ellipse.

Après chaque page rendue, la méthode retourne la constante Printable.PAGE_EXISTS pour indiquer le bon déroulement de l'impression. Dans le cas où l'index de page est invalide, il suffit de retourner Printable.NO_SUCH_PAGE.

II-A-2. L'interface Pageable

Dans l'exemple précédent, nous avons défini un Printable gérant 2 pages. Dans ce cas à plusieurs pages, il est préférable d'utiliser l'interface Pageable qui représente un conteneur de Printable où chaque page peut choisir son format d'impression.
Cette interface définit 3 méthodes.

Méthode qui retourne le nombre de pages à imprimer.

 
Sélectionnez
int getNumberOfPages()
Valeur retournée
  • Retourne le nombre de pages à imprimer ou Pageable.UNKOWN_NUMBER_OF_PAGES si ce nombre est indéterminé.




Méthode qui retourne le format de page pour une page donnée.

 
Sélectionnez
PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException
Paramètres
  • pageIndex : Index de la page.
Valeur retournée
  • Retourne les informations sur la taille et l'orientation de la page souhaitée pour cette page.
Exceptions
  • IndexOutOfBoundsException : Lancée si pageIndex est erroné..




Méthode qui retourne l'objet de rendu pour une page donnée.

 
Sélectionnez
Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException
Paramètres
  • pageIndex : Index de la page.
Valeur retournée
  • Retourne l'objet de rendu pour cette page.
Exceptions
  • IndexOutOfBoundsException : Lancée si pageIndex est erroné..

III-B. Comment imprimer ?

III-B-1. La classe PrinterJob

Une fois défini le contenu à imprimer, il faut envoyer un travail d'impression à un service d'impression. Cette tâche est réalisée par la classe PrinterJob.

 
Sélectionnez
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

public class Main {
   
   /** Creates a new instance of Main */
   public Main() {
   }
   
   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) {
      // Récupère un PrinterJob
      PrinterJob job = PrinterJob.getPrinterJob();
      // Définit son contenu à imprimer
      job.setPrintable(new PrintRectangle());
      // Affiche une boîte de choix d'imprimante
      if (job.printDialog()){
         try {
            // Effectue l'impression
            job.print();
         } catch (PrinterException ex) {
            ex.printStackTrace();
         }
      }
   }
}

La classe PrinterJob n'a pas de constructeur accessible. De ce fait, une instance de cette classe est obtenue en appelant sa méthode statique getPrinterJob(). Une fois, cette instance obtenue il est possible :

  • de lui affecter un contenu à imprimer (setPrintable, setPageable,...).
  • de demander à l'utilisateur de choisir l'imprimante où imprimer (printDialog,...).
  • d'effectuer l'impression par la méthode print.

En exécutant, ce petit programme, vous devez voir apparaître cette boîte de dialogue :

Image non disponible

Cette boîte est la boîte standard de configuration d'impression de l'OS (ici Windows). Vous pouvez sélectionner et configurer l'imprimante.
En appuyant sur Ok, vous imprimez 2 pages (l'une avec un rectangle et l'autre avec une ellipse) sur l'imprimante. L'appui sur Annuler, annule évidemment l'impression.

Et voilà, en quelques lignes de code, nous avons réussi à imprimer deux pages. Toutefois, toute la configuration de l'imprimante a été laissée au choix de l'utilisateur et c'est au rendu d'impression (l'implémentation de l'interface Printable) de s'adapter. Mais comment spécifier des préférences pour l'impression ? La solution est d'utiliser les requêtes d'impression ou PrintRequestAttribute.

III-B-1-a. Les PrintRequestAttribute ou requêtes d'impression

Basées sur la notion d'Attribute, les requêtes d'impression permettent aux développeurs de contrôler la configuration de l'impression.
L'interface javax.print.attribute.Attribute définit deux méthodes :

Méthode qui retourne la catégorie de cet attribut.

 
Sélectionnez
Class< ? extends Attribute> getCategory()
Valeur retournée
  • Retourne la classe de la catégorie de cet attribut.




Méthode qui retourne le nom de la catégorie de cet attribut.

 
Sélectionnez
String getName()
Valeur retournée
  • Retourne le nom de la catégorie de cet attribut.




Ces attributs peuvent être rangés dans un javax.print.attribute.AttributeSet où il ne peut y avoir au même instant qu'une seule (ou zéro) valeur d'une catégorie donnée. Par exemple, si on prend la catégorie javax.print.attribute.standard.Chromacity qui est la catégorie pour le choix entre l'impression noir & blanc et l'impression couleur. Cette catégorie ne contient que deux instances possibles : Chromacity.MONOCHROM et Chromacity.COLOR. Alors ces deux choix ne peuvent cohabiter dans un même set d'attributs ; c'est l'un ou l'autre ou aucun.

Cette notion étant utilisée à plusieurs endroits dans l'API d'impression de java, des familles d'attributs permettent de spécialiser les attributs pour des fonctions spécifiques. Ces familles sont matérialisées par un héritage de l'interface Attribute :

  • DocAttribute : Catégorie d'attributs de configuration d'un document (notion non abordée ici)
  • PrintJobAttribute : Catégorie d'attributs pour obtenir le statut ou d'autres caractéristiques d'un travail d'impression.
  • PrintRequestAttribute : Catégorie d'attributs pour configurer une impression.
  • PrintServiceAttribute : Catégorie d'attributs pour obtenir un statut ou d'autres caractéristiques d'un service d'impression (Un service d'impression peut être assimilé à une imprimante)
  • SupportedValuesAttribute : Catégorie d'attributs pour récupérer les valeurs supportées par une autre catégorie d'attributs. Par exemple, il est possible de connaître les résolutions supportées par une imprimante.

Modifions l'exemple précédent :

 
Sélectionnez
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.OrientationRequested;

/**
 *
 *
 */
public class Main2 {
   
   /** Constructeur par défaut de Main2 */
   public Main2() {
   }
   
   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) {
      // TODO code application logic here
      PrinterJob job = PrinterJob.getPrinterJob();
      HashPrintRequestAttributeSet printRequestSet = new HashPrintRequestAttributeSet();
      
      printRequestSet.add(OrientationRequested.LANDSCAPE);
      
      job.setPrintable(new PrintRectangle());
      if (job.printDialog(printRequestSet)){
         try {
            job.print();
         } catch (PrinterException ex) {
            ex.printStackTrace();
         }
      }
   }
}

Exécutons-le. La boîte suivante s'affiche  :

Image non disponible

Ce n'est plus du tout la boîte de dialogue native du système mais au contraire une boîte spécifique à Java. Si on peut encore choisir l'imprimante, le bouton propriétés est grisé. Par contre, on peut voir dans l'onglet « Mise en page » que la demande d'impression en paysage a bien été prise en compte.

Image non disponible

De plus quand l'utilisateur clique sur imprimer, le set de requêtes transmis à la méthode printDialog est mis à jour automatiquement pour refléter les choix de l'utilisateur. Il est donc possible à ce stade de connaître ces choix pour, par exemple, afficher un aperçu avant impression. Par contre, cette boîte ne permet plus de configurer les attributs spécifiques à une imprimante comme la sortie d'une page de garde, de l'agrafage des pages, etc...


précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2009 Bruno RICHETON. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.