Class Document
Document order = Document.of(Paper.A4)
.marginsMm(18, 15, 18, 15)
.title("Order 4512")
.header(page -> new Label("ACME Distribution"))
.footer(page -> new Label(page.number() + " / " + page.count()))
.add(customerCard)
.add(itemsTable) // cut between rows, its header on every page
.keepTogether(totalsBox) // moved whole to the next page if it does not fit
.pageBreak()
.add(new DonutChart(byCategory));
order.writePdf(file).onSuccess(saved -> window.launcher().openFile(saved)).start();
order.print(window);
The widgets are the document's. An application builds them for the document, the same components it shows on screen, over the same data, and does not lend it widgets that are in a window: a widget belongs to one scene, and a document paints each block in a scene of its own that no window shows. In that scene nothing has focus, nothing is hovered, nothing scrolls, every animation is at its end, and the palette is the document's.
The page. A document unit is 1/96 inch, the convention a browser prints with: a body label of 13 units prints at 9.75 points. Every block takes the width of the content box (the paper less its margins) and as much height as it measures to; a block that does not fit in what is left of a page is cut where it can be cut (between the lines of a label, between the children of a column or the rows of a grid, between the rows of a list, a table or a tree), or moved whole to the next page, or, taller than a page and with nowhere to cut, sliced at the page's height. A list, a table or a tree is cut between rows only as a block of its own: every row is printed, a page's worth realized at a time, and a table's header is on every page. Inside another block it prints the box it measures to.
The smallest content box. What the margins, the header and the footer leave of a page
is at least a quarter inch (24 units, 18 points) each way, room for a line of body text: a
document that leaves less, a letterhead and a disclaimer filling a small label, or the default
three-quarter-inch margins on paper less than an inch and three quarters across or down, is
refused with an
IllegalStateException that names the paper, the margins and the header's and the
footer's heights, when its pages are recorded. The header and the footer are measured then,
since they are made per page.
What a page holds that a PDF cannot. A soft shadow is a picture at the document's raster
resolution (rasterDpi, 300 by default), as is an icon; a backdrop effect is its tint; a
video or a 3D view is left out, with a warning.
UI thread only: a document holds widgets. Its pages are recorded on the UI thread when
writePdf(java.nio.file.Path) or print(limn.backend.NativeWindow) is called or a PrintPreview asks for them, and again
once a face the text asked for has loaded, or after ten seconds without it, with a warning; the
PDF's bytes are written on a worker. A document
can be written, printed and previewed any number of times; each
records its pages afresh, so what the widgets show at that moment is what is printed.
-
Method Summary
Modifier and TypeMethodDescriptionAdds a block: it takes the content box's width and the height it measures to, and is cut where it can be cut when it does not fit.Sets what is drawn at the foot of every page, asheaderdoes at its top.Sets what is drawn at the top of every page: a new widget for each page, made when the page is drawn, since a page's number is known only once the document is cut, and its count only once it is cut to the end.keepTogether(Widget<?> widget) Adds a block that is never cut: moved whole to the next page when it does not fit in what is left of a page, and sliced only when it is taller than a whole page.@Nullable Localelocale()Sets the locale the pages are laid out in, which also sets their direction and the PDF's language; by default the process's.marginsMm(float top, float right, float bottom, float left) Sets the margins, in millimetres.marginsPt(float top, float right, float bottom, float left) Sets the margins, in points (1/72 inch).static Documentof()static DocumentEnds the page: the next block begins a new one.intCuts the document into pages now and says how many there are.paper()print(NativeWindow window) Prints the document through the system's own print dialog, owned bywindow: the pages are recorded on the UI thread (again once a face the text asked for has loaded, or after ten seconds without it, with a warning), the PDF is written on a worker, and the window'sPrinterhands it to the system.intrasterDpi(int dpi) Sets the resolution of what is drawn as a picture: icons, soft shadows.Sets the palette the pages are painted with.title()Sets the title: the PDF's title and the name of the print job.writePdf(OutputStream out) Writes the document as a PDF to a stream, which is not closed.Writes the document as a PDF file.
-
Method Details
-
of
- Parameters:
paper- the paper every page is laid out on- Returns:
- an empty document, with margins of three quarters of an inch
-
of
- Returns:
- an empty document on the paper of the default locale's region (
Paper.forLocale(java.util.Locale))
-
marginsMm
Sets the margins, in millimetres.- Returns:
- this document
-
marginsPt
Sets the margins, in points (1/72 inch).- Returns:
- this document
-
title
Sets the title: the PDF's title and the name of the print job.- Parameters:
title- never blank- Returns:
- this document
-
header
Sets what is drawn at the top of every page: a new widget for each page, made when the page is drawn, since a page's number is known only once the document is cut, and its count only once it is cut to the end. The tallest of them is the room every page keeps for it: the document is cut again each time the count makes one taller, up to three times, and one taller still after that is drawn in the room the last cut kept, cut at its foot, with a warning; the content never runs under it.- Parameters:
header- makes a page's header, or null for none- Returns:
- this document
-
theme
Sets the palette the pages are painted with. By default it is the light palette of the process's palette family (Theme.light()forTheme.dark(),Theme.limnLight()forTheme.limn(), andTheme.light()for any other dark palette): paper is white, and a dark page spends its toner on the background.- Parameters:
theme- the palette, or null for the default- Returns:
- this document
-
locale
Sets the locale the pages are laid out in, which also sets their direction and the PDF's language; by default the process's.- Parameters:
locale- the locale, or null for the process's- Returns:
- this document
-
rasterDpi
Sets the resolution of what is drawn as a picture: icons, soft shadows.- Parameters:
dpi- dots per inch, from 72 to 1200; 300 by default- Returns:
- this document
-
add
Adds a block: it takes the content box's width and the height it measures to, and is cut where it can be cut when it does not fit.- Parameters:
widget- a widget made for the document, in no window and in no other document- Returns:
- this document
-
keepTogether
Adds a block that is never cut: moved whole to the next page when it does not fit in what is left of a page, and sliced only when it is taller than a whole page.- Parameters:
widget- a widget made for the document- Returns:
- this document
-
pageBreak
Ends the page: the next block begins a new one.- Returns:
- this document
-
paper
- Returns:
- the paper
-
title
- Returns:
- the title
-
locale
- Returns:
- the locale, or null for the process's
-
rasterDpi
public int rasterDpi()- Returns:
- the raster resolution, in dots per inch
-
pageCount
public int pageCount()Cuts the document into pages now and says how many there are.- Returns:
- the number of pages, at least 1
- Throws:
IllegalStateException- if the margins, the header and the footer leave a content box smaller than a quarter inch either way (the class says why)
-
writePdf
Writes the document as a PDF file. The pages are recorded now, on the UI thread, and recorded again once the work runs if a face the text asked for was still loading (a script's fallback face, loaded in the background on its first need), as soon as it has loaded or after ten seconds without it, with a warning; the file is written by the work on a worker, first to a temporary file besidefileand then moved over it, so a failed or cancelled write leaves no half file.document.writePdf(file) .onProgress(fraction -> bar.setProgress((float) fraction)) .onSuccess(saved -> window.launcher().showInFolder(saved)) .onFailure(error -> status.setText(error.getMessage())) .start();- Parameters:
file- where to write it- Returns:
- the work, not started; its value is
file - Throws:
IllegalStateException- if the margins, the header and the footer leave a content box smaller than a quarter inch either way (the class says why); thrown here, as the pages are recorded, before any work exists
-
writePdf
Writes the document as a PDF to a stream, which is not closed. The pages are recorded now, and again once the work runs if a face was still loading, aswritePdf(Path)says; the bytes are written by the work on a worker.- Parameters:
out- where to write it- Returns:
- the work, not started
- Throws:
IllegalStateException- aswritePdf(Path)does
-
print
Prints the document through the system's own print dialog, owned bywindow: the pages are recorded on the UI thread (again once a face the text asked for has loaded, or after ten seconds without it, with a warning), the PDF is written on a worker, and the window'sPrinterhands it to the system. The dialog chooses the printer and may save the job as PDF where the system offers it; it scales a page to other paper, never re-flowing it.Pages that cannot be recorded, a content box smaller than a quarter inch among them (the class says why), show no dialog: the answer is
PrintResult.FAILED, and theIllegalStateExceptionis logged as a warning.- Parameters:
window- the window that owns the dialog- Returns:
- what became of it, completed on the UI thread
-