Swing : Afficher ses Pdf avec style

Florent Dupont

Voici un premier tutoriel pour utiliser le PDFRenderer et afficher ses PDF de manière graphique. ♪

- Titre : Swing : Afficher ses Pdf avec style

- Auteur : Florent Dupont

- Parution : 2 octobre 2008

- Mise à jour : 2 octobre 2008

- Licence : Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.

Sommaire

- I. Introduction

- II. Première étape : utiliser le PDF Renderer

- III. Seconde étape : ajouter un effet de reliure en spirale

- IV. Étape finale : mixer le tout

- V. Aller plus loin

- VI. Téléchargements

I - Introduction

Ce tutoriel va nous expliquer rapidement comment utiliser SwingX pour créer son propre Visualiseur PDF. Le but de ce tutoriel est de créer un effet sur les fichiers PDF, un peu comme ceux que l'on peut voir sur Mac OS X lorsque l'on ouvre un dossier contenant des fichiers PDF.

II - Première étape : utiliser le PDF Renderer

L'équipe SwingLabs a récemment sorti un PDF Renderer, une API qui ne permet pas de créer des PDF, mais d'afficher leur contenu.

Pour plus d'informations sur cette librairie, on peut se rendre sur le site officiel du projet.

L'utilisation de cette librairie est très simple. Tout ce qu'il y a à faire est d'ouvrir le fichier PDF, stocker ce fichier dans un ByteBuffer et créer un PDFFile depuis ce buffer. Le site officiel donne les principaux exemples d'utilisation : Exporter une PDFPage dans une BufferedImage, ou encore dans un Graphics.

Dans notre premier exemple plus bas, nous allons utiliser un JXPanel (du projet SwingX) pour simplement afficher la première page de notre fichier PDF en tant qu'image.

public class PdfRendererTester extends JXFrame {

private static final long serialVersionUID = 1L;

public PdfRendererTester() {

setTitle("PDF Renderer Tester");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

String url = "/Users/flo/Documents/pdf/PaintingEffects.pdf";

// this one above is not working.
//String url = "/Users/flo/Documents/pdf/TS-3414.pdf";

Image pdfImage;
JLabel lbl = new JLabel();
try {
pdfImage = getImageFromPdf(url);
Image tmbPdfImage = GraphicsUtilities.createThumbnail((BufferedImage)pdfImage, 400);
lbl.setIcon(new ImageIcon(tmbPdfImage));

} catch (IOException e) {
e.printStackTrace();
lbl.setText(e.toString());

}
add(lbl);
pack();
}

public Image getImageFromPdf(String fileUrl) throws IOException {

//load a pdf from a byte buffer
File file = new File(fileUrl);
RandomAccessFile raf = new RandomAccessFile(file, "r");
FileChannel channel = raf.getChannel();
ByteBuffer buf = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
PDFFile pdffile = new PDFFile(buf);

// draw the first page to an image
PDFPage page = pdffile.getPage(0);

//get the width and height for the doc at the default zoom
Rectangle rect = new Rectangle(0,0,
(int)page.getBBox().getWidth(),
(int)page.getBBox().getHeight());

//generate the image
Image result = page.getImage(
rect.width, rect.height, //width & height
rect, // clip rect
null, // null for the ImageObserver
true, // fill background with white
true  // block until drawing is done
);

return result;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new PdfRendererTester().setVisible(true);
}});
}
}

On obtient finalement ce résultat :

Certains fichiers PDF provoquent des erreurs OutOfMemoryError ou autres. Pour l'instant l'équipe Singlabs ne prend pas en compte toutes les fonctionnalités des PDF et donc, certaines peuvent ne pas être rendues correctement.

III - Seconde étape : ajouter un effet de reliure en spirale

On va maintenant utiliser les SwingX Painters pour créer l'effet de reliure sur la gauche de l'image pour ajouter un effet plus réaliste.

Comme rien d'équivalent n'existe dans SwingX pour créer un tel effet, nous allons implémenter le nôtre. Nous avons donc créé une classe utilitaire PDFUtil qui va s'occuper de créer notre effet à partir d'une BufferedImage existante. Cette méthode dessine au-dessus de l'image existante un effet de gloss puis un ensemble de lignes pour faire une pseudoreliure. L'appel à la méthode createSpiralBinding() est fait depuis notre méthode getImageFromPdf()

createSpiralBinding(GraphicsUtilities.createThumbnail(result, newSize));

IV - Étape finale : mixer le tout

CompoundPainter est utilisé ici pour assembler les différents Painter :

- celui contenant l'image PDF ;

- celui contenant l'effet d'ombre.

img = PdfUtil.getImageFromPdf(url, imgSize.width, imgSize.height);
ImagePainter pdfPainter = new ImagePainter(img);

ShadowRenderer shadowRndr = new ShadowRenderer();
shadowRndr.setOpacity(0.9f);
shadowRndr.setSize(10);

BufferedImage shadowImg = shadowRndr.createShadow(img);
ImagePainter shadowPainter = new ImagePainter(shadowImg);

CompoundPainter cp = new CompoundPainter(shadowPainter, pdfPainter);

JXLabel lbl = new JXLabel();
lbl.setBackgroundPainter(cp);

Maintenant, on peut exécuter le tout pour voir le résultat.

V - Aller plus loin

SwingX Painters sur DeveloperLife qui m'a inspiré pour écrire cet article.
Le site du projet PDFRenderer où on trouvera les sources du projet ainsi que des exemples.
SwingLabs qui met à disposition un ensemble de composants Swing améliorés.

VI - Téléchargements

Les sources du projet.