/*
* Copyright (c) 1997-2024 IDRsolutions (https://www.idrsolutions.com)
*/
package org.jpedal.examples.viewer.gui.popups;
import org.jpedal.PdfDecoder;
import org.jpedal.PdfDecoderInt;
import org.jpedal.display.Display;
import org.jpedal.examples.viewer.gui.SwingGUI;
import org.jpedal.examples.viewer.paper.MarginPaper;
import org.jpedal.examples.viewer.paper.PaperSizes;
import org.jpedal.exception.PdfException;
import org.jpedal.io.ColorSpaceConvertor;
import org.jpedal.objects.PrinterOptions;
import org.jpedal.utils.LogWriter;
import org.jpedal.utils.Messages;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.SetOfIntegerSyntax;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrinterResolution;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.awt.print.Paper;
import java.text.NumberFormat;
import java.util.ArrayList;
public class PrintPanel extends javax.swing.JPanel {
private int pageCount;
private int currentPage;
private int currentPreviewedPage = 1;
private boolean okClicked;
private String[] printersList;
private final PaperSizes paperDefinitions;
private int defaultResolution;
private static final double mmPerSubInch = 25.4 / 72;
private final PdfDecoderInt pdf;
/**
* Creates a panel to display the various printing options available in the Viewer
*
* @param printersList String array listing the available printers names
* @param defaultPrinter String value representing the default printer option
* @param paperDefinitions Papersizes object containing details for all supported paper sizes
* @param defaultResolution int value representing the default resolution for printing
* @param pageNumber int value representing the page currently displayed
* @param decoder PdfDecoderInt object representing the PDF file that is currently open
*/
public PrintPanel(final String[] printersList, final String defaultPrinter, final PaperSizes paperDefinitions, final int defaultResolution, final int pageNumber, final PdfDecoderInt decoder) {
pdf = decoder;
pageCount = pdf.getPageCount();
currentPage = pageNumber;
this.defaultResolution = defaultResolution;
this.paperDefinitions = paperDefinitions;
this.printersList = printersList;
initComponents(defaultPrinter);
}
/**
* Reset the default values of the print panel to those provided
*
* @param printersList String array listing the available printers names
* @param defaultPrinter String value representing the default printer option
* @param pageCount int value representing total number of pages in the document
* @param currentPage int value representing the page currently displayed
*/
public void resetDefaults(final String[] printersList, final String defaultPrinter, final int pageCount, final int currentPage) {
this.printersList = printersList;
this.pageCount = pageCount;
this.currentPage = currentPage;
if (pageSize.getItemCount() == 0) {
return;
}
resetRangeTab();
printHandlingCopies.setValue(1);
if (defaultPrinter != null && !defaultPrinter.isEmpty()) {
printerName.setSelectedItem(defaultPrinter);
}
printerName.setModel(new javax.swing.DefaultComboBoxModel<>(printersList));
tabbedPane.setSelectedIndex(0);
}
private void resetRangeTab() {
pagesFrom.setText("1");
pagesTo.setText(String.valueOf(pageCount));
printRangeAll.setSelected(true);
printRangeSubset.setSelectedIndex(0);
printRangeReversePages.setSelected(false);
}
/**
* This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">
@SuppressWarnings({"OverlyLongMethod", "java:S138"})
private void initComponents(final String startingPrinter) {
buttonGroup1 = new javax.swing.ButtonGroup();
printerPanel = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
tabbedPane = new javax.swing.JTabbedPane();
printerName = new javax.swing.JComboBox<>();
pageSize = new javax.swing.JComboBox<>();
jLabel10 = new JLabel();
jLabel11 = new javax.swing.JLabel();
jLabel12 = new javax.swing.JLabel();
jLabel13 = new javax.swing.JLabel();
jLabel14 = new javax.swing.JLabel();
jLabel15 = new javax.swing.JLabel();
left = new javax.swing.JSpinner();
right = new javax.swing.JSpinner();
top = new javax.swing.JSpinner();
bottom = new javax.swing.JSpinner();
resolution = new javax.swing.JComboBox<>();
printRangePanel = new javax.swing.JPanel();
pagesFrom = new javax.swing.JTextField();
printRangeCurrentPage = new javax.swing.JRadioButton();
printRangeAll = new javax.swing.JRadioButton();
printRangeCurrentView = new javax.swing.JRadioButton();
printRangeFrom = new javax.swing.JRadioButton();
jLabel4 = new javax.swing.JLabel();
printRangeSubset = new javax.swing.JComboBox<>();
printRangeReversePages = new javax.swing.JCheckBox();
jLabel7 = new javax.swing.JLabel();
pagesTo = new javax.swing.JTextField();
pageHandlingPanel = new javax.swing.JPanel();
final JPanel previewPanel = new JPanel();
previewComponent = new javax.swing.JComponent() {
@Override
public void paintComponent(final Graphics g) {
printPreview((Graphics2D) g);
}
};
previewSlider = new CustomSlider();
jLabel8 = new javax.swing.JLabel();
printHandlingCopies = new javax.swing.JSpinner();
jLabel9 = new javax.swing.JLabel();
printHandlingScaling = new javax.swing.JComboBox<>();
autoRotateCenter = new javax.swing.JCheckBox();
paperSourceByPDF = new javax.swing.JCheckBox();
grayscale = new javax.swing.JCheckBox();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
nameElements();
setLayout(null);
add(tabbedPane);
tabbedPane.setBounds(10, 7, 400, 339);
createPrinterPanel(startingPrinter);
createPrintRangePanel();
createPageHandlingPanel();
//START Preview PANEL
previewPanel.setLayout(null);
previewPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null,
Messages.getMessage("PdfViewerLabel.PrintPreview"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION,
javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", Font.PLAIN, 11)));
previewPanel.add(previewComponent);
previewComponent.setBounds(5, 5, 220, 275);
previewPanel.add(previewSlider);
previewSlider.setBounds(5, 280, 220, 40);
previewSlider.resetValue();
updatePreview();
add(previewPanel);
previewPanel.setBounds(420, 7, 230, 330);
//END Preview PANEL
okButton.setText(Messages.getMessage("PdfMessage.Ok"));
okButton.addActionListener(evt -> okEvent());
add(okButton);
okButton.setBounds(445, 348, 90, 23);
cancelButton.setText(Messages.getMessage("PdfMessage.Cancel"));
cancelButton.addActionListener(evt -> cancelEvent());
add(cancelButton);
cancelButton.setBounds(560, 348, 90, 23);
} // </editor-fold>
private void createPageHandlingPanel() {
//START Page Handling PANEL
pageHandlingPanel.setLayout(new GridBagLayout());
final GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
jLabel8.setText(Messages.getMessage("PdfViewerPrint.Copies"));
pageHandlingPanel.add(jLabel8, setGridBagConstraints(gbc, 0, 0, 1));
printHandlingCopies.setModel(new SpinnerNumberModel(1, 1, 1_000, 1));
gbc.fill = GridBagConstraints.VERTICAL;
gbc.insets = new Insets(0, 0, 0, 0);
gbc.anchor = GridBagConstraints.WEST;
printHandlingCopies.setMinimumSize(new Dimension(65, 22));
printHandlingCopies.setPreferredSize(new Dimension(65, 22));
pageHandlingPanel.add(printHandlingCopies, setGridBagConstraints(gbc, 1, 0, 1));
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.CENTER;
gbc.insets = new Insets(5, 5, 5, 5);
jLabel9.setText(Messages.getMessage("PdfViewerPrint.PageScaling"));
pageHandlingPanel.add(jLabel9, setGridBagConstraints(gbc, 0, 1, 1));
printHandlingScaling.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{
Messages.getMessage("PdfViewerPrint.NoScaling"),
Messages.getMessage("PdfViewerPrint.FitToPrinterMargins"),
Messages.getMessage("PdfViewerPrint.ReduceToPrinterMargins")}));
printHandlingScaling.setSelectedIndex(PrinterOptions.LAST_SCALING_CHOICE);
gbc.insets = new Insets(5, 0, 5, 0);
pageHandlingPanel.add(printHandlingScaling, setGridBagConstraints(gbc, 1, 1, 1));
gbc.insets = new Insets(5, 5, 5, 5);
printHandlingScaling.addItemListener(e -> updatePreview());
autoRotateCenter.setSelected(true);
autoRotateCenter.setText((Messages.getMessage("PdfViewerPrint.AutoRotateAndCenter")));
autoRotateCenter.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
autoRotateCenter.setMargin(new java.awt.Insets(0, 0, 0, 0));
pageHandlingPanel.add(autoRotateCenter, setGridBagConstraints(gbc, 0, 2, 2));
autoRotateCenter.addItemListener(e -> updatePreview());
paperSourceByPDF.setText(Messages.getMessage("PdfViewerPrint.ChoosePaperByPdfSize"));
paperSourceByPDF.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
paperSourceByPDF.setMargin(new java.awt.Insets(0, 0, 0, 0));
pageHandlingPanel.add(paperSourceByPDF, setGridBagConstraints(gbc, 0, 3, 2));
paperSourceByPDF.addItemListener(e -> updatePreview());
grayscale.setText(Messages.getMessage("PdfViewerPrint.Grayscale"));
grayscale.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
pageHandlingPanel.add(grayscale, setGridBagConstraints(gbc, 0, 4, 2));
grayscale.setMargin(new java.awt.Insets(0, 0, 0, 0));
grayscale.addItemListener(e -> updatePreview());
tabbedPane.addTab(Messages.getMessage("PdfViewerPrintTab.handling"), pageHandlingPanel);
//END Page Handling PANEL
}
private void createPrintRangePanel() {
//START Print Range PANEL
printRangePanel.setLayout(new GridBagLayout());
setUpRangeSettings();
addRangeOptionsToPanel();
tabbedPane.addTab(Messages.getMessage("PdfViewerPrintTab.range"), printRangePanel);
//END Print Range PANEL
}
private void setUpRangeSettings() {
pagesFrom.setText("1");
pagesFrom.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mousePressed(final java.awt.event.MouseEvent evt) {
pagesBoxPressed();
}
});
pagesFrom.setMinimumSize(new Dimension(65, 22));
pagesFrom.setPreferredSize(new Dimension(65, 22));
jLabel7.setText(Messages.getMessage("PdfViewerPrint.PagesTo"));
pagesTo.setText(String.valueOf(pageCount));
pagesTo.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mousePressed(final java.awt.event.MouseEvent evt) {
pagesBoxPressed();
}
});
pagesTo.setMinimumSize(new Dimension(65, 22));
pagesTo.setPreferredSize(new Dimension(65, 22));
printRangeReversePages.setText(Messages.getMessage("PdfViewerPrint.ReversePages"));
printRangeReversePages.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
printRangeReversePages.setMargin(new java.awt.Insets(0, 0, 0, 0));
printRangeReversePages.addItemListener(e -> updatePreview());
jLabel4.setText(Messages.getMessage("PdfViewerPrint.Subset"));
printRangeSubset.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{
Messages.getMessage("PdfViewerPrint.AllPagesInRange"), Messages.getMessage("PdfViewerPrint.OddPagesOnly"),
Messages.getMessage("PdfViewerPrint.EvenPagesOnly")}));
printRangeSubset.addItemListener(e -> updatePreview());
printRangeCurrentPage.setText(Messages.getMessage("PdfViewerRadioButton.CurrentPage"));
printRangeCurrentPage.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
printRangeCurrentPage.setMargin(new java.awt.Insets(0, 0, 0, 0));
printRangeCurrentPage.setOpaque(false);
printRangeCurrentPage.addItemListener(evt -> currentPageStateChanged());
printRangeAll.setSelected(true);
printRangeAll.setText(Messages.getMessage("PdfViewerRadioButton.All"));
printRangeAll.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
printRangeAll.setMargin(new java.awt.Insets(0, 0, 0, 0));
printRangeAll.setOpaque(false);
printRangeAll.addItemListener(evt -> allStateChanged());
printRangeCurrentView.setText(Messages.getMessage("PdfViewerPrint.CurrentView"));
printRangeCurrentView.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
printRangeCurrentView.setEnabled(true);
printRangeCurrentView.setMargin(new java.awt.Insets(0, 0, 0, 0));
printRangeCurrentView.setOpaque(false);
//Disable in non single mode
if (pdf.getDisplayView() != Display.SINGLE_PAGE) {
printRangeCurrentView.setEnabled(false);
printRangeCurrentView.setToolTipText(Messages.getMessage("PageLayoutMessage.SinglePageOnly"));
} else {
printRangeCurrentView.setEnabled(true);
printRangeCurrentView.setToolTipText(null);
}
printRangeCurrentView.addItemListener(evt -> printRangeCurrentView());
printRangeFrom.setText(Messages.getMessage("PdfViewerPrint.PagesFrom"));
printRangeFrom.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
printRangeFrom.setMargin(new java.awt.Insets(0, 0, 0, 0));
printRangeFrom.setOpaque(false);
printRangeFrom.addItemListener(evt -> pagesFromStateChanged());
buttonGroup1.add(printRangeCurrentPage);
buttonGroup1.add(printRangeAll);
buttonGroup1.add(printRangeCurrentView);
buttonGroup1.add(printRangeFrom);
}
private void addRangeOptionsToPanel() {
final GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
printRangePanel.add(printRangeAll, setGridBagConstraints(gbc, 0, 0, 1));
printRangePanel.add(printRangeCurrentView, setGridBagConstraints(gbc, 0, 1, 1));
printRangePanel.add(printRangeCurrentPage, setGridBagConstraints(gbc, 0, 2, 1));
printRangePanel.add(printRangeFrom, setGridBagConstraints(gbc, 0, 3, 1));
printRangePanel.add(jLabel4, setGridBagConstraints(gbc, 0, 4, 1));
printRangePanel.add(printRangeReversePages, setGridBagConstraints(gbc, 0, 5, 3));
gbc.insets = new Insets(0, 0, 0, 0);
printRangePanel.add(pagesFrom, setGridBagConstraints(gbc, 1, 3, 1));
gbc.insets = new Insets(5, 0, 5, 0);
printRangePanel.add(printRangeSubset, setGridBagConstraints(gbc, 1, 4, 4));
gbc.insets = new Insets(5, 5, 5, 5);
printRangePanel.add(jLabel7, setGridBagConstraints(gbc, 2, 3, 1));
gbc.insets = new Insets(0, 0, 0, 0);
printRangePanel.add(pagesTo, setGridBagConstraints(gbc, 3, 3, 1));
}
private void createPrinterPanel(final String startingPrinter) {
//START Printer PANEL
printerPanel.setLayout(new GridBagLayout());
final GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(5, 5, 5, 5);
jLabel1.setText(Messages.getMessage("PdfViewerPrint.Name"));
printerPanel.add(jLabel1, setGridBagConstraints(gbc, 0, 0, 1));
jLabel2.setText(Messages.getMessage("PdfViewerPrint.PageSize"));
printerPanel.add(jLabel2, setGridBagConstraints(gbc, 0, 1, 1));
printerName.setModel(new javax.swing.DefaultComboBoxModel<>(printersList));
printerPanel.add(printerName, setGridBagConstraints(gbc, 1, 0, 5));
addPrinterChangeListener();
pageSize.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Loading..."}));
pageSize.setEnabled(false);
resolution.setModel(new javax.swing.DefaultComboBoxModel<>(new String[]{"Loading..."}));
resolution.setEnabled(false);
okButton.setEnabled(false);
loadPrinterDefaults(startingPrinter);
pageSize.addItemListener(e -> {
updatePreview();
updateMargins();
});
pageSize.setMinimumSize(new Dimension(40, 22));
pageSize.setPreferredSize(new Dimension(40, 22));
printerPanel.add(pageSize, setGridBagConstraints(gbc, 1, 1, 5));
jLabel10.setText(Messages.getMessage("PdfViewerPrintMargins.margin"));
printerPanel.add(jLabel10, setGridBagConstraints(gbc, 0, 2, 1));
jLabel11.setText(Messages.getMessage("PdfViewerPrintMargins.left"));
printerPanel.add(jLabel11, setGridBagConstraints(gbc, 1, 2, 1));
left.setModel(new CustomSpinnerModel());
left.setMinimumSize(new Dimension(65, 22));
left.setPreferredSize(new Dimension(65, 22));
printerPanel.add(left, setGridBagConstraints(gbc, 2, 2, 1));
jLabel12.setText(Messages.getMessage("PdfViewerPrintMargins.right"));
printerPanel.add(jLabel12, setGridBagConstraints(gbc, 3, 2, 1));
right.setModel(new CustomSpinnerModel());
right.setMinimumSize(new Dimension(65, 22));
right.setPreferredSize(new Dimension(65, 22));
printerPanel.add(right, setGridBagConstraints(gbc, 4, 2, 1));
jLabel13.setText(Messages.getMessage("PdfViewerPrintMargins.top"));
printerPanel.add(jLabel13, setGridBagConstraints(gbc, 1, 3, 1));
top.setModel(new CustomSpinnerModel());
top.setMinimumSize(new Dimension(65, 22));
top.setPreferredSize(new Dimension(65, 22));
printerPanel.add(top, setGridBagConstraints(gbc, 2, 3, 1));
jLabel14.setText(Messages.getMessage("PdfViewerPrintMargins.bottom"));
printerPanel.add(jLabel14, setGridBagConstraints(gbc, 3, 3, 1));
bottom.setModel(new CustomSpinnerModel());
bottom.setMinimumSize(new Dimension(65, 22));
bottom.setPreferredSize(new Dimension(65, 22));
printerPanel.add(bottom, setGridBagConstraints(gbc, 4, 3, 1));
addMarginChangeListener();
jLabel15.setText(Messages.getMessage("PdfViewerPrintResolution.text"));
printerPanel.add(jLabel15, setGridBagConstraints(gbc, 0, 4, 1));
printerPanel.add(resolution, setGridBagConstraints(gbc, 1, 4, 5));
tabbedPane.addTab(Messages.getMessage("PdfViewerPrintTab.printer"), printerPanel);
//END Printer PANEL
}
private static GridBagConstraints setGridBagConstraints(final GridBagConstraints gbc, final int x, final int y, final int width) {
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
return gbc;
}
private void addPrinterChangeListener() {
printerName.addItemListener(e -> {
previewComponent.repaint();
okButton.setEnabled(false);
pageSize.setEnabled(false);
pageSize.setModel(new DefaultComboBoxModel<>(new String[]{"Loading..."}));
resolution.setEnabled(false);
resolution.setModel(new DefaultComboBoxModel<>(new String[]{"Loading..."}));
SwingUtilities.invokeLater(() -> {
final PrintService[] ps = PrintServiceLookup.lookupPrintServices(null, null);
PrintService p = null;
for (final PrintService p1 : ps) {
if (p1.getName().equals(printerName.getSelectedItem())) {
p = p1;
}
}
if (p != null) {
resolution.setModel(new DefaultComboBoxModel<>(getAvailableResolutions(p)));
final int resInd = getDefaultResolutionIndex();
if (resolution.getModel().getSize() > resInd) {
resolution.setSelectedIndex(resInd);
}
resolution.setEnabled(true);
paperDefinitions.setPrintService(p);
pageSize.setModel(new DefaultComboBoxModel<>(getAvailablePaperSizes()));
final int pageInd = paperDefinitions.getDefaultPageIndex();
if (pageSize.getModel().getSize() > pageInd) {
pageSize.setSelectedIndex(pageInd);
}
pageSize.setEnabled(true);
okButton.setEnabled(true);
}
updateMargins();
});
});
}
private void addMarginChangeListener() {
final ChangeListener marginListener = new ChangeListener() {
static final double mmToSubInch = 72 / 25.4;
@Override
public void stateChanged(final ChangeEvent e) {
final MarginPaper paper = getSelectedPaper();
if (paper == null) {
return;
}
final double l = (Double) left.getValue() * mmToSubInch;
final double r = (Double) right.getValue() * mmToSubInch;
final double t = (Double) top.getValue() * mmToSubInch;
final double b = (Double) bottom.getValue() * mmToSubInch;
paper.setImageableArea(l, t, (paper.getWidth() - l) - r, (paper.getHeight() - t) - b);
updatePreview();
}
};
left.addChangeListener(marginListener);
right.addChangeListener(marginListener);
top.addChangeListener(marginListener);
bottom.addChangeListener(marginListener);
}
private String getDefaultPrinterName(final String startingPrinter) {
final String printerFlag = System.getProperty("org.jpedal.defaultPrinter");
String printerToUse = null;
if (printerFlag != null) {
for (final String aPrintersList : printersList) {
if (printerFlag.equals(aPrintersList)) {
printerToUse = aPrintersList;
break;
}
}
} else {
printerToUse = startingPrinter;
}
//Finally check system default incase nothing has been set
if (printerToUse == null || printerToUse.isEmpty()) {
final PrintService printer = PrintServiceLookup.lookupDefaultPrintService();
if (printer != null) {
printerToUse = printer.getName();
}
}
return printerToUse;
}
private void loadPrinterDefaults(final String startingPrinter) {
final Thread t = new Thread(() -> {
final String printerToUse = getDefaultPrinterName(startingPrinter);
final PrintService[] ps = PrintServiceLookup.lookupPrintServices(null, null);
PrintService p = null;
for (final PrintService p1 : ps) {
if (p1.getName().equals(printerToUse)) {
p = p1;
}
}
if (p != null) {
paperDefinitions.setPrintService(p);
resolution.setModel(new DefaultComboBoxModel<>(getAvailableResolutions(p)));
final int defaultResolution = getDefaultResolutionIndex();
if (resolution.getModel().getSize() > defaultResolution) {
resolution.setSelectedIndex(defaultResolution);
}
resolution.setEnabled(true);
pageSize.setModel(new DefaultComboBoxModel<>(getAvailablePaperSizes()));
final int defaultPageSize = paperDefinitions.getDefaultPageIndex();
if (defaultPageSize < pageSize.getModel().getSize()) {
pageSize.setSelectedIndex(defaultPageSize);
}
pageSize.setEnabled(true);
okButton.setEnabled(true);
}
updateMargins();
});
t.setDaemon(true);
t.start();
}
private static String[] getAvailableResolutions(final PrintService p) {
final PrinterResolution[] resolutions = (PrinterResolution[]) p.getSupportedAttributeValues(PrinterResolution.class, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
if (resolutions == null) {
return new String[]{"Default"};
}
final String[] names = new String[resolutions.length];
for (int i = 0; i < resolutions.length; i++) {
final PrinterResolution res = resolutions[i];
names[i] = res.getCrossFeedResolution(PrinterResolution.DPI) + "x" + res.getFeedResolution(PrinterResolution.DPI) + " dpi";
}
return names;
}
/**
* Gets the resolution value currently selected based on printer and selected resolution index
*
* @return PrinterResolution object representing the selected resolutions or null if no supported resolution is found.
*/
public PrinterResolution getResolution() {
final PrintService[] ps = PrintServiceLookup.lookupPrintServices(null, null);
PrintService p = null;
for (final PrintService p1 : ps) {
if (p1.getName().equals(printerName.getSelectedItem())) {
p = p1;
}
}
if (p == null) {
return null;
}
final PrinterResolution[] resolutions = ((PrinterResolution[]) p.getSupportedAttributeValues(PrinterResolution.class, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null));
if (resolutions == null) {
return null;
}
return resolutions[resolution.getSelectedIndex()];
}
private int getDefaultResolutionIndex() {
//get print service
final PrintService[] ps = PrintServiceLookup.lookupPrintServices(null, null);
PrintService p = null;
for (final PrintService p1 : ps) {
if (p1.getName().equals(printerName.getSelectedItem())) {
p = p1;
}
}
if (p == null) {
return 0;
}
//get available resolutions
final PrinterResolution[] resolutions = (PrinterResolution[]) p.getSupportedAttributeValues(PrinterResolution.class, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
if (resolutions == null) {
return 0;
}
if (defaultResolution == -1) {
defaultResolution = 600;
}
//find nearest resolution
int minDiff = Integer.MAX_VALUE;
int indexToUse = 0;
for (int i = 0; i < resolutions.length; i++) {
final PrinterResolution res = resolutions[i];
int cfDiff = res.getCrossFeedResolution(PrinterResolution.DPI) - defaultResolution;
if (cfDiff < 0) {
cfDiff = -cfDiff;
}
int fDiff = res.getFeedResolution(PrinterResolution.DPI) - defaultResolution;
if (fDiff < 0) {
fDiff = -fDiff;
}
if (cfDiff + fDiff < minDiff) {
minDiff = cfDiff + fDiff;
indexToUse = i;
}
}
return indexToUse;
}
private void updateMargins() {
final MarginPaper p = getSelectedPaper();
if (p == null) {
return;
}
//Update minimum values
((CustomSpinnerModel) left.getModel()).setMinValue(p.getMinX() * mmPerSubInch);
((CustomSpinnerModel) top.getModel()).setMinValue(p.getMinY() * mmPerSubInch);
((CustomSpinnerModel) right.getModel()).setMinValue((p.getWidth() - p.getMaxRX()) * mmPerSubInch);
((CustomSpinnerModel) bottom.getModel()).setMinValue((p.getHeight() - p.getMaxBY()) * mmPerSubInch);
//Set values to min
final Double a = (double) 0;
left.setValue(a);
top.setValue(a);
right.setValue(a);
bottom.setValue(a);
}
private void printPreview(final Graphics2D g2) {
final int w = previewComponent.getWidth();
final int h = previewComponent.getHeight();
int pageWidth, pageHeight;
//In print current view use the visible area of the screen instead of the page heights
if (printRangeCurrentView.isSelected()) {
pageWidth = (int) (pdf.getVisibleRect().getWidth() / (pdf.getScaling()));
pageHeight = (int) (pdf.getVisibleRect().getHeight() / (pdf.getScaling()));
} else {
pageWidth = pdf.getPdfPageData().getCropBoxWidth(currentPreviewedPage);
pageHeight = pdf.getPdfPageData().getCropBoxHeight(currentPreviewedPage);
}
//set paper size and printable area
final Paper p = getPaperForPreview(pageWidth, pageHeight);
if (p == null) {
g2.setColor(getForeground());
g2.drawString(Messages.getMessage("PdfPrintPreview.Loading"), (w / 2) - 25, (h / 2) - 5);
return;
}
//Set offsets
int lO = 25;
int tO = 30;
final int rO = 5;
final int bO = 25;
final double paperHeightInInches = p.getHeight() / 72d;
final double paperWidthInInches = p.getWidth() / 72d;
//Calculate scaling
final double wScale = (w - (lO + rO)) / p.getWidth();
final double hScale = (h - (tO + bO)) / p.getHeight();
final double scale = Math.min(wScale, hScale);
//Scale all values
p.setSize(scale * p.getWidth(), scale * p.getHeight());
p.setImageableArea(scale * p.getImageableX(), scale * p.getImageableY(), scale * p.getImageableWidth(), scale * p.getImageableHeight());
pageWidth = (int) (scale * pageWidth);
pageHeight = (int) (scale * pageHeight);
double pageScale = 1;
if (printHandlingScaling.getSelectedIndex() == 1 //Fit
|| (printHandlingScaling.getSelectedIndex() == 2 && (pageWidth > p.getImageableWidth() || pageHeight > p.getImageableHeight()))) { //Reduce
pageScale = p.getImageableWidth() / pageWidth;
if ((p.getImageableHeight() / pageHeight) < pageScale) {
pageScale = p.getImageableHeight() / pageHeight;
}
pageWidth = (int) (pageScale * pageWidth);
pageHeight = (int) (pageScale * pageHeight);
}
//Include any centering
lO += (w - (lO + rO + p.getWidth())) / 2;
tO += (h - (tO + bO + p.getHeight())) / 2;
drawPreviewArea(g2, lO, tO, (int) p.getWidth(), (int) p.getHeight(), (int) p.getImageableX(), (int) p.getImageableY(), (int) p.getImageableWidth(), (int) p.getImageableHeight());
drawPreviewWidthBar(g2, lO, tO, (int) p.getWidth(), paperWidthInInches, getForeground());
drawPreviewHeightBar(g2, lO, tO, (int) p.getHeight(), paperHeightInInches, getForeground());
//draw page
drawPreviewPage(g2, lO, tO, pageWidth, pageHeight, (int) p.getImageableX() - 1, (int) p.getImageableY() - 1, (int) p.getImageableWidth() - 1, (int) p.getImageableHeight() - 1);
//Draw border
drawPreviewBorder(g2, lO, tO, (int) p.getWidth(), (int) p.getHeight(), pageScale, h);
}
private Paper getPaperForPreview(final int pageWidth, final int pageHeight) {
final Paper p = new Paper();
if (paperSourceByPDF.isSelected()) {
p.setSize(pageWidth, pageHeight);
p.setImageableArea(0, 0, pageWidth, pageHeight);
} else {
final MarginPaper mp = paperDefinitions.getSelectedPaper((String) pageSize.getSelectedItem());
if (mp != null) {
p.setSize(mp.getWidth(), mp.getHeight());
p.setImageableArea(mp.getImageableX(), mp.getImageableY(), mp.getImageableWidth(), mp.getImageableHeight());
} else {
return null;
}
}
//check auto rotate
if (autoRotateCenter.isSelected()
&& ((pageWidth > pageHeight && p.getImageableWidth() < p.getImageableHeight())
|| (pageWidth < pageHeight && p.getImageableWidth() > p.getImageableHeight()))) {
p.setSize(p.getHeight(), p.getWidth());
p.setImageableArea(p.getImageableY(), p.getImageableX(), p.getImageableHeight(), p.getImageableWidth());
}
return p;
}
private static void drawPreviewBorder(final Graphics2D g2, final int lO, final int tO,
final int pW, final int pH, final double pageScale, final int h) {
g2.setClip(null);
g2.drawRect(lO, tO, pW, pH);
final NumberFormat f = NumberFormat.getNumberInstance();
f.setMaximumFractionDigits(0);
g2.drawString(Messages.getMessage("PdfPrintPreview.UnitScale") + f.format(pageScale * 100) + '%', 5, h - 5);
}
private void drawPreviewPage(final Graphics2D g2, final int lO, final int tO,
final int pageWidth, final int pageHeight,
final int iX, final int iY, final int iW, final int iH) {
try {
BufferedImage img;
//print current view uses current display on PdfDecoder
if (printRangeCurrentView.isSelected()) {
img = new BufferedImage((int) pdf.getVisibleRect().getWidth(), (int) pdf.getVisibleRect().getHeight(), BufferedImage.TYPE_INT_ARGB);
final Graphics g = img.getGraphics();
g.translate((int) -pdf.getVisibleRect().getX(), (int) -pdf.getVisibleRect().getY());
//store border and background and restore after paint
final Border bStore = ((JComponent) pdf).getBorder();
final Color cStore = ((Component) pdf).getBackground();
((JComponent) pdf).setBorder(BorderFactory.createEmptyBorder());
((Component) pdf).setBackground(Color.WHITE);
((PdfDecoder) pdf).paintComponent(g);
((JComponent) pdf).setBorder(bStore);
((Component) pdf).setBackground(cStore);
} else {
img = pdf.getPageAsImage(currentPreviewedPage);
}
if (grayscale.isSelected()) {
img = ColorSpaceConvertor.convertColorspace(img, BufferedImage.TYPE_BYTE_GRAY);
}
g2.setClip(lO + iX, tO + iY, iW, iH);
final int centeringX = (int) ((iW - pageWidth) / 2d);
final int centeringY = (int) ((iH - pageHeight) / 2d);
g2.drawImage(img, lO + iX + centeringX, tO + iY + centeringY, pageWidth, pageHeight, null);
} catch (final PdfException e) {
LogWriter.writeLog("Caught a PDFException " + e);
}
}
private static void drawPreviewArea(final Graphics2D g2, final int lO, final int tO,
final int pW, final int pH,
final int iX, final int iY, final int iW, final int iH) {
//Fill page background
g2.setPaint(Color.WHITE);
g2.fillRect(lO, tO, pW, pH);
//Draw printable area
g2.setPaint(Color.RED);
g2.drawLine(lO + iX, tO, lO + iX, tO + pH);
g2.drawLine(lO, tO + iY, lO + pW, tO + iY);
g2.drawLine(lO + iW + iX, tO, lO + iW + iX, tO + pH);
g2.drawLine(lO, tO + iH + iY, lO + pW, tO + iH + iY);
}
private static void drawPreviewWidthBar(final Graphics2D g2, final int lO, final int tO,
final int pW, final double paperWidthInInches, final Color col) {
g2.setPaint(col);
//Draw width bar
final NumberFormat f = NumberFormat.getNumberInstance();
f.setMaximumFractionDigits(1);
final String widthString = f.format(paperWidthInInches);
final int tLen = widthString.length() * 3;
g2.drawString(widthString, lO + (pW / 2) - tLen, tO - 5);
g2.drawLine(lO, tO - 15, lO, tO - 5);
g2.drawLine(lO + pW, tO - 15, lO + pW, tO - 5);
g2.drawLine(lO, tO - 10, (lO + (pW / 2) - tLen) - 6, tO - 10);
g2.drawLine((lO + (pW / 2) + tLen) + 6, tO - 10, lO + pW, tO - 10);
g2.drawLine(lO, tO - 10, lO + 5, tO - 15);
g2.drawLine(lO, tO - 10, lO + 5, tO - 5);
g2.drawLine(lO + pW, tO - 10, lO + pW - 5, tO - 15);
g2.drawLine(lO + pW, tO - 10, lO + pW - 5, tO - 5);
}
private static void drawPreviewHeightBar(final Graphics2D g2, final int lO, final int tO,
final int pH, final double paperHeightInInches, final Color col) {
g2.setPaint(col);
//Draw width bar
final NumberFormat f = NumberFormat.getNumberInstance();
f.setMaximumFractionDigits(1);
//Draw height bar
final String heightString = f.format(paperHeightInInches);
final int tLen = heightString.length() * 3;
g2.drawString(heightString, (lO - 12) - tLen, tO + (pH / 2) + 5);
g2.drawLine(lO - 15, tO, lO - 5, tO);
g2.drawLine(lO - 15, tO + pH, lO - 5, tO + pH);
g2.drawLine(lO - 10, tO, lO - 10, (tO + (pH / 2)) - 8);
g2.drawLine(lO - 10, ((tO + (pH / 2)) + 8), lO - 10, tO + pH);
g2.drawLine(lO - 10, tO, lO - 5, tO + 5);
g2.drawLine(lO - 10, tO, lO - 15, tO + 5);
g2.drawLine(lO - 10, tO + pH, lO - 15, tO + pH - 5);
g2.drawLine(lO - 10, tO + pH, lO - 5, tO + pH - 5);
}
private void nameElements() {
okButton.setName("ok");
cancelButton.setName("cancel");
pageSize.setName("size");
printerName.setName("printer");
autoRotateCenter.setName("autoRot");
paperSourceByPDF.setName("paperSource");
printHandlingScaling.setName("scaling");
tabbedPane.setName("tabPane");
setName("printDialog");
}
private void updatePreview() {
int selection = previewSlider.getValue();
//check for illogical settings
final SetOfIntegerSyntax set = getPrintRange();
final int pagePrintCount;
if (set == null) {
//Illogical - preview nothing
currentPreviewedPage = 0;
pagePrintCount = 0;
} else {
final int[][] ranges = set.getMembers();
//calculate length
int count = 0;
for (final int[] range1 : ranges) {
count += range1[1] - (range1[0] - 1);
}
final int[] pagesToPrint = new int[count];
pagePrintCount = pagesToPrint.length;
//populate array with page numbers
count = 0;
for (final int[] range : ranges) {
final int rangeLength = range[1] - (range[0] - 1);
for (int j = 0; j < rangeLength; j++) {
pagesToPrint[count] = range[0] + j;
count++;
}
}
//check selection value
if (selection > pagePrintCount) {
selection = 1;
previewSlider.resetValue();
}
//Work out which page to preview
if (printRangeReversePages.isSelected()) {
currentPreviewedPage = pagesToPrint[pagesToPrint.length - selection];
} else {
currentPreviewedPage = pagesToPrint[selection - 1];
}
}
//recalculate previewSlider
previewSlider.setMaxValue(pagePrintCount);
//redraw
previewComponent.repaint();
}
private void pagesBoxPressed() {
printRangeFrom.setSelected(true);
printRangeSubset.setEnabled(true);
printRangeReversePages.setEnabled(true);
updatePreview();
}
private void pagesFromStateChanged() {
if (printRangeFrom.isSelected()) {
printRangeSubset.setEnabled(true);
printRangeReversePages.setEnabled(true);
updatePreview();
}
}
private void printRangeCurrentView() {
if (printRangeCurrentView.isSelected()) {
printRangeSubset.setEnabled(false);
printRangeReversePages.setEnabled(false);
updatePreview();
}
}
private void currentPageStateChanged() {
if (printRangeCurrentPage.isSelected()) {
printRangeSubset.setEnabled(false);
printRangeReversePages.setEnabled(false);
updatePreview();
}
}
private void allStateChanged() {
if (printRangeAll.isSelected()) {
printRangeSubset.setEnabled(true);
printRangeReversePages.setEnabled(true);
updatePreview();
}
}
private void cancelEvent() {
okClicked = false;
getTopLevelAncestor().setVisible(false);
}
private void okEvent() {
okClicked = true;
getTopLevelAncestor().setVisible(false);
}
// Variables declaration - do not modify
private javax.swing.JCheckBox autoRotateCenter;
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JButton cancelButton;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel7;
private javax.swing.JLabel jLabel8;
private javax.swing.JLabel jLabel9;
private javax.swing.JLabel jLabel10;
private javax.swing.JLabel jLabel11;
private javax.swing.JLabel jLabel12;
private javax.swing.JLabel jLabel13;
private javax.swing.JLabel jLabel14;
private javax.swing.JLabel jLabel15;
private javax.swing.JSpinner left;
private javax.swing.JSpinner right;
private javax.swing.JSpinner top;
private javax.swing.JSpinner bottom;
private JComboBox<String> resolution;
private javax.swing.JButton okButton;
private javax.swing.JPanel pageHandlingPanel;
private javax.swing.JComponent previewComponent;
private CustomSlider previewSlider;
private JComboBox<String> pageSize;
private javax.swing.JTextField pagesFrom;
private javax.swing.JTextField pagesTo;
private javax.swing.JCheckBox paperSourceByPDF;
private javax.swing.JCheckBox grayscale;
private javax.swing.JSpinner printHandlingCopies;
private JComboBox<String> printHandlingScaling;
private javax.swing.JRadioButton printRangeAll;
private javax.swing.JRadioButton printRangeCurrentPage;
private javax.swing.JRadioButton printRangeCurrentView;
private javax.swing.JRadioButton printRangeFrom;
private javax.swing.JPanel printRangePanel;
private javax.swing.JCheckBox printRangeReversePages;
private JComboBox<String> printRangeSubset;
private JComboBox<String> printerName;
private javax.swing.JPanel printerPanel;
private javax.swing.JTabbedPane tabbedPane;
// End of variables declaration
/**
* Get the range of pages to be printed.
* If the range is specified so no pages possible, such as printing all
* even pages between 1 and 1, this method will return null.
*
* @return SetOfIntegerSyntax object containing the page numbers of pages to be printed or null if no pages are applicable
*/
@SuppressWarnings({"OverlyLongMethod", "java:S138"})
public SetOfIntegerSyntax getPrintRange() {
SetOfIntegerSyntax pageRange = null;
if (printRangeAll.isSelected()) {
pageRange = new PageRanges(1, pageCount);
if (printRangeSubset.getSelectedIndex() == 0) {
return pageRange;
}
if (printRangeSubset.getSelectedIndex() == 1) {
pageRange = getPageRange1(pageRange, 1);
} else if (printRangeSubset.getSelectedIndex() == 2) {
pageRange = getPageRange1(pageRange, 0);
}
} else if (printRangeCurrentPage.isSelected()) {
pageRange = new PageRanges(currentPage);
} else if (printRangeCurrentView.isSelected()) {
pageRange = new PageRanges(currentPage);
} else if (printRangeFrom.isSelected()) {
int start, end;
try {
start = Integer.parseInt(pagesFrom.getText());
} catch (final NumberFormatException e) {
LogWriter.writeLog("Exception in setting page range " + e);
pagesFrom.setText("1");
start = 1;
}
try {
end = Integer.parseInt(pagesTo.getText());
} catch (final NumberFormatException e) {
LogWriter.writeLog("Exception in setting page range " + e);
pagesTo.setText(String.valueOf(pageCount));
end = pageCount;
}
//Check values in range
start = limitValueToFullPageRange(start, pageCount);
end = limitValueToFullPageRange(end, pageCount);
pagesFrom.setText(String.valueOf(start));
pagesTo.setText(String.valueOf(end));
if (start > end) {
final int tmp = end;
end = start;
start = tmp;
if (SwingGUI.showMessages) {
JOptionPane.showMessageDialog(this, Messages.getMessage("PdfViewerPrint.SwapValues"));
}
}
pageRange = new PageRanges(start, end);
if (printRangeSubset.getSelectedIndex() == 0) {
return pageRange;
}
if (printRangeSubset.getSelectedIndex() == 1) {
final StringBuilder membersStr = new StringBuilder();
int i = -1;
while ((i = pageRange.next(i)) != -1) {
if (i % 2 == 1) {
membersStr.append(i).append(',');
}
}
String members = membersStr.toString();
final StringBuilder sb = new StringBuilder(members);
if (members.isEmpty()) {
return null;
}
sb.deleteCharAt(members.length() - 1);
members = sb.toString();
pageRange = new PageRanges(members);
} else if (printRangeSubset.getSelectedIndex() == 2) {
final StringBuilder membersStr = new StringBuilder();
int i = -1;
while ((i = pageRange.next(i)) != -1) {
if (i % 2 == 0) {
membersStr.append(i).append(',');
}
}
String members = membersStr.toString();
final StringBuilder sb = new StringBuilder(members);
final int length = members.length();
if (length > 0) {
sb.deleteCharAt(length - 1);
}
members = sb.toString();
if (!members.isEmpty()) {
pageRange = new PageRanges(members);
} else {
pageRange = null;
}
}
}
return pageRange;
}
private static SetOfIntegerSyntax getPageRange1(SetOfIntegerSyntax pageRange, final int i2) {
final StringBuilder membersStr = new StringBuilder();
int i = -1;
while ((i = pageRange.next(i)) != -1) {
if (i % 2 == i2) {
membersStr.append(i).append(',');
}
}
String members = membersStr.toString();
final StringBuilder sb = new StringBuilder(members);
sb.deleteCharAt(members.length() - 1);
members = sb.toString();
pageRange = new PageRanges(members);
return pageRange;
}
private static int limitValueToFullPageRange(final int value, final int pageCount) {
final int returnValue;
if (value < 1) {
returnValue = 1;
} else {
returnValue = Math.min(value, pageCount);
}
return returnValue;
}
/**
* Get the number of copies to be printed as set in the print panel.
*
* @return int value representing the number of copies to be printed.
*/
public int getCopies() {
final String copies = printHandlingCopies.getValue().toString();
return Integer.parseInt(copies);
}
/**
* Get the page scaling selected in the print panel
* The possible values and their variables include,
* <p>
* PrinterOptions.PAGE_SCALING_NONE = 0
* PrinterOptions.PAGE_SCALING_FIT_TO_PRINTER_MARGINS = 1
* PrinterOptions.PAGE_SCALING_REDUCE_TO_PRINTER_MARGINS = 2
* see org.jpedal.objects.PrinterOptions for all values
*
* @return int value representing the page scaling to be used (see org.jpedal.objects.PrinterOptions for all values)
*/
public int getPageScaling() {
final int option = printHandlingScaling.getSelectedIndex();
int value = 0;
//make choice
switch (option) {
case 0: //No scaling
break;
case 1: //Fit to scaling
value = PrinterOptions.PAGE_SCALING_FIT_TO_PRINTER_MARGINS;
break;
case 2: //Reduce to scaling
value = PrinterOptions.PAGE_SCALING_REDUCE_TO_PRINTER_MARGINS;
break;
}
//remember last option for next print dialog
PrinterOptions.LAST_SCALING_CHOICE = value;
return value;
}
/**
* Get the name of the printer selected in the print panel
*
* @return String value representing the name of a printer or null if no printer selected
*/
public String getPrinter() {
if (printerName == null) {
return "";
} else {
if (printerName.getSelectedItem() == null) {
return null;
} else {
return printerName.getSelectedItem().toString();
}
}
}
public boolean okClicked() {
return okClicked;
}
public boolean isAutoRotateAndCenter() {
return autoRotateCenter.isSelected();
}
public boolean isPaperSourceByPDFSize() {
return paperSourceByPDF.isSelected();
}
public boolean isPrintingCurrentView() {
return printRangeCurrentView.isSelected();
}
private String[] getAvailablePaperSizes() {
return paperDefinitions.getAvailablePaperSizes();
}
/**
* return selected Paper
*
* @return the selected paper
*/
public MarginPaper getSelectedPaper() {
return paperDefinitions.getSelectedPaper((String) pageSize.getSelectedItem());
}
/**
* return printers default orientation
*
* @return an int value to show if page is landscape or portrait [reverse landscape = 2, portrait = 1, landscape = 0]
*/
public int getSelectedPrinterOrientation() {
return paperDefinitions.getDefaultPageOrientation();
}
public boolean isPagesReversed() {
return printRangeReversePages.isSelected();
}
public boolean isOddPagesOnly() {
return printRangeSubset.getSelectedIndex() == 1;
}
public boolean isEvenPagesOnly() {
return printRangeSubset.getSelectedIndex() == 2;
}
public boolean isMonochrome() {
return grayscale.isSelected();
}
private class CustomSlider extends JPanel {
private int value = 1, maxValue = 100;
private static final int rightMargin = 9;
private static final int leftMargin = 9;
private boolean dragging;
CustomSlider() {
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(final MouseEvent e) {
if (dragging) {
value = (int) ((((double) (e.getX() - leftMargin) / (getWidth() - (leftMargin + rightMargin))) * (maxValue - 1)) + 1.5);
if (value > maxValue) {
value = maxValue;
}
if (value < 1) {
value = 1;
}
updatePreview();
repaint();
}
}
});
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(final MouseEvent e) {
if (e.getY() < 20) {
final double newValue = (((double) (e.getX() - leftMargin) / (getWidth() - (leftMargin + rightMargin))) * (maxValue - 1)) + 1;
if (newValue > value) {
value++;
} else if (newValue < value) {
value--;
}
if (value > maxValue) {
value = maxValue;
}
if (value < 1) {
value = 1;
}
updatePreview();
repaint();
}
}
@Override
public void mousePressed(final MouseEvent e) {
if (e.getY() < 20) {
dragging = true;
}
}
@Override
public void mouseReleased(final MouseEvent e) {
dragging = false;
}
});
}
@Override
public void paint(final Graphics g) {
final Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
final int w = getWidth();
final int h = getHeight();
//fill background
g2.setPaint(getBackground());
g2.fillRect(0, 0, w, h);
//draw text
g2.setPaint(getForeground());
g2.drawString(Messages.getMessage("PdfPrintPreview.Sheet") + value + ' ' + Messages.getMessage("PdfPrintPreview.SheetOf") + maxValue, 2, h - 3);
//draw line
g2.setPaint(Color.LIGHT_GRAY);
g2.fillRect(leftMargin + 1, 11, w - ((leftMargin + rightMargin) + 1), 3);
g2.setPaint(Color.GRAY);
g2.drawLine(leftMargin, 12, w - rightMargin, 12);
//draw knob
final float pageX = leftMargin + (((float) (value - 1) / (maxValue - 1)) * (w - (leftMargin + rightMargin)));
final Shape number = new Ellipse2D.Float(pageX - 6, 6.5f, 12, 12);
final Shape number2 = new Ellipse2D.Float(pageX - 4, 8.5f, 8, 8);
g2.setPaint(Color.BLACK);
g2.fill(number);
g2.setPaint(Color.WHITE);
g2.fill(number2);
}
void resetValue() {
value = 1;
repaint();
}
void setMaxValue(final int maxValue) {
if (maxValue != this.maxValue) {
value = 1;
this.maxValue = maxValue;
updatePreview();
return;
}
repaint();
}
int getValue() {
return value;
}
}
private static class CustomSpinnerModel extends SpinnerNumberModel {
private double value;
private final ArrayList<ChangeListener> listeners = new ArrayList<>();
private double minValue;
@SuppressWarnings("ManualMinMaxCalculation")
@Override
public Object getPreviousValue() {
if (value <= minValue) {
return null;
}
if (value - 0.5 < minValue) {
return minValue;
}
return value - 0.5;
}
@Override
public Object getNextValue() {
return value + 0.5;
}
@Override
public Object getValue() {
return value;
}
@Override
public void addChangeListener(final ChangeListener l) {
listeners.add(l);
}
@Override
public void removeChangeListener(final ChangeListener l) {
listeners.remove(l);
}
@Override
public void setValue(final Object value) {
try {
final double newValue = (Double) value;
this.value = Math.max(newValue, minValue);
} catch (final Exception e) {
LogWriter.writeLog("Exception in setting print value " + e);
throw new IllegalArgumentException();
}
final ChangeEvent e = new ChangeEvent(this);
for (final ChangeListener listener : listeners) {
if (listener != null) {
listener.stateChanged(e);
}
}
}
void setMinValue(final double minValue) {
this.minValue = minValue;
setValue(getValue());
}
}
}
|