pdfrender实现简易版pdf阅读器-支持鼠标拖动浏览

基于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。

你可能感兴趣的:(java)