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 }