swing 实现PDF封面设计--可拖动横向,纵向文本

    最近用swing做了个工具,实现TXT到PDF的格式转换,其中有个功能是“封面设计器”,当然要求也不是很高,就是可以添加背景图片,可以添加横向和纵向的文本,文本字体可自定义,并且文本位置可拖动定位。

    完成思路:

         1.封面背景图片重写JPanel的paintComponent方法。

         2.封面中文本使用JLabel组件,纵向增加<html>标签<br>换行

         3.JLabel组件拖动使用MouseListener中的mouseDragged和mousePressed方法

         4.由于swingJPanel中坐标是在左上角视为0,0,而pdf是左下为00,所以需要坐标转换。

         5.PDF页面大小和背景图片大小可能不同,所以要以JLabel文本相对于页面的宽高比例去定位PDF的坐标

         6.字体转换,swing字体转换为PDF字体,PDF采用加载本地TrueType 字体文件 (.ttf)的形式生成字体

         7.PDF用itext生成(PdfContentByte)

 

   效果图:

                
swing 实现PDF封面设计--可拖动横向,纵向文本_第1张图片
  

 PDF效果图:


swing 实现PDF封面设计--可拖动横向,纵向文本_第2张图片
 

核心代码:

  1.封面背景:

     此部分代码来源于网络:

 @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        
        //如果设置了背景图片则显示
        if(backgroundImage != null)
        {
            int width = this.getWidth();
            int height = this.getHeight();
            int imageWidth = backgroundImage.getWidth(this);
            int imageHeight = backgroundImage.getHeight(this);

            switch(modeIndex)
            {
                //居中
                case 0:
                {
                    int x = (width - imageWidth) / 2;
                    int y = (height - imageHeight) / 2;
                    g.drawImage(backgroundImage, x, y, this);
                    break;
                }
                //平铺
                case 1:
                {
                    for(int ix = 0; ix < width; ix += imageWidth)
                    {
                        for(int iy = 0; iy < height; iy += imageHeight)
                        {
                            g.drawImage(backgroundImage, ix, iy, this);
                        }
                    }
                    break;
                }
                //拉伸
                case 2:
                {
                    g.drawImage(backgroundImage, 0, 0, width, height, this);
                    break;
                }
            }
        }
    }

 配合:backgroundImage.getScaledInstance(width, height, hints);来控制图片显示大小

 

2.JLabel纵向文本,JLabel大小自动适应

 

//设置纵向JLabel文本
private String setHtmlLabel(String text) {
        if (text == null) {
            return "";
        }
        String str="<html>";
        char[] arr = text.toCharArray();
        for (char c : arr) {
            str=str+c+"<br>";
        }
        //System.out.println(str);
        return str;
    }
//设置JLable大小写    
private void setVerticalLabelSize(JLabel label, java.awt.Font font) {
        String text = label.getText();
        if (text == null) {
            return;
        }
        text=text.replaceAll("<html>","").replaceAll("<br>","");
        FontMetrics fm = this.getFontMetrics(font);
        int w = fm.stringWidth("位");
        int y = text.toCharArray().length * (font.getSize()+font.getSize()/4);
        label.setSize(w, y);
       // System.out.println(text+"--"+y+"--"+font.getSize());
    }

 3.JLabel拖动功能,来源于网络

 

//拖动监听器
class DragListener extends MouseInputAdapter {
        private JLabel dragComponet;
        /** 坐标点 */
        Point point = new Point(0, 0);

        public DragListener(JLabel dragComponet) {
            this.dragComponet = dragComponet;
        }
        /**
         * 当鼠标拖动时触发该事件。 记录下鼠标按下(开始拖动)的位置。
         */
        public void mouseDragged(MouseEvent e) {
            // 转换坐标系统
            Point newPoint = SwingUtilities.convertPoint(dragComponet, e.getPoint(), dragComponet.getParent());
            // System.out.println(newPoint.x + " : " + newPoint.y);
            // 设置标签的新位置
            dragComponet.setLocation(dragComponet.getX()
                    + (newPoint.x - point.x), dragComponet.getY()
                    + (newPoint.y - point.y));
            // 更改坐标点
            point = newPoint;
        }

