基于pdfrender实现简易版pdf阅读器,支持鼠标上下拖动实现翻页和滚动条支持看了代码就知道其中的奥妙
PDFComponent类:
import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFRenderer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
/**
* pdf显示component
* @author yy
*/
public class PDFComponent extends JScrollPane {
private static final long serialVersionUID = 1L;
// byte array containing the PDF file content
//当前文件字符数组
private byte[] bytes = null;
//文件名称
private String fileName;
//每页高度(当前高度会根据当前窗体大小计算相对高度)
private double pageHeight;
//页面总高度(画布)
private double totalHeight;
//当前pdf文件
private PDFFile pdfFile;
//当前所查看的页数
private int index = 0;
/**
* y轴上一个值,鼠标按下时触发,鼠标释放时设置为0
*/
private int preY = 0;
/**
* pdf组件
*/
private JPanel pdfPanel;
public PDFComponent() {
pdfPanel = new JPanel(){
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//绘制当前页和下一页,避免滑动到两页中间位置出现文档显示不全问题(这样也解决了当文档太大时加载整个文档所消耗不必要的时间)
draw(g, index);
draw(g, index+1);
}
};
initComponents();
}
public PDFComponent(String fileName) {
this();
this.fileName = fileName;
readFile();
}
/**
* 初始化组件
*/
private void initComponents(){
this.setViewportView(pdfPanel);
//添加滚动事件
this.getVerticalScrollBar().addAdjustmentListener((e)->{
int value = e.getValue();
PDFComponent.this.setIndex((int) (value / PDFComponent.this.getPageHeight() + 1));
PDFComponent.this.repaint();
});
pdfPanel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
preY = e.getYOnScreen();
}
@Override
public void mouseReleased(MouseEvent e) {
preY = 0;
}
});
pdfPanel.addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
if(preY == 0){//正常情况不会执行到当前方法快
preY = e.getYOnScreen();
return;
}
int currentY = e.getYOnScreen();
int tmpY = getVerticalScrollBar().getValue();
//如果拖动上一个值和当前值相等就直接返回
if(currentY == preY){
return;
}
if( currentY > preY){
tmpY -= 50;
}else if(currentY < preY){
tmpY += 50;
}
getVerticalScrollBar().setValue(tmpY);
preY = currentY;
}
});
}
/**
* 读取当前文件
*/
public void readFile() {
try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(fileName));) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int b;
while ((b = inputStream.read()) != -1) {
outputStream.write(b);
}
this.bytes = outputStream.toByteArray();
pdfFile = new PDFFile(ByteBuffer.wrap(this.bytes));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 改变当前component高度
*/
public void changeHeight(){
totalHeight = pageHeight * pdfFile.getNumPages();
Dimension dimension = this.getSize();
dimension.setSize(dimension.getWidth(), totalHeight);
pdfPanel.setMinimumSize(dimension);
pdfPanel.setPreferredSize(dimension);
pdfPanel.setMaximumSize(dimension);
pdfPanel.setSize(dimension);
}
/**
* 绘制指定页数
* @param g
* @param pageIndex 页码
*/
public void draw(Graphics g, int pageIndex) {
/**
* 如果当前文件或绘制下标超过pdf页数就不绘制
*/
if(pdfFile == null || pageIndex > pdfFile.getNumPages()){
return;
}
PDFPage page = pdfFile.getPage(pageIndex);
Paper paper = new Paper();
int formatOrientation = page.getAspectRatio() > 1 ? PageFormat.LANDSCAPE
: PageFormat.PORTRAIT;
if (formatOrientation == PageFormat.LANDSCAPE) {
paper.setSize(page.getHeight(), page.getWidth());
} else {
paper.setSize(page.getWidth(), page.getHeight());
}
PageFormat pageFormat = new PageFormat();
pageFormat.setPaper(paper);
pageFormat.setOrientation(formatOrientation);
Graphics2D g2d = (Graphics2D) g.create();
//计算界面宽度与文档宽度的比例
double tmp = this.getSize().getWidth() / page.getWidth();
//重新计算高度(避免pdf变形)
pageHeight = pageFormat.getHeight() * tmp;
//重新设置panel高度
changeHeight();
//绘制到指定位置
Rectangle imgbounds = new Rectangle(0, (int)((pageIndex - 1) * pageHeight), (int)this.getSize().getWidth(),
(int)pageHeight);
PDFRenderer renderer = new PDFRenderer(page, g2d, imgbounds, null, Color.WHITE);
try {
page.waitForFinish();
} catch (InterruptedException e) {
// some exception handling
e.printStackTrace();
}
renderer.run();
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public double getPageHeight() {
return pageHeight;
}
public void setIndex(int index) {
this.index = index;
}
}
MyJFrame:
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
/**
* @author Administrator
*/
public class MyJFrame extends javax.swing.JFrame {
private int num = 1;
/**
* Creates new form MyJFrame
*/
public MyJFrame() {
initComponents();
pDFComponent1.setFileName("C:\\Users\\Administrator\\Desktop\\*.pdf");
pDFComponent1.readFile();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// //GEN-BEGIN:initComponents
private void initComponents() {
pDFComponent1 = new PDFComponent();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(806, 518));
getContentPane().add(pDFComponent1, java.awt.BorderLayout.CENTER);
pack();
}// //GEN-END:initComponents
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(MyJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(MyJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(MyJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(MyJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MyJFrame().setVisible(true);
}
});
}
}
jar包就自己download(可直接在maven repository下载),我用的是:
pdfrenderer-0.9.1-patched.jar。