/* * Copyright 2014 Jocki Hendry * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package simple.escp.swing; import simple.escp.data.DataSource; import simple.escp.dom.PageFormat; import simple.escp.fill.FillJob; import simple.escp.SimpleEscp; import simple.escp.Template; import simple.escp.data.DataSources; import javax.print.PrintService; import javax.print.PrintServiceLookup; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToolBar; import javax.swing.JViewport; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Map; import java.util.Vector; /** * Use <code>PrintPreviewPane</code> to display string generated by simple-escp's <code>Template</code>. * The panel includes a print button and printer selection (by name). * * <p>Because some configurations for text mode printing is stored in printer's RAM and can't be read using * ESC/P commands, <code>PrintPreviewPane</code> will not attempt to create an exact print preview. * All characters is printed using the same monospace font and ESC/P commands are ignored. You must also * specificy the page length and page width for print preview. These values is used for previewing only and * will not affect printing. * */ public class PrintPreviewPane extends JPanel implements ActionListener { public static final int DEFAULT_PAGE_LENGTH = 50; public static final int DEFAULT_PAGE_WIDTH = 80; private String text; private JScrollPane scrollPane; private OutputPane outputPane; private JToolBar toolbar; private JButton printButton; private JComboBox<String> printerNameComboBox; /** * Create a new instance of this class. */ public PrintPreviewPane() { outputPane = new OutputPane(); MouseHandler mouseHandler = new MouseHandler(); outputPane.addMouseListener(mouseHandler); outputPane.addMouseMotionListener(mouseHandler); scrollPane = new JScrollPane(outputPane); toolbar = new JToolBar(); printButton = new JButton("Print"); printButton.addActionListener(this); PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null); Vector<String> printerName = new Vector<>(); printerName.add(PrintServiceLookup.lookupDefaultPrintService().getName()); for (PrintService printService: printServices) { if (!printerName.contains(printService.getName())) { printerName.add(printService.getName()); } } printerNameComboBox = new JComboBox<>(printerName); toolbar.add(printerNameComboBox); toolbar.add(printButton); setLayout(new BorderLayout()); add(toolbar, BorderLayout.PAGE_START); add(scrollPane, BorderLayout.CENTER); } /** * Create a new instance of <code>PrintPreviewPane</code> based on a <code>Template</code> and its * value (a <code>Map</code> and/or an object). Template <strong>must</strong> have a valid value * for <code>pageLength</code> and <code>pageWidth</code> in its <code>pageFormat</code>. * * @param template an instance of <code>Template</code>. * @param mapValue to fill placholders in the <code>Template</code>. * @param objectValue to fill placeholders in the <code>Template</code>. */ public PrintPreviewPane(Template template, Map mapValue, Object objectValue) { this(new FillJob(template.parse(), DataSources.from(mapValue, objectValue)).fill(), template.getPageFormat().getPageLength(), template.getPageFormat().getPageWidth()); } /** * Create a new instance of <code>PrintPreviewPane</code>. You must specify page size for previewing. * This page size <strong>doesn't</strong> affect print result. Page size parameters only affect * preview panel. If you use the different paper size in the printer, the result will be different. * * @param text the string that will be displayed. * @param pageLength page length in number of lines. * @param pageWidth page width in number of characters. */ public PrintPreviewPane(String text, int pageLength, int pageWidth) { this(); display(text, pageLength, pageWidth); } /** * Set the data that will be displayed by this <code>PrintPreviewPane</code> and display it. * * @param text the string that will be displayed. * @param pageLength page length in number of lines. * @param pageWidth page width in number of characters. */ public void display(String text, int pageLength, int pageWidth) { this.text = text; outputPane.display(text, pageLength, pageWidth); scrollPane.revalidate(); } /** * Set the data that will be displayed by this <code>PrintPreviewPane</code> and display it. * * @param text the string that will be displayed. * @param pageFormat the page format that contains information about this report. */ private void display(String text, PageFormat pageFormat) { this.text = text; int pageLength = DEFAULT_PAGE_LENGTH; if (pageFormat.getPageLength() != null) { pageLength = pageFormat.getPageLength(); } int pageWidth = DEFAULT_PAGE_WIDTH; if (pageFormat.getPageWidth() != null) { pageWidth = pageFormat.getPageWidth(); } outputPane.display(text, pageLength, pageWidth); scrollPane.revalidate(); } /** * Set the data that will be displayed by this <code>PrintPreviewPane</code> and display it. * * @param template an instance of <code>Template</code>. * @param dataSource the data source to fill this template. */ public void display(Template template, DataSource dataSource) { PageFormat pageFormat = template.getPageFormat(); display(new FillJob(template.parse(), dataSource).fill(), pageFormat); } /** * Set the data that will be displayed by this <code>PrintPreviewPane</code> and display it. * * @param template an instance of <code>Template</code>. * @param dataSources the data source to fill this template. */ public void display(Template template, DataSource[] dataSources) { PageFormat pageFormat = template.getPageFormat(); display(new FillJob(template.parse(), dataSources).fill(), pageFormat); } /** * Handler for print button. * * @param e <code>ActionEvent</code>. */ @Override public void actionPerformed(ActionEvent e) { if (printerNameComboBox.getSelectedIndex() < 0) { JOptionPane.showMessageDialog(this, "You must select a printer.", "Warning", JOptionPane.WARNING_MESSAGE); return; } new SimpleEscp((String) printerNameComboBox.getSelectedItem()).print(text); } /** * Handler for mouse related events in <code>scrollPane</code>. */ private class MouseHandler extends MouseAdapter { private int x, y; @Override public void mousePressed(MouseEvent e) { x = e.getX(); y = e.getY(); scrollPane.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); } @Override public void mouseReleased(MouseEvent e) { scrollPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } @Override public void mouseDragged(MouseEvent e) { JViewport viewport = scrollPane.getViewport(); Point point = viewport.getViewPosition(); int newX = point.x - (e.getX() - x); int maxX = outputPane.getWidth() - viewport.getWidth(); int newY = point.y - (e.getY() - y); int maxY = outputPane.getHeight() - viewport.getHeight(); if (newX < 0) { newX = 0; } if (newX > maxX) { newX = maxX; } if (newY < 0) { newY = 0; } if (newY > maxY) { newY = maxY; } viewport.setViewPosition(new Point(newX, newY)); } } }