15 grudnia
14:58 2007
Parę dni temu ujawniono wielki sekret(tm). Chodzi nową i darmową (licencja LGPL) bibliotekę służącą do renderowania plików PDF - PDF Renderer. Pomimo tego, że sama biblioteka jest jeszcze w dość wczesnej (?) fazie rozwoju, to działa bardzo dobrze i szybko ;)
Więc jak użyć to API, żeby wyświetlić plik PDF w Swingu?
Podstawowe klasy, które użyjemy w naszym przykładzie to:
com.sun.pdfview.PDFFile- reprezentuje plik PDFcom.sun.pdfview.PDFPage- reprezentuje pojedynczą stronę w pliku PDFcom.sun.pdfview.PagePanel- komponent w którym wyświetlana jest strona
Najpierw otwieramy plik PDF. OK, na razie API nie jest najładniejsze, ale pewnie wkrótce to poprawią ;)
RandomAccessFile raf = new RandomAccessFile("jakiśplik.pdf", "r");
FileChannel fc = raf.getChannel();
file = new PDFFile(fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()));
Po otwarciu pliku można wczytać np. 1 stronę:
PDFPage page = file.getPage(1); panel.showPage(page);
Kompletny program
- Kompilacja:
javac -cp PDFRenderer.jar:. PDF.java - Uruchomienie:
java -cp PDFRenderer.jar:. PDF jakiśplik.pdf - Plik
PDFRenderer.jarjest na stronie PDF Renderer - Spacja - następna strona, Backspace - poprzednia, Z - zoom po zaznaczeniu myszą
import com.sun.pdfview.*;
import java.awt.event.*;
import java.io.*;
import java.nio.channels.FileChannel;
import javax.swing.*;
public class PDF extends JFrame {
boolean zoom;
int currentPage = 1;
PagePanel panel;
PDFFile file;
PDF(String[] args) {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(800, 600);
setLocationRelativeTo(null); // center on screen
panel = new PagePanel();
panel.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_SPACE:
navigate(currentPage + 1);
break;
case KeyEvent.VK_BACK_SPACE:
navigate(currentPage - 1);
break;
case KeyEvent.VK_Z:
zoom = !zoom;
panel.useZoomTool(zoom);
if (!zoom)
panel.setClip(null);
break;
}
}
} );
add(panel);
setVisible(true);
try {
RandomAccessFile raf = new RandomAccessFile(args[0], "r");
FileChannel fc = raf.getChannel();
file = new PDFFile(fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()));
navigate(1);
}
catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "Error: " + e.getMessage());
}
}
void navigate(int pageNumber) {
if (pageNumber < 1 || pageNumber > file.getNumPages())
return;
PDFPage page = file.getPage(pageNumber);
panel.showPage(page);
currentPage = pageNumber;
setTitle(currentPage + "/" + file.getNumPages());
}
public static void main(final String[] args) {
if (args.length != 1) {
JOptionPane.showMessageDialog(null, "Usage: PDF ");
return;
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new PDF(args);
}
} );
}
}
PS. Na stronie projektu można również uruchomić dużo bardziej funkcjonalne "viewer demo".
Proszę o komentarz
Zajebioza. Może skonwertują to na C#, to wtedy użyję to w swoim projekcie.
Problem się pojawia jak okno JDialog jest modalne – PagePanel przestaje działać ...
fajne, ale ja potrzebuje by dalo sie zaznaczac tekst, zeby stwierdzic czy pdf jest OCRowany czy nie. Do tego lepsza jest biblioteka jPedal, choc jest troche kaprysna
Osobiście użyłem tej biblioteki do Oracle Forms 10g jako Beana Javovego. Zamieszczony program bardzo się przydał i działa naprawdę nice. Jeśli chodzi o używanie jPedal to są z tą biblioteką spore problemy. Próbowałem na początku zaimplementować mojego beana właśnie z wykorzystaniem jPedal i owa bibliotego nie potrafiła poradzić sobie z polskimi czcionkami w plikach PDF co gorsza dla PDF'ów bez zagnieżdżonych fontów nie działało wcale. Pozdrawiam