00001
import java.io.*;
00002
import java.text.*;
00003
import java.awt.font.*;
00004
import java.awt.*;
00005
import javax.swing.*;
00006
import java.awt.event.*;
00007
import java.awt.geom.*;
00008
import java.awt.print.*;
00009
import javax.swing.text.*;
00010
00011 public class PrintableText implements Printable {
00012 AttributedString
text;
00013
00014 public PrintableText(String _text, Font font) {
00015
text =
new AttributedString(_text);
00016
if (_text.length()>0)
00017
text.addAttribute(TextAttribute.FONT, font);
00018 }
00019
00020 public PrintableText(AttributedString _text) {
00021
text = _text;
00022 }
00023
00024 public int print(Graphics g, PageFormat format,
int page) {
00025 Graphics2D g2 = (Graphics2D)g;
00026
00027
if (
printPage(g2,page,
00028 format.getImageableX(),format.getImageableY(),
00029 format.getImageableWidth(),format.getImageableHeight()))
00030
return PAGE_EXISTS;
00031
else
00032
return NO_SUCH_PAGE;
00033 }
00034
00035 int currentPage;
00036 boolean endOfDocument;
00037 TextLayout
lineLayout;
00038 int paragraph;
00039 CharacterIterator
paragraphIterator;
00040 LineBreakMeasurer
lineBreak;
00041
00042 int prev_currentPage = -1;
00043 boolean prev_endOfDocument;
00044 TextLayout
prev_lineLayout;
00045 int prev_paragraph;
00046 CharacterIterator
prev_paragraphIterator;
00047 int totalPageNum = -1;
00048 LineBreakMeasurer
prev_lineBreak;
00049 int prev_lineBreakPos;
00050
00051 class Previewer {
00052 int previewPage = 0;
00053 PageFormat
previewFormat;
00054 JPanel
sheet;
00055 JTextField
pageNum;
00056 JLabel
totalPageNumField;
00057 JFrame
frame;
00058 JButton
prev,
next,
first,
last;
00059
00060 void checkPage() {
00061
if (
previewPage<0)
previewPage = 0;
00062
if (totalPageNum!=-1 &&
previewPage>=totalPageNum)
previewPage = totalPageNum-1;
00063
pageNum.setText(Integer.toString(
previewPage+1));
00064
if (totalPageNum!=-1) {
00065
totalPageNumField.setText(
" of "+Integer.toString(totalPageNum));
00066
totalPageNumField.setVisible(
true); }
00067
prev.setEnabled(
previewPage>0);
00068
next.setEnabled(totalPageNum==-1 ||
previewPage<totalPageNum-1);
00069
first.setEnabled(
previewPage>0);
00070
last.setEnabled(totalPageNum==-1 ||
previewPage<totalPageNum-1);
00071
pageNum.setEnabled(totalPageNum!=0 && totalPageNum!=1);
00072
sheet.repaint();
00073 }
00074
00075 Previewer(JFrame _frame, PageFormat format) {
00076
frame = _frame;
00077
previewFormat = format;
00078
sheet =
new JPanel() {
00079
public void paintComponent(Graphics g) {
00080 Graphics2D g2 = (Graphics2D)g;
00081 Color oldColor = g2.getColor();
00082 g2.setColor(Color.white);
00083 g2.fillRect(0,0,
00084 (
int)
previewFormat.getWidth(),
00085 (
int)
previewFormat.getHeight());
00086 g2.setColor(oldColor);
00087
int oldTotalPageNum = totalPageNum;
00088
if (
previewPage<0 || !printPage(g2,
previewPage,
00089
previewFormat.getImageableX(),
00090
previewFormat.getImageableY(),
00091
previewFormat.getImageableWidth(),
00092
previewFormat.getImageableHeight())) {
00093 g2.setColor(Color.gray);
00094 Rectangle r = g2.getClipBounds();
00095 g2.fillRect(r.x,r.y,r.width,r.height);
00096 g2.setColor(oldColor);
00097 }
00098
if (oldTotalPageNum!=totalPageNum)
checkPage();
00099 }};
00100 Dimension sheetSize =
00101
new Dimension((
int)format.getWidth(),(
int)format.getHeight());
00102
sheet.setPreferredSize(sheetSize);
00103 JPanel buttons =
new JPanel();
00104
frame.getContentPane().add(
"Center",
sheet);
00105
frame.getContentPane().add(
"South",buttons);
00106
first =
new JButton(
"<<");
00107
first.setEnabled(
false);
00108
first.addActionListener(
new ActionListener() {
00109
public void actionPerformed(ActionEvent e) {
00110
previewPage = 0;
00111
checkPage();
00112 }});
00113
prev =
new JButton(
"<");
00114
prev.setEnabled(
false);
00115
prev.addActionListener(
new ActionListener() {
00116
public void actionPerformed(ActionEvent e) {
00117 previewPage--;
00118
checkPage();
00119 }});
00120
next =
new JButton(
">");
00121
next.addActionListener(
new ActionListener() {
00122
public void actionPerformed(ActionEvent e) {
00123 previewPage++;
00124
checkPage();
00125 }});
00126
last =
new JButton(
">>");
00127
last.addActionListener(
new ActionListener() {
00128
public void actionPerformed(ActionEvent e) {
00129
if (totalPageNum!=-1) previewPage=totalPageNum-1;
00130
else previewPage += 1000000;
00131
checkPage();
00132 }});
00133
pageNum =
new JTextField(3);
00134
pageNum.setText(
"1");
00135
pageNum.addActionListener(
new ActionListener() {
00136
public void actionPerformed(ActionEvent e) {
00137
try {
00138 System.out.println(
"PN "+
pageNum.getText());
00139 previewPage = Integer.parseInt(
pageNum.getText())-1;
00140 }
catch (NumberFormatException ex) {};
00141
checkPage();
00142 }});
00143 pageNum.setMaximumSize(pageNum.getPreferredSize());
00144 pageNum.setMinimumSize(pageNum.getPreferredSize());
00145 totalPageNumField =
new JLabel(
" of ??");
00146
00147
00148
00149 frame.addKeyListener(
new KeyListener() {
00150
public void keyTyped(KeyEvent e) {};
00151
public void keyPressed(KeyEvent e) {};
00152
public void keyReleased (KeyEvent e) {
00153
switch (e.getKeyCode()) {
00154
case KeyEvent.VK_PAGE_DOWN:
00155 previewPage++; checkPage();
break;
00156
case KeyEvent.VK_PAGE_UP:
00157 previewPage--; checkPage();
break;
00158
case KeyEvent.VK_HOME:
00159 previewPage=0; checkPage();
break;
00160
case KeyEvent.VK_END:
00161
if (totalPageNum!=-1) previewPage=totalPageNum-1;
00162
else previewPage += 100000000;
00163 checkPage();
break;
00164
case KeyEvent.VK_ESCAPE:
00165 frame.setVisible(
false);
break;
00166 }}});
00167
00168 buttons.add(first);
00169 buttons.add(prev);
00170
00171 buttons.add(Box.createHorizontalStrut((
int)(pageNum.getPreferredSize().getWidth()/2)));
00172
00173 buttons.add(pageNum);
00174 buttons.add(totalPageNumField);
00175
00176 buttons.add(Box.createHorizontalStrut((
int)(pageNum.getPreferredSize().getWidth()/2)));
00177
00178 buttons.add(next);
00179 buttons.add(last);
00180
00181 frame.pack();
00182 frame.setState(Frame.NORMAL);
00183 frame.setVisible(
true);
00184 }
00185 }
00186
00187
00188
00189
00190
00191
00192 public JFrame showPreview(JFrame frame, PageFormat format) {
00193
if (frame==null)
00194 frame =
new JFrame(
"Print preview");
00195
else
00196 frame.getContentPane().removeAll();
00197
new Previewer(frame,format);
00198
return frame;
00199 }
00200
00201
00202 public boolean printPage(Graphics2D gfx,
int page,
00203
double x0,
double y0,
00204
double width,
double height) {
00205
if (page<0)
00206
throw new IllegalArgumentException(
"page = "+page+
" < 0");
00207
if (prev_currentPage==page) {
00208 currentPage = prev_currentPage;
00209 endOfDocument = prev_endOfDocument;
00210 lineLayout = prev_lineLayout;
00211 paragraph = prev_paragraph;
00212
if (prev_paragraphIterator!=null)
00213 paragraphIterator = (CharacterIterator)prev_paragraphIterator.clone();
00214
else
00215 paragraphIterator = null;
00216 lineBreak = prev_lineBreak;
00217
if (lineBreak!=null) lineBreak.setPosition(prev_lineBreakPos);
00218 }
else {
00219 prev_currentPage = currentPage;
00220 prev_endOfDocument = endOfDocument;
00221 prev_lineLayout = lineLayout;
00222 prev_paragraph = paragraph;
00223
if (paragraphIterator!=null)
00224 prev_paragraphIterator = (CharacterIterator)paragraphIterator.clone();
00225
else
00226 prev_paragraphIterator = null;
00227 prev_lineBreak = lineBreak;
00228
if (prev_lineBreak!=null) prev_lineBreakPos = prev_lineBreak.getPosition();
00229 }
00230
if (currentPage>page || paragraphIterator==null) {
00231 paragraphIterator = text.getIterator();
00232 paragraph = 0;
00233 currentPage = 0; endOfDocument =
false;
00234 lineLayout = null; lineBreak = null;
00235 }
00236
if (endOfDocument)
return false;
00237
boolean pageEmpty =
true;
00238
while (currentPage<=page) {
00239
double x = x0, y = y0;
00240
while (
true) {
00241
if (lineLayout==null) {
00242
if (lineBreak==null) {
00243
int start = paragraph;
00244
00245
if (paragraphIterator.current()==CharacterIterator.DONE) {
00246 endOfDocument =
true; currentPage++;
00247 totalPageNum = pageEmpty?(currentPage-1):currentPage;
00248
return !pageEmpty && currentPage-1==page; };
00249
while (
true) {
00250
char c = paragraphIterator.current();
00251
00252 paragraph++;
00253
if (paragraphIterator.next()==CharacterIterator.DONE)
break;
00254
int t = Character.getType(c);
00255
if (t==Character.LINE_SEPARATOR ||
00256 t==Character.PARAGRAPH_SEPARATOR || c==
'\n')
break;
00257 }
00258
00259 lineBreak =
new LineBreakMeasurer
00260 (text.getIterator(null,start,paragraph),
00261 gfx.getFontRenderContext());
00262
00263 }
00264
00265 lineLayout = lineBreak.nextLayout((
float)width);
00266
00267
if (lineLayout==null) {
00268 lineBreak = null;
continue; }
00269 }
00270
00271 y += lineLayout.getAscent();
00272
00273
if (!pageEmpty && y+lineLayout.getDescent() > height)
break;
00274
00275
double dx = lineLayout.isLeftToRight()?0:
00276 (width-lineLayout.getAdvance());
00277
if (currentPage==page)
00278 lineLayout.draw(gfx,(
float)(x+dx),(
float)y);
00279 y += lineLayout.getDescent()+lineLayout.getLeading();
00280 lineLayout = null;
00281
00282 pageEmpty =
false;
00283 }
00284 currentPage++;
00285 }
00286
return true;
00287 }
00288 }