        /**
         * 当鼠标按下时触发该事件。 记录下鼠标按下(开始拖动)的位置。
         */
        public void mousePressed(MouseEvent e) {
            // 得到当前坐标点
            point = SwingUtilities.convertPoint(dragComponet, e.getPoint(),
                    dragComponet.getParent());
            //System.out.println(e.getPoint().x + " : " + e.getPoint().y);
            //System.out.println(point.x + " : " + point.y);
        }
    }

//添加监听
 DragListener titleDragListener = new DragListener(titleLabel);
  titleLabel.addMouseListener(titleDragListener);
   titleLabel.addMouseMotionListener(titleDragListener);

5.获取swing字体对应的TrueType 字体文件 (.ttf)路径

 

    /**
     * 获取系统字体对应全路径Map
     * @return 
     */
    public static Map<String, String> getFontPathMap() {
        if (fontPathMap == null) {
            fontPathMap = new HashMap<String, String>();
            GraphicsEnvironment eq = GraphicsEnvironment.getLocalGraphicsEnvironment();
            //设置字体路径
            java.awt.Font[] fs = eq.getAllFonts();
            if (fs != null) {
                for (java.awt.Font f : fs) {
                    //获取TrueType 字体文件 (.ttf)路径
                    String fontFilePath = FontManager.getFontPath(true) + File.separator + FontManager.getFileNameForFontName(f.getFontName());
                    fontPathMap.put(f.getFontName(), fontFilePath);
                }
            }
        }
        return fontPathMap;
    }

 /*
     * 根据swing字体生成PDF字体
     */
    public static BaseFont getPdfBaseFont(java.awt.Font swingFont) {
        String fontPath = getFontPathMap().get(swingFont.getFontName());
        String defaultFontName = "STSong-Light";
        String defaultEcoding = "UniGB-UCS2-H";
        if (StringUtil.isNotBlank(fontPath)) {
            if (fontPath.toLowerCase().endsWith(".ttf")) {
                defaultFontName = fontPath;
                defaultEcoding = BaseFont.IDENTITY_H;
            }
            //字体集
            if (fontPath.toLowerCase().endsWith(".ttc")) {
                defaultFontName = fontPath + ",1";//指定字体集中的第一个字体
                defaultEcoding = BaseFont.IDENTITY_H;
            }

        }
        BaseFont bBaseFont = null;
        try {
            bBaseFont = BaseFont.createFont(defaultFontName, defaultEcoding, false);
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return bBaseFont;
    }
 

6.完成后封装成对象,使用itext生成PDF封面

 

 

import java.awt.Font;
import java.awt.Point;

/**
 *封面显示文本类
 * @author changxian
 */
public class CoverShowTextBean {
    private String text;//文本内容
    private Font font;//文本字体
    private Point point;//文本位置(暂无用)
    private double x_percent;//文本位置X相对图片宽度百分比
    private double y_percent;//文本位置Y相对图片高度百分比
    public static int MODEL_HORIZONTAL=0;
    public static int MODEL_VERTICAL=1;
    private int model=MODEL_HORIZONTAL;
    

    public CoverShowTextBean(String text, Font font, Point point,int model) {
        this.text = text;
        this.font = font;
        this.point = point;
        this.model=model;
    }
    
    public CoverShowTextBean(String text, Font font, Point point) {
        this(text,font,point,MODEL_HORIZONTAL);
    }

    public CoverShowTextBean() {
    } 
    
    public Font getFont() {
        return font;
    }

    public void setFont(Font font) {
        this.font = font;
    }

    public Point getPoint() {
        return point;
    }

    public void setPoint(Point point) {
        this.point = point;
    } 

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
    
    public double getX(){
        if(point!=null){
            return point.getX();
        }
        return -1d;
    }
    public double getY(){
         if(point!=null){
            return point.getY();
        }
        return -1d;
    }
    /**
     * 获取横坐标占页面宽度的百分比<=1,point.x/wallpaper_width
     * @return double
     */
    public double getX_percent() {
        return x_percent;
    }

    public void setX_percent(double x_percent) {
        this.x_percent = x_percent;
    }
    /**
     * 获取纵坐标占页面高度的百分比<=1,point.y/wallpaper_height
     * @return double
     */
    public double getY_percent() {
        return y_percent;
    }

    public void setY_percent(double y_percent) {
        this.y_percent = y_percent;
    }
    
  
    public void setXPercent(double wallpaper_width){
        this.setX_percent(getX()/wallpaper_width);
    }
    
  
    public void setYPercent(double wallpaper_height){
        this.setY_percent(getY()/wallpaper_height);
    }
    
    public void setPositionPercent(double wallpaper_width,double wallpaper_height){
        setXPercent(wallpaper_width);
        setYPercent(wallpaper_height);
    }

    public int getModel() {
        return model;
    }

    public void setModel(int model) {
        this.model = model;
    }
    
}
 
import java.util.ArrayList;
import java.util.List;

/**
 *封面类
 * @author changxian
 */
public class Cover { 
    private String imgPath;
    private List<CoverShowTextBean> showTextList=new ArrayList<CoverShowTextBean>();
    private boolean show;

    public boolean isShow() {
        return show;
    }

    public void setShow(boolean show) {
        this.show = show;
    }

    public String getImgPath() {
        return imgPath;
    }
    public void setImgPath(String imgPath) {
        this.imgPath = imgPath;
    }

    public List<CoverShowTextBean> getShowTextList() {
        return showTextList;
    }

    public void setShowTextList(List<CoverShowTextBean> showTextList) {
        this.showTextList = showTextList;
    }
        
}

   生成PDF封面:

/**
     * 生成封面
     * @param writer
     * @param doc
     * @param cover
     * @throws IOException
     * @throws DocumentException 
     */
    public void setCover(PdfWriter writer, Document doc, Cover cover) throws IOException, DocumentException {
        float doc_height = doc.getPageSize().getHeight();
        float doc_width = doc.getPageSize().getWidth();
        //封面
        Image tImgCover = Image.getInstance(cover.getImgPath());
        /* 设置图片的位置 */
        tImgCover.setAbsolutePosition(0, 0);
        /* 设置图片的大小 */
        tImgCover.scaleAbsolute(doc_width, doc_height);
        doc.add(tImgCover);//加载图片 
        PdfContentByte cb = writer.getDirectContent();
        List<CoverShowTextBean> showTextList = cover.getShowTextList();
        if (showTextList != null && !showTextList.isEmpty()) {
            for (CoverShowTextBean show : showTextList) {
                Double t_x = doc_width * show.getX_percent();
                Double t_y = doc_height * show.getY_percent();
                BaseFont bf = CommonUtil.getPdfBaseFont(show.getFont());
                if (show.getModel() == CoverShowTextBean.MODEL_HORIZONTAL) {//横向文本
                    cb.beginText();
                    cb.setFontAndSize(bf, show.getFont().getSize());
                    //cb.showTextAligned(PdfContentByte.ALIGN_LEFT,cover.getTitle(), t_x.intValue(),doc_height-t_y.intValue(), 0);
                    //cb.setTextMatrix(doc_width, doc_width, doc_width, doc_width, doc_width, doc_width);
                    //System.err.println("X=" + t_x.intValue() + "--Y=" + (doc_height - t_y.intValue()));
                    cb.setTextMatrix(t_x.intValue(), doc_height - t_y.intValue() - show.getFont().getSize());
                    cb.showText(show.getText());
                    cb.endText();
                } else {//纵向
                    String text = CommonUtil.removeHtmlSymbol(show.getText());
                    char[] textArr = text.toCharArray();
                    int j=show.getFont().getSize();
                    for (char c : textArr) {
                        cb.beginText();
                        cb.setFontAndSize(bf, show.getFont().getSize());
                        cb.setTextMatrix(t_x.intValue(),doc_height - t_y.intValue() - j);
                        cb.showText(c+"");
                        j = j + show.getFont().getSize();
                        cb.endText();
                    }

                }
            }
        }
        doc.add(new Paragraph(" "));
        doc.newPage();
    }
 

 

你可能感兴趣的:(swing,itext,pdf封面,可拖动)