Package limn.print

Class PrintPreview


public final class PrintPreview extends Widget<PrintPreview>
A document's pages as sheets on a neutral background, before they are printed or saved: what a business application shows under "Print preview".

 PrintPreview preview = new PrintPreview(order);
 dialogBody.add(preview);                 // with the application's own Print and Paper buttons
 preview.setZoom(PrintPreview.Zoom.FIT_WIDTH);
 

It shows the document's own recording, the one its PDF is written from, so what it shows is what the file and the printer get. The pages scroll as a column, one sheet under the next, at a zoom that fits a whole page, fits the width, or is a percentage of the paper's real size. It is the toolkit's and the same on every system, because only one of the three systems' print dialogs previews an application's pages.

The user zooms it as a document viewer is zoomed: a pinch on a trackpad, or the wheel with Command held on macOS and Control elsewhere (Control on macOS too), around the point under the pointer (MouseEvent.Type.ZOOM), and, with the preview focused, Command or Control with + or = to zoom in, - to zoom out and 0 for the paper's real size. A zoom the user made is a PrintPreview.Zoom.PERCENT one and is announced as a Change.Aspect.VALUE change of the user's, which a toolbar showing the zoom watches. Focused, the arrows, Page Up, Page Down, Home and End scroll the pages.

A reader hears a group named "Print preview", described by the page in the middle of the view and the count ("Page 3 of 12"); the pages' own text is not published to it.

The pages are recorded when the preview is made and again by refresh(); a face the text asked for that was still loading records them again once it has loaded, or after ten seconds without it, with a warning. A recording made again that fails, when nobody is in a call to hear it, leaves the pages recorded before on show, and failure() says why. UI thread only.

  • Constructor Details

    • PrintPreview

      public PrintPreview(Document document)
      Parameters:
      document - the document to show; its pages are recorded now
      Throws:
      IllegalStateException - if the document's margins, header and footer leave a content box smaller than a quarter inch either way (Document says why)
  • Method Details

    • refresh

      public PrintPreview refresh()
      Records the document's pages again and shows them: after the application changed what its widgets show, or the document's paper.
      Returns:
      this preview
      Throws:
      IllegalStateException - as the constructor does, for what the document's widgets show now
    • failure

      public @Nullable RuntimeException failure()
      Why the pages shown are not the document's last recording, or null when they are.

      A face the text asked for that was still loading records the pages again once it has loaded, after the constructor or refresh() has returned, so no caller is there to hear a throw. That recording can fail where the first did not: a header or a footer that measures taller in the face that loaded can leave less than the quarter inch Document requires. The preview then keeps showing the pages recorded before the face loaded, logs a warning, answers the exception here, and announces a Change.Aspect.VALIDITY change, which a dialog around it watches to say that the document cannot be printed as it is. The next recording that succeeds clears it, with another such change.

      Returns:
      the IllegalStateException the recording made again threw (or what wraps any other failure), or null
    • pageCount

      public int pageCount()
      Returns:
      how many pages the document has, as last recorded
    • currentPage

      public int currentPage()
      Returns:
      the page in the middle of the view, from 1
    • showPage

      public PrintPreview showPage(int number)
      Scrolls a page's top into the view.
      Parameters:
      number - the page, from 1; clamped to the document's pages
      Returns:
      this preview
    • setZoom

      public PrintPreview setZoom(PrintPreview.Zoom zoom)
      Parameters:
      zoom - how the sheets are sized; PrintPreview.Zoom.PERCENT uses the last percentage set
      Returns:
      this preview
    • zoom

      public PrintPreview.Zoom zoom()
      Returns:
      how the sheets are sized
    • setZoomPercent

      public PrintPreview setZoomPercent(float percent)
      Sizes the sheets at a percentage of the paper's real size, on a screen of 96 dots per inch at 100 %, and sets the zoom to PrintPreview.Zoom.PERCENT.
      Parameters:
      percent - from 10 to 800
      Returns:
      this preview
    • zoomPercent

      public float zoomPercent()
      Returns:
      the size the sheets are shown at, as a percentage of the paper's real size on a 96-dpi screen, whichever the zoom: what a fitting zoom comes to at the view's size
    • onKeyEvent

      protected void onKeyEvent(KeyEvent event)
      Description copied from class: Widget
      Key events (focused widget first, then ancestors).
      Overrides:
      onKeyEvent in class Widget<PrintPreview>
    • onFocusGained

      protected void onFocusGained()
      Description copied from class: Widget
      Called when this widget takes keyboard focus. Default: nothing.
      Overrides:
      onFocusGained in class Widget<PrintPreview>
    • onFocusLost

      protected void onFocusLost()
      Description copied from class: Widget
      Called when this widget loses keyboard focus. Default: nothing.
      Overrides:
      onFocusLost in class Widget<PrintPreview>
    • onMeasure

      protected Size onMeasure(Constraints constraints)
      Description copied from class: Widget
      Reports the size this widget wants within constraints. Called once per layout pass, and the result is cached against the constraints and the resolved axes (size step, layout direction, locale), so it must be a pure function of them and of this widget's own state.

      Resolve the ControlSize and the LayoutDirection once each here and thread them down; never read either in a constructor. The locale needs no threading: it is in scope, and I18n.locale() answers it wherever text is resolved.

      Specified by:
      onMeasure in class Widget<PrintPreview>
    • onLayout

      protected void onLayout()
      Description copied from class: Widget
      Containers position children here (measure + Widget.layoutBox(float, float, float, float) per child).
      Overrides:
      onLayout in class Widget<PrintPreview>
    • onPaintOverlay

      protected void onPaintOverlay(Canvas canvas)
      Description copied from class: Widget
      Painted after children (scrollbars, focus rings…).
      Overrides:
      onPaintOverlay in class Widget<PrintPreview>
    • onAccessibility

      protected void onAccessibility(Accessibility a)
      Description copied from class: Widget
      Says what this widget is, for an assistive technology.

      Called on the UI thread inside the publish step, with this widget's own locale in scope, and never from a paint. A widget that overrides nothing still gets a node with its bounds, its enabled, focusable, visible and showing states, its language, its children in tree order, the focus and scroll-into-view verbs when it is focusable, and its tooltip as a name when nothing else supplied one. What it does not get is a role: a widget that declares no role, no name, no description, no state, no verb and no facet is scaffolding, and the tree removes it and hoists its children in its place, so that a screen reader hears the controls rather than the boxes.

      Nothing here may allocate. The builder's setters take a facet's fields rather than a facet, and a name is handed over as the localizable string this widget holds rather than as a resolved one, so that a frame which damaged this widget and changed nothing about it costs a comparison and no memory at all. Accessibility states the two rules and what breaks when they are ignored.

      Overrides:
      onAccessibility in class Widget<PrintPreview>
      Parameters:
      a - the node being described; write into it, and never keep it