From 1e18107023e8755ca93121e50978d63f29370417 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 18 Feb 2023 17:50:49 +0100 Subject: [PATCH 1/4] AS Cards: Enable printing --- .../client/ui/dialogs/ASStatsDialog.java | 26 +++- .../client/ui/swing/ASStatsTablePanel.java | 13 +- .../ui/swing/alphaStrike/ASCardPanel.java | 4 + .../swing/alphaStrike/ASElementPrinter.java | 120 ++++++++++++++++++ .../alphaStrike/ConfigurableASCardPanel.java | 19 +++ .../common/alphaStrike/cardDrawer/ASCard.java | 27 +++- .../cardDrawer/ASLargeAeroCard.java | 15 ++- 7 files changed, 212 insertions(+), 12 deletions(-) create mode 100644 megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java diff --git a/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java b/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java index 7037d5ce58d..09bab47a160 100644 --- a/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java +++ b/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java @@ -30,8 +30,9 @@ import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; -import java.util.ArrayList; -import java.util.Collection; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; +import java.util.*; /** * This non-modal dialog shows stats of one or more AlphaStrike elements in the form of a table. @@ -41,8 +42,10 @@ public class ASStatsDialog extends AbstractDialog { private final Collection entities; private final JButton clipBoardButton = new JButton("Copy to Clipboard"); + private final JButton printButton = new JButton("Print"); private final JScrollPane scrollPane = new JScrollPane(); private final JPanel centerPanel = new JPanel(); + private ASStatsTablePanel tablePanel; private static final String COLUMN_SEPARATOR = "\t"; private static final String INTERNAL_DELIMITER = ","; @@ -68,7 +71,9 @@ protected Container createCenterPane() { var optionsPanel = new UIUtil.FixedYPanel(new FlowLayout(FlowLayout.LEFT)); optionsPanel.add(Box.createVerticalStrut(25)); optionsPanel.add(clipBoardButton); + optionsPanel.add(printButton); clipBoardButton.addActionListener(e -> copyToClipboard()); + printButton.addActionListener(ev -> printCards()); scrollPane.getVerticalScrollBar().setUnitIncrement(16); @@ -81,8 +86,8 @@ protected Container createCenterPane() { private void setupTable() { centerPanel.remove(scrollPane); - JPanel asPanel = new ASStatsTablePanel(getFrame()).add(entities, "Selected Units").getPanel(); - scrollPane.setViewportView(asPanel); + tablePanel = new ASStatsTablePanel(getFrame()).add(entities, "Selected Units"); + scrollPane.setViewportView(tablePanel.getPanel()); centerPanel.add(scrollPane); adaptToGUIScale(); } @@ -143,4 +148,17 @@ private StringBuilder dataLine(AlphaStrikeElement element) { private void adaptToGUIScale() { UIUtil.adjustDialog(this, UIUtil.FONT_SCALE1); } + + private void printCards() { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(tablePanel); + boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ignored) { + + } + } + } } \ No newline at end of file diff --git a/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java b/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java index 30f845dbd5e..0ae5191910e 100644 --- a/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java +++ b/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java @@ -19,6 +19,7 @@ package megamek.client.ui.swing; import megamek.client.ui.dialogs.ASConversionInfoDialog; +import megamek.client.ui.swing.alphaStrike.ASElementPrinter; import megamek.client.ui.swing.calculationReport.FlexibleCalculationReport; import megamek.client.ui.swing.util.SpringUtilities; import megamek.client.ui.swing.util.UIUtil; @@ -30,10 +31,13 @@ import javax.swing.*; import java.awt.*; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; import java.util.List; import java.util.*; -public class ASStatsTablePanel { +public class ASStatsTablePanel implements Printable { private final int COLUMNS = 15; private final static Color GROUP_NAME_COLOR = UIUtil.uiLightGreen(); @@ -43,6 +47,7 @@ public class ASStatsTablePanel { private int rows; private final List groups = new ArrayList<>(); private final JFrame frame; + private final List elements = new ArrayList<>(); /** * Constructs a panel with a table of AlphaStrike stats for any units that are added to it. @@ -123,6 +128,7 @@ private void addGrouptoPanel(EntityGroup group) { } } } + elements.addAll(elementList); // Print the elements rows++; @@ -247,6 +253,11 @@ private void addLine() { } } + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + return new ASElementPrinter(elements).print(graphics, pageFormat, pageIndex); + } + /** A record to store added groups of units before constructing the panel. */ private static class EntityGroup { private final List entities; diff --git a/megamek/src/megamek/client/ui/swing/alphaStrike/ASCardPanel.java b/megamek/src/megamek/client/ui/swing/alphaStrike/ASCardPanel.java index 27b8746f150..db123047af9 100644 --- a/megamek/src/megamek/client/ui/swing/alphaStrike/ASCardPanel.java +++ b/megamek/src/megamek/client/ui/swing/alphaStrike/ASCardPanel.java @@ -116,4 +116,8 @@ protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(cardImage, 0, 0, this); } + + public ASCard getCard() { + return card; + } } \ No newline at end of file diff --git a/megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java b/megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java new file mode 100644 index 00000000000..7b5050a0b1c --- /dev/null +++ b/megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2023 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ +package megamek.client.ui.swing.alphaStrike; + +import megamek.MMConstants; +import megamek.client.ui.swing.GUIPreferences; +import megamek.codeUtilities.StringUtility; +import megamek.common.alphaStrike.ASCardDisplayable; +import megamek.common.alphaStrike.cardDrawer.ASCard; +import megamek.common.alphaStrike.cardDrawer.ASLargeAeroCard; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class ASElementPrinter { + + private final List cardSlots = new ArrayList<>(); + private int row; + private int column; + private AffineTransform baseTransform; + private int columnCount = 2; + private int rowCount = 4; + + public ASElementPrinter(Collection elements) { + Font userSelectedFont = userSelectedFont(); + for (ASCardDisplayable element : elements) { + ASCard card = ASCard.createCard(element); + card.setFont(userSelectedFont); + cardSlots.add(new CardSlot(card, false)); + if (element.usesArcs()) { + cardSlots.add(new CardSlot(card, true)); + } + } + } + + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) + throws PrinterException { + double height = 2.5 * 72; + rowCount = (int) (pageFormat.getImageableHeight() / height); + columnCount = (int) (pageFormat.getImageableWidth() / (3.5 * 72)); + if (isPageIndexValid(pageIndex)) { + double fullHeight = rowCount * height; + Graphics2D g2D = (Graphics2D) graphics; + double topCardY = pageFormat.getHeight() / 2 - fullHeight / 2; + g2D.translate(pageFormat.getWidth() / 2, topCardY); + g2D.scale(ASCard.PRINT_SCALE, ASCard.PRINT_SCALE); + baseTransform = g2D.getTransform(); + + int elementIndex = pageStartSlotIndex(pageIndex); + while ((elementIndex < pageStartSlotIndex(pageIndex + 1)) && (elementIndex < cardSlots.size())) { + goToPrintSlot(elementIndex - pageStartSlotIndex(pageIndex), g2D); + CardSlot cardSlot = cardSlots.get(elementIndex); + if (cardSlot.flipSide) { + ((ASLargeAeroCard) (cardSlot.card)).drawFlipside(g2D); + } else { + cardSlot.card.drawCard(g2D); + } + elementIndex++; + } + + return Printable.PAGE_EXISTS; + } else { + return Printable.NO_SUCH_PAGE; + } + } + + private Font userSelectedFont() { + String fontName = GUIPreferences.getInstance().getAsCardFont(); + return (StringUtility.isNullOrBlank(fontName) + ? new Font(MMConstants.FONT_SANS_SERIF, Font.PLAIN, 14) + : Font.decode(fontName)); + } + + private int pageStartSlotIndex(int pageIndex) { + return columnCount * rowCount * pageIndex; + } + + private boolean isPageIndexValid(int pageIndex) { + return cardSlots.size() > pageStartSlotIndex(pageIndex); + } + + private void goToPrintSlot(int slot, Graphics2D g2D) { + g2D.setTransform(baseTransform); + column = slot / rowCount; + row = slot - column * rowCount; + g2D.translate(-ASCard.WIDTH * columnCount / 2 + ASCard.WIDTH * column, ASCard.HEIGHT * row); + } + + private static class CardSlot { + ASCard card; + boolean flipSide; + + CardSlot(ASCard card, boolean flipSide) { + this.card = card; + this.flipSide = flipSide; + } + } +} \ No newline at end of file diff --git a/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java b/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java index 2b0ee9fb79b..9f946e1035d 100644 --- a/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java +++ b/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java @@ -33,6 +33,8 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; +import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; import java.net.URL; /** @@ -45,6 +47,7 @@ public class ConfigurableASCardPanel extends JPanel { private final JComboBox fontChooser = new JComboBox<>(); private final JComboBox sizeChooser = new JComboBox<>(); private final JButton copyButton = new JButton("Copy to Clipboard"); + private final JButton printButton = new JButton("Print"); private final JButton mulButton = new JButton("MUL"); private final JButton conversionButton = new JButton("Conversion Report"); private final ASCardPanel cardPanel = new ASCardPanel(); @@ -79,6 +82,7 @@ public ConfigurableASCardPanel(@Nullable ASCardDisplayable element, JFrame paren sizeChooser.setRenderer((list, value, index, isSelected, cellHasFocus) -> new JLabel(Float.toString(value))); copyButton.addActionListener(ev -> copyCardToClipboard()); + printButton.addActionListener(ev -> printCard()); mulButton.addActionListener(ev -> showMUL()); mulButton.setToolTipText("Show the Master Unit List entry for this unit. Opens a browser window."); @@ -96,6 +100,8 @@ public ConfigurableASCardPanel(@Nullable ASCardDisplayable element, JFrame paren chooserLine.add(Box.createHorizontalStrut(15)); chooserLine.add(copyButton); chooserLine.add(Box.createHorizontalStrut(15)); + chooserLine.add(printButton); + chooserLine.add(Box.createHorizontalStrut(15)); chooserLine.add(mulButton); chooserLine.add(Box.createHorizontalStrut(15)); chooserLine.add(conversionButton); @@ -166,6 +172,19 @@ private void showConversionReport() { } } + private void printCard() { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(cardPanel.getCard()); + boolean doPrint = job.printDialog(); + if (doPrint) { + try { + job.print(); + } catch (PrinterException ex) { + JOptionPane.showMessageDialog(this, ex.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE); + } + } + } + // Taken from https://alvinalexander.com/java/java-copy-image-to-clipboard-example/ private void copyCardToClipboard() { ImageSelection imgSel = new ImageSelection(cardPanel.getCardImage()); diff --git a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java index 281ed983d89..03f14d5c2cc 100644 --- a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java +++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java @@ -33,6 +33,9 @@ import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.awt.print.PageFormat; +import java.awt.print.Printable; +import java.awt.print.PrinterException; import java.time.LocalDate; import java.util.Locale; @@ -50,10 +53,11 @@ * for Large Aerospace units the specific class can be used to have additional functionality for the two * card faces of these cards. */ -public class ASCard { +public class ASCard implements Printable { - protected final static int WIDTH = 1050; - protected final static int HEIGHT = 750; + public final static int WIDTH = 1050; + public final static int HEIGHT = 750; + public final static double PRINT_SCALE = 3.5 * 72 / WIDTH; // 3.5" wide, 1/72 dots per inch protected final static int BORDER = 21; protected final static int ARMOR_PIP_SIZE = 22; protected final static int DAMAGE_PIP_SIZE = 18; @@ -222,7 +226,7 @@ protected void initializeFonts(Font lightFont, Font boldFont, Font blackFont) { } /** This method controls drawing the card. */ - protected final void drawCard(Graphics g) { + public final void drawCard(Graphics g) { initializeFonts(lightFont, boldFont, blackFont); Graphics2D g2D = (Graphics2D) g; GUIPreferences.AntiAliasifSet(g); @@ -555,4 +559,19 @@ private Image getFluffImage(ASCardDisplayable element) { return null; } } + + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { + if (pageIndex == 0) { + Graphics2D g2D = (Graphics2D) graphics; + double height = 2.5 * 72; + g2D.translate(pageFormat.getWidth() / 2, pageFormat.getHeight() / 2 - height / 2); + g2D.scale(ASCard.PRINT_SCALE, ASCard.PRINT_SCALE); + g2D.translate(-WIDTH / 2, 0); + drawCard(graphics); + return PAGE_EXISTS; + } else { + return NO_SUCH_PAGE; + } + } } \ No newline at end of file diff --git a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASLargeAeroCard.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASLargeAeroCard.java index d01b738526e..a1ee2dec49d 100644 --- a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASLargeAeroCard.java +++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASLargeAeroCard.java @@ -18,6 +18,7 @@ */ package megamek.common.alphaStrike.cardDrawer; +import megamek.client.ui.swing.GUIPreferences; import megamek.client.ui.swing.util.StringDrawer; import megamek.common.alphaStrike.*; import megamek.common.util.ImageUtil; @@ -48,8 +49,7 @@ public class ASLargeAeroCard extends ASCard { private Font arcSpecialsFont; private Font critTextFont; - private final StringDrawer.StringDrawerConfig damageValueConfig = new StringDrawer.StringDrawerConfig().centerX() - .scaleX(0.9f).color(Color.BLACK).font(damageFont); + private StringDrawer.StringDrawerConfig damageValueConfig; public ASLargeAeroCard(ASCardDisplayable element) { super(element); @@ -89,6 +89,9 @@ protected void initializeFonts(Font lightFont, Font boldFont, Font blackFont) { specialsHeaderConfig = new StringDrawer.StringDrawerConfig().color(Color.BLACK) .font(blackFont.deriveFont((float)largeAeroSpecialFont.getSize())); + + damageValueConfig = new StringDrawer.StringDrawerConfig().centerX() + .scaleX(0.9f).color(Color.BLACK).font(damageFont); } @Override @@ -99,7 +102,13 @@ protected void initialize() { fluffYCenter = 366; } - private void drawFlipside(Graphics2D g) { + public void drawFlipside(Graphics2D g) { + initializeFonts(lightFont, boldFont, blackFont); + GUIPreferences.AntiAliasifSet(g); + g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); + g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); + g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); paintCardBackground(g, true); new StringDrawer("WEAPON CRITICALS").at(33, 629).font(arcTitleFont).maxWidth(220) .outline(Color.BLACK, 0.4f).centerY().draw(g); From edcc849623df8cad7c2f7370da202043f99e7c46 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 23 Feb 2023 23:05:02 +0100 Subject: [PATCH 2/4] AS Cards: Add a progress monitor --- .../client/ui/dialogs/ASStatsDialog.java | 17 +---- .../client/ui/swing/ASStatsTablePanel.java | 15 ++-- .../alphaStrike/ConfigurableASCardPanel.java | 13 +--- .../megamek/client/ui/swing/util/UIUtil.java | 2 +- .../common/alphaStrike/cardDrawer/ASCard.java | 20 +---- .../cardDrawer/ASCardPrinter.java} | 74 +++++++++++++++++-- 6 files changed, 82 insertions(+), 59 deletions(-) rename megamek/src/megamek/{client/ui/swing/alphaStrike/ASElementPrinter.java => common/alphaStrike/cardDrawer/ASCardPrinter.java} (62%) diff --git a/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java b/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java index 09bab47a160..de010b4191f 100644 --- a/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java +++ b/megamek/src/megamek/client/ui/dialogs/ASStatsDialog.java @@ -24,15 +24,15 @@ import megamek.common.Entity; import megamek.common.alphaStrike.AlphaStrikeElement; import megamek.common.alphaStrike.AlphaStrikeHelper; +import megamek.common.alphaStrike.cardDrawer.ASCardPrinter; import megamek.common.alphaStrike.conversion.ASConverter; import javax.swing.*; import java.awt.*; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; -import java.awt.print.PrinterException; -import java.awt.print.PrinterJob; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; /** * This non-modal dialog shows stats of one or more AlphaStrike elements in the form of a table. @@ -150,15 +150,6 @@ private void adaptToGUIScale() { } private void printCards() { - PrinterJob job = PrinterJob.getPrinterJob(); - job.setPrintable(tablePanel); - boolean doPrint = job.printDialog(); - if (doPrint) { - try { - job.print(); - } catch (PrinterException ignored) { - - } - } + new ASCardPrinter(tablePanel.getElements(), getFrame()).printCards(); } } \ No newline at end of file diff --git a/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java b/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java index 0ae5191910e..3d36e7f6e23 100644 --- a/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java +++ b/megamek/src/megamek/client/ui/swing/ASStatsTablePanel.java @@ -19,7 +19,6 @@ package megamek.client.ui.swing; import megamek.client.ui.dialogs.ASConversionInfoDialog; -import megamek.client.ui.swing.alphaStrike.ASElementPrinter; import megamek.client.ui.swing.calculationReport.FlexibleCalculationReport; import megamek.client.ui.swing.util.SpringUtilities; import megamek.client.ui.swing.util.UIUtil; @@ -31,13 +30,10 @@ import javax.swing.*; import java.awt.*; -import java.awt.print.PageFormat; -import java.awt.print.Printable; -import java.awt.print.PrinterException; import java.util.List; import java.util.*; -public class ASStatsTablePanel implements Printable { +public class ASStatsTablePanel { private final int COLUMNS = 15; private final static Color GROUP_NAME_COLOR = UIUtil.uiLightGreen(); @@ -100,6 +96,10 @@ public JPanel getPanel() { return panel; } + public List getElements() { + return elements; + } + /** Assembles the JPanel. It is empty before calling this method. */ private void constructPanel() { addVerticalSpace(); @@ -253,11 +253,6 @@ private void addLine() { } } - @Override - public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { - return new ASElementPrinter(elements).print(graphics, pageFormat, pageIndex); - } - /** A record to store added groups of units before constructing the panel. */ private static class EntityGroup { private final List entities; diff --git a/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java b/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java index 9f946e1035d..12b132a4331 100644 --- a/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java +++ b/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java @@ -24,6 +24,7 @@ import megamek.client.ui.swing.util.UIUtil; import megamek.common.alphaStrike.ASCardDisplayable; import megamek.common.alphaStrike.AlphaStrikeElement; +import megamek.common.alphaStrike.cardDrawer.ASCardPrinter; import megamek.common.annotations.Nullable; import org.apache.logging.log4j.LogManager; @@ -36,6 +37,7 @@ import java.awt.print.PrinterException; import java.awt.print.PrinterJob; import java.net.URL; +import java.util.List; /** * This is a JPanel that displays an AlphaStrike unit card and elements to configure the display of @@ -173,16 +175,7 @@ private void showConversionReport() { } private void printCard() { - PrinterJob job = PrinterJob.getPrinterJob(); - job.setPrintable(cardPanel.getCard()); - boolean doPrint = job.printDialog(); - if (doPrint) { - try { - job.print(); - } catch (PrinterException ex) { - JOptionPane.showMessageDialog(this, ex.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE); - } - } + new ASCardPrinter(List.of(element), parent).printCards(); } // Taken from https://alvinalexander.com/java/java-copy-image-to-clipboard-example/ diff --git a/megamek/src/megamek/client/ui/swing/util/UIUtil.java b/megamek/src/megamek/client/ui/swing/util/UIUtil.java index 7e6130dd7c6..0c16379301b 100644 --- a/megamek/src/megamek/client/ui/swing/util/UIUtil.java +++ b/megamek/src/megamek/client/ui/swing/util/UIUtil.java @@ -416,7 +416,7 @@ public static void adjustContainer(Container parentCon, int fontSize) { if ((comp instanceof JButton) || (comp instanceof JLabel) || (comp instanceof JComboBox) || (comp instanceof JTextField) || (comp instanceof JSlider) || (comp instanceof JSpinner) || (comp instanceof JTextArea) || (comp instanceof JToggleButton) - || (comp instanceof JTable) || (comp instanceof JList) + || (comp instanceof JTable) || (comp instanceof JList) || (comp instanceof JProgressBar) || (comp instanceof JEditorPane) || (comp instanceof JTree)) { if ((comp.getFont() != null) && (sf != comp.getFont().getSize())) { comp.setFont(comp.getFont().deriveFont((float) sf)); diff --git a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java index 03f14d5c2cc..a9f4ecac0fc 100644 --- a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java +++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCard.java @@ -33,9 +33,6 @@ import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; -import java.awt.print.PageFormat; -import java.awt.print.Printable; -import java.awt.print.PrinterException; import java.time.LocalDate; import java.util.Locale; @@ -53,7 +50,7 @@ * for Large Aerospace units the specific class can be used to have additional functionality for the two * card faces of these cards. */ -public class ASCard implements Printable { +public class ASCard { public final static int WIDTH = 1050; public final static int HEIGHT = 750; @@ -559,19 +556,4 @@ private Image getFluffImage(ASCardDisplayable element) { return null; } } - - @Override - public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { - if (pageIndex == 0) { - Graphics2D g2D = (Graphics2D) graphics; - double height = 2.5 * 72; - g2D.translate(pageFormat.getWidth() / 2, pageFormat.getHeight() / 2 - height / 2); - g2D.scale(ASCard.PRINT_SCALE, ASCard.PRINT_SCALE); - g2D.translate(-WIDTH / 2, 0); - drawCard(graphics); - return PAGE_EXISTS; - } else { - return NO_SUCH_PAGE; - } - } } \ No newline at end of file diff --git a/megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java similarity index 62% rename from megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java rename to megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java index 7b5050a0b1c..9503cbafe0d 100644 --- a/megamek/src/megamek/client/ui/swing/alphaStrike/ASElementPrinter.java +++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved. * * This file is part of MegaMek. * @@ -16,35 +16,40 @@ * You should have received a copy of the GNU General Public License * along with MegaMek. If not, see . */ -package megamek.client.ui.swing.alphaStrike; +package megamek.common.alphaStrike.cardDrawer; import megamek.MMConstants; import megamek.client.ui.swing.GUIPreferences; +import megamek.client.ui.swing.util.UIUtil; import megamek.codeUtilities.StringUtility; import megamek.common.alphaStrike.ASCardDisplayable; -import megamek.common.alphaStrike.cardDrawer.ASCard; -import megamek.common.alphaStrike.cardDrawer.ASLargeAeroCard; +import javax.swing.*; +import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.geom.AffineTransform; import java.awt.print.PageFormat; import java.awt.print.Printable; import java.awt.print.PrinterException; +import java.awt.print.PrinterJob; import java.util.ArrayList; import java.util.Collection; import java.util.List; -public class ASElementPrinter { +public class ASCardPrinter implements Printable { + private final JFrame parent; private final List cardSlots = new ArrayList<>(); + private ProgressPopup progressPopup; private int row; private int column; private AffineTransform baseTransform; private int columnCount = 2; private int rowCount = 4; - public ASElementPrinter(Collection elements) { + public ASCardPrinter(Collection elements, JFrame parent) { Font userSelectedFont = userSelectedFont(); + this.parent = parent; for (ASCardDisplayable element : elements) { ASCard card = ASCard.createCard(element); card.setFont(userSelectedFont); @@ -55,6 +60,60 @@ public ASElementPrinter(Collection elements) { } } + public void printCards() { + PrinterJob job = PrinterJob.getPrinterJob(); + job.setPrintable(this); + boolean doPrint = job.printDialog(); + if (doPrint) { + progressPopup = new ProgressPopup(cardSlots.size(), parent); + progressPopup.setVisible(true); + new PrintCardTask(job).execute(); + } + } + + private class PrintCardTask extends SwingWorker { + + private final PrinterJob job; + + PrintCardTask(PrinterJob job) { + this.job = job; + } + + @Override + protected Void doInBackground() throws Exception { + try { + job.print(); + } catch (PrinterException ex) { + JOptionPane.showMessageDialog(parent, ex.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE); + } + return null; + } + + @Override + protected void done() { + progressPopup.setVisible(false); + } + } + + private static class ProgressPopup extends JDialog { + private final JProgressBar progressBar = new JProgressBar(); + + ProgressPopup(int maximum, JFrame parent) { + super(parent, "Print Cards"); + progressBar.setMaximum(maximum); + progressBar.setStringPainted(true); + progressBar.setBorder(new EmptyBorder(20, 40, 20, 40)); + getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS)); + add(Box.createVerticalStrut(20)); + add(new JLabel("Printing Alpha Strike Cards...", JLabel.CENTER)); + add(progressBar); + + UIUtil.adjustDialog(ProgressPopup.this, UIUtil.FONT_SCALE1); + setLocationRelativeTo(null); + pack(); + } + } + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { double height = 2.5 * 72; @@ -80,6 +139,9 @@ public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) elementIndex++; } + final int doneCards = elementIndex; + SwingUtilities.invokeLater(() -> + progressPopup.progressBar.setValue(doneCards)); return Printable.PAGE_EXISTS; } else { return Printable.NO_SUCH_PAGE; From 87dfdc05fd807f2aeb1eb5a2626f8d914b6f10f0 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 26 Feb 2023 18:15:32 +0100 Subject: [PATCH 3/4] AS Card Printing: Code comments --- .../alphaStrike/ConfigurableASCardPanel.java | 4 +--- .../alphaStrike/cardDrawer/ASCardPrinter.java | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java b/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java index 12b132a4331..502267dd9a8 100644 --- a/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java +++ b/megamek/src/megamek/client/ui/swing/alphaStrike/ConfigurableASCardPanel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2022-2023 - The MegaMek Team. All Rights Reserved. * * This file is part of MegaMek. * @@ -34,8 +34,6 @@ import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; -import java.awt.print.PrinterException; -import java.awt.print.PrinterJob; import java.net.URL; import java.util.List; diff --git a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java index 9503cbafe0d..e4abd9b478b 100644 --- a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java +++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 - The MegaMek Team. All Rights Reserved. + * Copyright (c) 2022-2023 - The MegaMek Team. All Rights Reserved. * * This file is part of MegaMek. * @@ -36,6 +36,11 @@ import java.util.Collection; import java.util.List; +/** + * This class prints a collection of one or more Alpha Strike cards. The cards to be printed can be created + * from either an {@link megamek.common.alphaStrike.AlphaStrikeElement} or a {@link megamek.common.MechSummary}. + * It shows a progress bar dialog but the printing happens in the background and the calling window is not blocked. + */ public class ASCardPrinter implements Printable { private final JFrame parent; @@ -47,6 +52,11 @@ public class ASCardPrinter implements Printable { private int columnCount = 2; private int rowCount = 4; + /** + * Creates a new ASCardPrinter object for the given ASCardDisplayable elements (either + * {@link megamek.common.alphaStrike.AlphaStrikeElement} or {@link megamek.common.MechSummary}. + * The parent is used for the progress dialog. Print the cards by calling {@link #printCards()}. + */ public ASCardPrinter(Collection elements, JFrame parent) { Font userSelectedFont = userSelectedFont(); this.parent = parent; @@ -60,6 +70,11 @@ public ASCardPrinter(Collection elements, JFrame pa } } + /** + * Starts a printing process for the carsd of this ASCardPrinter. This will display the usual printer + * selection dialog and a progress dialog. Printing itself happens in the background and the progress + * dialog can be closed. + */ public void printCards() { PrinterJob job = PrinterJob.getPrinterJob(); job.setPrintable(this); From e46c54e254be876345537a951ce69a478b7e57da Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 27 Feb 2023 17:50:15 +0100 Subject: [PATCH 4/4] AS Card Printing: More code comments and annotation --- .../common/alphaStrike/cardDrawer/ASCardPrinter.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java index e4abd9b478b..d1488e3e6c9 100644 --- a/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java +++ b/megamek/src/megamek/common/alphaStrike/cardDrawer/ASCardPrinter.java @@ -49,6 +49,8 @@ public class ASCardPrinter implements Printable { private int row; private int column; private AffineTransform baseTransform; + + // The column and row count depend on the page format of a given print job and are set anew for each print call private int columnCount = 2; private int rowCount = 4; @@ -129,8 +131,8 @@ private static class ProgressPopup extends JDialog { } } - public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) - throws PrinterException { + @Override + public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException { double height = 2.5 * 72; rowCount = (int) (pageFormat.getImageableHeight() / height); columnCount = (int) (pageFormat.getImageableWidth() / (3.5 * 72)); @@ -178,6 +180,7 @@ private boolean isPageIndexValid(int pageIndex) { return cardSlots.size() > pageStartSlotIndex(pageIndex); } + /** Sets the translate in the given g2D to the given card slot, going down the first column, then the second... */ private void goToPrintSlot(int slot, Graphics2D g2D) { g2D.setTransform(baseTransform); column = slot / rowCount; @@ -185,6 +188,7 @@ private void goToPrintSlot(int slot, Graphics2D g2D) { g2D.translate(-ASCard.WIDTH * columnCount / 2 + ASCard.WIDTH * column, ASCard.HEIGHT * row); } + /** Holds the card for a card slot on the page together with the info if this is the front or back side. */ private static class CardSlot { ASCard card; boolean flipSide;