JFrame 文本打印

  1 package tools;
  2 
  3 import java.awt.BorderLayout;
  4 import java.awt.Color;
  5 import java.awt.Font;
  6 import java.awt.Graphics;
  7 import java.awt.Graphics2D;
  8 import java.awt.event.ActionEvent;
  9 import java.awt.event.ActionListener;
 10 import java.awt.event.KeyEvent;
 11 import java.awt.print.PageFormat;
 12 import java.awt.print.Printable;
 13 import java.awt.print.PrinterException;
 14 import java.awt.print.PrinterJob;
 15 
 16 import javax.swing.JButton;
 17 import javax.swing.JFrame;
 18 import javax.swing.JOptionPane;
 19 import javax.swing.JPanel;
 20 import javax.swing.JScrollPane;
 21 import javax.swing.JTextArea;
 22 
 23 import comm.SysProperties;
 24 
 25 public class PrintTxt extends JFrame implements Printable, ActionListener {
 26     /**
 27      * 实现功能:调打印机打印文本内容
 28      */
 29     private static final long serialVersionUID = 1L;// 序列化
 30     private JButton printTextButton = new JButton("print txt");// 实例化打印文本按钮
 31     private JPanel buttonPanel = new JPanel();// 一般轻量级容器,存放页面按钮等组件
 32     private JTextArea area = new JTextArea();// 显示纯文本的多行区域。它作为一个轻量级组件
 33     private JScrollPane scroll = new JScrollPane(area);// 轻量级组件的 scrollable 视图
 34 
 35     private int PAGES = 0;// 打印总页
 36     private String printStr;
 37 
 38     public PrintTxt() {// 初始化显示窗口
 39         JFrame.setDefaultLookAndFeelDecorated(true);// 新创建的窗体设置一个默认外观显示
 40         this.setSize(SysProperties.SCREEN_WIDTH, SysProperties.SCREEN_HEIGHT);// 設置窗口大小
 41         this.setDefaultCloseOperation(EXIT_ON_CLOSE);// 设置点击关闭时退出
 42         initLayout();// 界面上添加需要的組件
 43         this.setLocationRelativeTo(null);// 组件当前未显示,或者 c 为 null,则此窗口将置于屏幕的中央
 44         this.setVisible(true);
 45     }
 46 
 47     private void initLayout() {// 初始化界面组件
 48         printTextButton.addActionListener(this);
 49         printTextButton.setMnemonic(KeyEvent.VK_P);// 设置键盘上p键跟按钮绑定,Alt+p进行触发
 50         buttonPanel.add(printTextButton);// 将按钮添加到JPanel这个中间容器
 51         this.getContentPane().setLayout(new BorderLayout());// 设置内容面板为边框布局
 52         this.getContentPane().add(scroll, BorderLayout.CENTER);// 添加scroll组件到JFrame内容面板的中位置
 53         this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);// 添加buttonPanel按钮这个中间容器到JFrame内容面板的南位置
 54     }
 55 
 56     /**
 57      * 打印文本
 58      */
 59     private void printTextAction() {
 60         printStr = area.getText().trim();
 61         if (printStr != null && printStr.length() > 0) {
 62             PAGES = getPagesCount(printStr);
 63             PrinterJob prtJob = PrinterJob.getPrinterJob();// 创建并返回初始化时与默认打印机关联的PrinterJob
 64             PageFormat pageFormat = prtJob.defaultPage();// 创建新的 PageFormat实例,并将它设置为默认大小和方向
 65             prtJob.setPrintable(this, pageFormat);// 调用 painter,用指定的 format呈现该页面
 66             if (prtJob.printDialog()) {
 67                 try {
 68                     prtJob.print();
 69                 } catch (PrinterException e) {
 70                     // TODO Auto-generated catch block
 71                     e.printStackTrace();
 72                 }
 73             } else {
 74                 JOptionPane.showConfirmDialog(null,
 75                         "Sorry, Printer Job is Empty, Print Cancelled!",
 76                         "Empty", JOptionPane.DEFAULT_OPTION,
 77                         JOptionPane.WARNING_MESSAGE);
 78             }
 79         }
 80     }
 81 
 82     /**
 83      * 计算需要打印的页数
 84      * 
 85      * @param printStr
 86      * @return 打印页数
 87      */
 88     private int getPagesCount(String curStr) {
 89         int count = 0, page = 0, position = 0;
 90         while (curStr.length() > 0) {
 91             position = curStr.indexOf("\n");
 92             count++;// 记录行数
 93             if (position != -1) {
 94                 curStr = curStr.substring(position + 1);
 95             } else {
 96                 curStr = "";// 结束循环
 97             }
 98         }
 99 
100         if (count > 0 && count <= 10) {
101             page = 1;
102         } else {
103             page = count / 10 + 1;// 规定10行为一页,计算打印的页数
104         }
105         return page;
106     }
107 
108     public static void main(String[] args) {
109         new PrintTxt();
110     }
111 
112     /**
113      * 绘制字符串内容
114      * 
115      * @param g2
116      * @param pf
117      * @param page
118      */
119     private void drawCurrentPageText(Graphics2D g2, PageFormat pf, int page) {
120         // TODO Auto-generated method stub
121         Font f = area.getFont();// 从系统属性列表返回一个 Font 对象
122         String s = getDrawText(printStr)[page];// 获取打印值
123         String drawText;
124         float ascent = 16;
125         int k, i = f.getSize(), lines = 0;
126         while (s.length() > 0 && lines < 10) {
127             k = s.indexOf('\n');
128             if (k != -1) {
129                 lines++;
130                 drawText = s.substring(0, k);
131                 g2.drawString(drawText, 0, ascent);
132                 if (s.substring(k + 1).length() > 0) {
133                     s = s.substring(k + 1);
134                     ascent += i;
135                 }
136             } else {
137                 lines += 1;
138                 drawText = s;
139                 g2.drawString(drawText, 0, ascent);
140                 s = "";
141             }
142         }
143 
144     }
145 
146     /**
147      * 获取需要绘制的文本字符串数组
148      * 
149      * @param s
150      * @return
151      */
152     private String[] getDrawText(String s) {
153         String[] drawText = new String[PAGES];// 声明一个长度为总页数的的字符串数组
154         for (int i = 0; i < PAGES; i++)
155             drawText[i] = "";// 这段是拿来干嘛的??
156         int k, suffix = 0, lines = 0;
157         while (s.length() > 0) {
158             if (lines < 10) {
159                 k = s.indexOf('\n');// 记录是否换行
160                 if (k != -1) {
161                     ++lines;
162                     drawText[suffix] = drawText[suffix] + s.substring(0, k + 1);// ??拼接字符串
163                     if (s.substring(k + 1).length() > 0) {
164                         s = s.substring(k + 1);
165                     }
166                 } else {
167                     ++lines;
168                     drawText[suffix] = drawText[suffix] + s;
169                     s = "";
170                 }
171             } else {
172                 lines = 0;
173                 suffix++;
174             }
175         }
176         return drawText;
177 
178     }
179 
180     /**
181      * 用于接收操作事件的侦听器接口
182      * 
183      * @param e
184      */
185     @Override
186     public void actionPerformed(ActionEvent e) {
187         // TODO Auto-generated method stub
188         Object src = e.getSource();
189         if (src == printTextButton)
190             printTextAction();
191     }
192 
193     /**
194      * 覆写实现Printable接口的print方法
195      */
196     @Override
197     public int print(Graphics g, PageFormat pf, int page)
198             throws PrinterException {
199         // TODO Auto-generated method stub
200         Graphics2D g2 = (Graphics2D) g;// ?这两个类都是抽象类,声明的只是引用类型,为何可以调用方法
201         g2.setPaint(Color.black);// 设置颜色
202         if (page >= PAGES)
203             return Printable.NO_SUCH_PAGE;// 表示页面不存在,结束打印
204         g2.translate(pf.getImageableX(), pf.getImageableY());// 将 Graphics2D
205                                                                 // 上下文的原点平移到当前坐标系中的点
206                                                                 // (x, y)
207         drawCurrentPageText(g2, pf, page);208         return Printable.PAGE_EXISTS;
209     }
210 
211 }

 

posted on 2019-06-10 09:42  刀锋93  阅读(667)  评论(2编辑  收藏  举报

导航