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 }
来源:oschina
链接:https://my.oschina.net/u/4396922/blog/4253994