1 package de.lathanda.eos.common.gui;
4 import java.awt.Dimension;
6 import java.awt.FontMetrics;
7 import java.awt.Graphics;
8 import java.awt.geom.Rectangle2D;
9 import java.awt.print.PageFormat;
10 import java.awt.print.Pageable;
11 import java.awt.print.Paper;
12 import java.awt.print.Printable;
13 import java.awt.print.PrinterException;
14 import java.awt.print.PrinterJob;
15 import java.util.ArrayList;
16 import java.util.LinkedList;
17 import javax.swing.JOptionPane;
19 import de.lathanda.eos.baseparser.AbstractProgram;
20 import de.lathanda.eos.baseparser.Format;
21 import de.lathanda.eos.baseparser.InfoToken;
29 public class PrintPanel extends javax.swing.JPanel implements Printable, Pageable {
34 private static final long serialVersionUID = -6226144081255555607L;
35 private PageFormat pageFormat;
36 private int pageIndex = 0;
37 private boolean linenumbers =
false;
40 private final ArrayList<LinkedList<PrintPart>> pages =
new ArrayList<>();
42 private final Font fontLiteral =
new Font(
"monospaced", Font.PLAIN, 12);
43 private final Font fontComment = fontLiteral.deriveFont(Font.ITALIC);
44 private final Font fontKeyword = fontLiteral.deriveFont(Font.BOLD);
45 private final Font fontLinenumber = fontLiteral;
46 private final Font fontHeader =
new Font(
"sans", Font.PLAIN, 10);
47 private final Font fontFooter =
new Font(
"sans", Font.PLAIN, 8);
48 private final static String TAB =
" ";
49 private static final double PAPER_BORDER_X = 56.69;
50 private static final double PAPER_BORDER_Y = 28.34;
51 private String header =
"";
58 if (PrinterJob.lookupPrintServices().length > 0) {
59 PrinterJob job = PrinterJob.getPrinterJob();
60 pageFormat = job.defaultPage();
62 pageFormat =
new PageFormat();
64 }
catch (Throwable t) {
65 JOptionPane.showMessageDialog(
this,
Messages.
getString(
"Print.Error.Title"), t.getLocalizedMessage(),
66 JOptionPane.ERROR_MESSAGE);
67 pageFormat =
new PageFormat();
70 Paper paper = pageFormat.getPaper();
71 paper.setImageableArea(PAPER_BORDER_X, PAPER_BORDER_Y, paper.getWidth() - 2 * PAPER_BORDER_X,
72 paper.getHeight() - 2 * PAPER_BORDER_Y);
73 pageFormat.setPaper(paper);
75 setBackground(Color.WHITE);
76 setPreferredSize(
new Dimension(400, 300));
81 super.paintComponent(g);
83 print(g, pageFormat, pageIndex);
84 }
catch (PrinterException ex) {
85 JOptionPane.showMessageDialog(
this,
Messages.
getString(
"Print.Error.Title"), ex.getLocalizedMessage(),
86 JOptionPane.ERROR_MESSAGE);
91 public int print(Graphics graphics, PageFormat pageFormat,
int pageIndex)
throws PrinterException {
92 this.pageFormat = pageFormat;
93 if (pageIndex < 0 || pageIndex >= pages.size()) {
97 pages.get(pageIndex).stream().forEachOrdered(t -> t.print(graphics));
102 void previousPage() {
103 pageIndex = (pageIndex - 1 + pages.size()) % pages.size();
108 pageIndex = (pageIndex + 1) % pages.size();
113 linenumbers = visible;
118 this.header = header;
119 parse(getGraphics());
123 this.program = abstractProgram;
124 this.header = header;
125 parse(getGraphics());
128 private void parse(Graphics g) {
129 LinkedList<PrintPart> page =
new LinkedList<>();
136 double lineheight = g.getFontMetrics(fontLiteral).getHeight() * 1.0;
137 double lineNrOffset = g.getFontMetrics(fontLinenumber).stringWidth(
"XX: ");
138 double headerHeight = lineheight;
139 double footerHeight = lineheight;
142 double y = g.getFontMetrics(fontLiteral).getHeight();
145 double linewidth = pageFormat.getImageableWidth() - lineNrOffset;
146 double pageheight = pageFormat.getImageableHeight() - headerHeight - footerHeight;
147 double offsetX = pageFormat.getImageableX() + lineNrOffset;
148 double offsetY = pageFormat.getImageableY() + headerHeight;
150 if (program ==
null) {
158 if (st.getFormat() == Format.IGNORE)
160 String token = source.substring(sourceIndex, st.getBegin() + st.getLength());
163 boolean realline =
true;
164 while (tokenIndexBegin < token.length()) {
168 Rectangle2D r =
null;
169 tokenIndexEnd = token.indexOf(
'\n', tokenIndexBegin);
170 if (tokenIndexEnd != -1) {
174 Text linenr =
new Text(linenumber +
": ", fontLinenumber, Color.BLACK,
true);
175 Rectangle2D bounds = linenr.getMetrics(g);
176 linenr.move(offsetX - bounds.getWidth(), offsetY + y);
180 tokenIndexEnd = token.length();
184 boolean fitting =
false;
190 part = token.substring(tokenIndexBegin, tokenIndexEnd);
191 switch (st.getFormat()) {
193 text =
new Text(part, fontComment,
new Color(0, 160, 0),
false);
196 text =
new Text(part, fontLiteral, Color.BLACK,
false);
199 text =
new Text(part, fontKeyword, Color.BLACK,
false);
202 text =
new Text(part, fontLiteral, Color.BLACK,
false);
204 r = text.getMetrics(g);
205 if (fitting || r.getWidth() >= linewidth) {
206 if (x + r.getWidth() > linewidth) {
218 tokenIndexBegin = tokenIndexEnd + skip;
219 if (x + r.getWidth() > linewidth) {
222 if (y > pageheight) {
223 y = g.getFontMetrics(fontLiteral).getHeight();
224 page =
new LinkedList<>();
228 text.move(offsetX + x, offsetY + y);
235 if (y > pageheight) {
236 y = g.getFontMetrics(fontLiteral).getHeight();
237 page =
new LinkedList<>();
242 sourceIndex = st.getBegin() + st.getLength();
246 Text linenr =
new Text(linenumber +
": ", fontLinenumber, Color.BLACK,
true);
247 Rectangle2D bounds = linenr.getMetrics(g);
248 linenr.move(offsetX - bounds.getWidth(), offsetY + y);
252 Text headerText =
new Text(header, fontHeader, Color.BLACK,
false);
253 headerText.move(offsetX + (linewidth - headerText.getMetrics(g).getWidth()) / 2, offsetY - 1);
254 Line headerLine =
new Line(Color.BLACK, offsetX, offsetY, offsetX + linewidth, offsetY);
255 Line footerLine =
new Line(Color.BLACK, offsetX, offsetY + pageheight, offsetX + linewidth,
256 offsetY + pageheight);
258 for (LinkedList<PrintPart> p : pages) {
259 Text footerText =
new Text(pageNr +
"/" + pages.size(), fontFooter, Color.BLACK,
false);
260 footerText.move(offsetX + (linewidth - footerText.getMetrics(g).getWidth()) / 2,
261 offsetY + pageheight + footerHeight);
272 return new Dimension((
int) pageFormat.getWidth(), (
int) pageFormat.getHeight());
281 public PageFormat
getPageFormat(
int pageIndex)
throws IndexOutOfBoundsException {
286 public Printable
getPrintable(
int pageIndex)
throws IndexOutOfBoundsException {
290 private static interface PrintPart {
291 public void print(Graphics g);
294 private class Text
implements PrintPart {
296 private final String text;
297 private final Font font;
298 private final Color color;
301 private boolean linenumber;
303 public Text(String text, Font font, Color color,
boolean linenumber) {
304 this.text = text.replace(
"\t", TAB);
307 this.linenumber = linenumber;
310 public void move(
double x,
double y) {
315 public void print(Graphics g) {
316 if (!linenumber || linenumbers) {
319 g.drawString(text, x, y);
323 public Rectangle2D getMetrics(Graphics g) {
324 FontMetrics fm = g.getFontMetrics(font);
325 return fm.getStringBounds(text, g);
329 private static class Line
implements PrintPart {
330 private final Color color;
336 public Line(Color color,
double x1,
double y1,
double x2,
double y2) {
344 public void print(Graphics g) {
346 g.drawLine(x1, y1, x2, y2);
static String getString(String id)
Printable getPrintable(int pageIndex)
void paintComponent(Graphics g)
void setHeader(String header)
void setLinenumberVisible(boolean visible)
int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
Dimension getPreferredSize()
PageFormat getPageFormat(int pageIndex)
LinkedList< InfoToken > getTokenList()