1. 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 peux voir sur Mac OS X lorsque l'on ouvre un dossier contenant des fichiers PDF.

2. 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 peux 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 cet 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 finallement 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, certains peuvent ne pas être rendues correctement.
3. Seconde Etape : 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 notre. Nous avons donc créer 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 pui un ensemble de lignes pour faire une pseudo-reliure. L'appel à la méthode createSpiralBinding() est fait depuis notre méthode getImageFromPdf()
createSpiralBinding
(
GraphicsUtilities.createThumbnail
(
result, newSize));
3. Etape finale : mixer le tout▲
L'utilisation du 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 peux exécuter le tout pour voir le résultat.
4. Aller plus loin▲
SwingX Painters sur DeveloperLife qui m'as inspiré pour écrire cet article.
Le site du prjet PDFRenderer ou on trouvera les sources du projets ainsi que des exemples.
SwingLabs qui met à disposition un ensemble de composants Swing améliorés.
5. Téléchargements▲
Les sources du projet.