Ticket #14278: 14278-print-1.patch

File 14278-print-1.patch, 19.0 KB (added by hiddewie, 6 years ago)
  • src/org/openstreetmap/josm/plugins/print/PrintDialog.java

     
    2020import java.lang.reflect.Method;
    2121import java.lang.reflect.Modifier;
    2222import java.text.ParseException;
    23 import java.util.ArrayList;
    24 import java.util.Arrays;
    25 import java.util.Collection;
    26 import java.util.Iterator;
    27 import java.util.List;
    28 import java.util.Locale;
     23import java.util.*;
    2924
    3025import javax.print.PrintService;
    3126import javax.print.PrintServiceLookup;
     
    223218        mapView.setFixedMapScale(mapScale);
    224219        scaleModel = new SpinnerNumberModel(mapScale, 250, 5000000, 250);
    225220        final JSpinner scaleField = new JSpinner(scaleModel);
    226         scaleField.addChangeListener(new ChangeListener() {
    227             @Override
    228             public void stateChanged(ChangeEvent evt) {
    229                 SwingUtilities.invokeLater(new Runnable() {
    230                     @Override
    231                     public void run() {
    232                         try {
    233                             scaleField.commitEdit();
    234                             Config.getPref().put("print.map-scale", scaleModel.getNumber().toString());
    235                             mapView.setFixedMapScale(scaleModel.getNumber().intValue());
    236                             printPreview.repaint();
    237                         } catch (ParseException e) {
    238                             Logging.error(e);
    239                         }
    240                     }
    241                 });
     221        scaleField.addChangeListener(evt -> SwingUtilities.invokeLater(() -> {
     222            try {
     223                scaleField.commitEdit();
     224                Config.getPref().put("print.map-scale", scaleModel.getNumber().toString());
     225                mapView.setFixedMapScale(scaleModel.getNumber().intValue());
     226                printPreview.repaint();
     227            } catch (ParseException e) {
     228                Logging.error(e);
    242229            }
    243         });
     230        }));
    244231        add(scaleField, std.grid(GBC.RELATIVE, row));
    245232
    246233        row++;
     
    252239          Config.getPref().getInt("print.resolution.dpi", PrintPlugin.DEF_RESOLUTION_DPI),
    253240          30, 1200, 10);
    254241        final JSpinner resolutionField = new JSpinner(resolutionModel);
    255         resolutionField.addChangeListener(new ChangeListener() {
    256             @Override
    257             public void stateChanged(ChangeEvent evt) {
    258                 SwingUtilities.invokeLater(new Runnable() {
    259                     @Override
    260                     public void run() {
    261                         try {
    262                             resolutionField.commitEdit();
    263                             Config.getPref().put("print.resolution.dpi", resolutionModel.getNumber().toString());
    264                             printPreview.repaint();
    265                         } catch (ParseException e) {
    266                             Logging.error(e);
    267                         }
    268                     }
    269                 });
     242        resolutionField.addChangeListener(evt -> SwingUtilities.invokeLater(() -> {
     243            try {
     244                resolutionField.commitEdit();
     245                Config.getPref().put("print.resolution.dpi", resolutionModel.getNumber().toString());
     246                printPreview.repaint();
     247            } catch (ParseException e) {
     248                Logging.error(e);
    270249            }
    271         });
     250        }));
    272251        add(resolutionField, std.grid(GBC.RELATIVE, row));
    273252
    274253        row++;
     
    283262        attributionText.getDocument().addDocumentListener(new DocumentListener() {
    284263            @Override
    285264            public void insertUpdate(DocumentEvent evt) {
    286                 SwingUtilities.invokeLater(new Runnable() {
    287                     @Override
    288                     public void run() {
    289                         Config.getPref().put("print.attribution", attributionText.getText());
    290                         printPreview.repaint();
    291                     }
     265                SwingUtilities.invokeLater(() -> {
     266                    Config.getPref().put("print.attribution", attributionText.getText());
     267                    printPreview.repaint();
    292268                });
    293269            }
    294270
     
    469445        }
    470446
    471447        // Save all request attributes
    472         List<String> ignoredAttributes = Arrays.asList("media-printable-area");
     448        List<String> ignoredAttributes = Collections.singletonList("media-printable-area");
    473449        List<List<String>> requestAttributes = new ArrayList<>();
    474450        for (Attribute a : attrs.toArray()) {
    475451            List<String> setting = null;
  • src/org/openstreetmap/josm/plugins/print/PrintPlugin.java

     
    4545        int pos = fileMenu.getItemCount();
    4646        do {
    4747            pos--;
    48         } while (fileMenu != null && pos > 2 && fileMenu.getItem(pos) != null);
     48        } while (pos > 2 && fileMenu.getItem(pos) != null);
    4949
    5050        if (pos > 0) {
    5151            PrintAction printAction = new PrintAction();
     
    107107     * Saves the existing value for later restorePref.
    108108     *
    109109     * @param key the preference key
    110      * @param the temporary new int value
     110     * @param value the temporary new int value
    111111     */
    112112    protected static void adjustPref(String key, int value) {
    113113        if (!Config.getPref().get(key).isEmpty()) {
     
    122122     * Saves the existing value for later restorePref.
    123123     *
    124124     * @param key the preference key
    125      * @param the temporary new boolean value
     125     * @param value the temporary new boolean value
    126126     */
    127127    protected static void adjustPref(String key, boolean value) {
    128128        if (!Config.getPref().get(key).isEmpty()) {
     
    137137     * Saves the existing value for later restorePref.
    138138     *
    139139     * @param key the preference key
    140      * @param the temporary new String value
     140     * @param value the temporary new String value
    141141     */
    142142    protected static void adjustPref(String key, String value) {
    143143        if (!Config.getPref().get(key).isEmpty()) {
  • src/org/openstreetmap/josm/plugins/print/PrintableLayerManager.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.plugins.print;
    33
    4 import java.util.ArrayList;
    5 import java.util.Collections;
    64import java.util.Comparator;
    75import java.util.List;
     6import java.util.stream.Collectors;
    87
    98import org.openstreetmap.josm.data.osm.DataSet;
    109import org.openstreetmap.josm.gui.MainApplication;
     
    1413
    1514public class PrintableLayerManager extends MainLayerManager {
    1615
    17     private static final MainLayerManager layerManager = MainApplication.getLayerManager();
     16    private final MainLayerManager layerManager;
    1817
     18    PrintableLayerManager(MainLayerManager delegate) {
     19        this.layerManager = delegate;
     20    }
     21
    1922    @Override
    2023    public synchronized void removeActiveLayerChangeListener(ActiveLayerChangeListener listener) {
    2124        layerManager.removeActiveLayerChangeListener(listener);
     
    4346
    4447    @Override
    4548    public synchronized List<Layer> getVisibleLayersInZOrder() {
    46         ArrayList<Layer> layers = new ArrayList<>();
    47         for (Layer l: layerManager.getLayers()) {
    48             if (l.isVisible()) {
    49                 layers.add(l);
     49        final Comparator<Layer> layerComparator = (l2, l1) -> { // l1 and l2 swapped!
     50            if (l1 instanceof OsmDataLayer && l2 instanceof OsmDataLayer) {
     51                if (l1 == layerManager.getActiveLayer()) return -1;
     52                if (l2 == layerManager.getActiveLayer()) return 1;
    5053            }
    51         }
    52         Collections.sort(
    53             layers,
    54             new Comparator<Layer>() {
    55                 @Override
    56                 public int compare(Layer l2, Layer l1) { // l1 and l2 swapped!
    57                     if (l1 instanceof OsmDataLayer && l2 instanceof OsmDataLayer) {
    58                         if (l1 == layerManager.getActiveLayer()) return -1;
    59                         if (l2 == layerManager.getActiveLayer()) return 1;
    60                         return Integer.valueOf(layerManager.getLayers().indexOf(l1)).
    61                                      compareTo(layerManager.getLayers().indexOf(l2));
    62                     } else
    63                         return Integer.valueOf(layerManager.getLayers().indexOf(l1)).
    64                                      compareTo(layerManager.getLayers().indexOf(l2));
    65                 }
    66             }
    67         );
    68         return layers;
     54            return Integer.compare(layerManager.getLayers().indexOf(l1), layerManager.getLayers().indexOf(l2));
     55        };
     56
     57        return layerManager.getLayers().stream()
     58                .filter(Layer::isVisible)
     59                .sorted(layerComparator)
     60                .collect(Collectors.toList());
    6961    }
    7062
    7163    @Override
  • src/org/openstreetmap/josm/plugins/print/PrintableMapView.java

     
    1111import java.awt.Graphics;
    1212import java.awt.Graphics2D;
    1313import java.awt.Shape;
    14 import java.awt.event.ComponentListener;
    1514import java.awt.font.FontRenderContext;
    1615import java.awt.font.GlyphVector;
    1716import java.awt.geom.AffineTransform;
     
    1817import java.awt.geom.Rectangle2D;
    1918import java.awt.print.PageFormat;
    2019import java.awt.print.Printable;
    21 import java.awt.print.PrinterException;
     20import java.util.Arrays;
    2221
    2322import org.openstreetmap.gui.jmapviewer.tilesources.AbstractOsmTileSource;
    2423import org.openstreetmap.josm.data.Bounds;
     
    3029import org.openstreetmap.josm.gui.layer.LayerManager.LayerOrderChangeEvent;
    3130import org.openstreetmap.josm.gui.layer.LayerManager.LayerRemoveEvent;
    3231import org.openstreetmap.josm.spi.preferences.Config;
     32import org.openstreetmap.josm.tools.Logging;
    3333
    3434/**
    3535 * The PrintableMapView class implements a "Printable" perspective on
    3636 * the main MapView.
     37 *
    3738 * @author Kai Pastor
    3839 */
    3940public class PrintableMapView extends MapView implements Printable {
     
    5859     */
    5960    public PrintableMapView() {
    6061        /* Initialize MapView with a dummy parent */
    61         super(new PrintableLayerManager(), null);
     62        super(new PrintableLayerManager(MainApplication.getLayerManager()), null);
    6263
    6364        /* Disable MapView's ComponentLister,
    6465         * as it will interfere with the main MapView. */
    65         ComponentListener[] listeners = getComponentListeners();
    66         for (int i = 0; i < listeners.length; i++) {
    67             removeComponentListener(listeners[i]);
    68         }
     66        Arrays.stream(getComponentListeners())
     67                .forEach(this::removeComponentListener);
    6968    }
    7069
    7170    /**
     
    8079
    8180    /**
    8281     * Unset the fixed map scale
    83      *
     82     * <p>
    8483     * The map scaling will be chosen automatically such that the
    8584     * main windows map view fits on the page format.
    8685     */
     
    106105     * Initialize the PrintableMapView for a particular combination of
    107106     * main MapView, PageFormat and target resolution
    108107     *
    109      * @param pageformat the size and orientation of the page being drawn
     108     * @param pageFormat the size and orientation of the page being drawn
    110109     */
    111110    public void initialize(PageFormat pageFormat) {
    112111        int resolution = Config.getPref().getInt("print.resolution.dpi", PrintPlugin.DEF_RESOLUTION_DPI);
    113         g2dFactor = 72.0/resolution;
    114         setSize((int) (pageFormat.getImageableWidth()/g2dFactor), (int) (pageFormat.getImageableHeight()/g2dFactor));
     112        g2dFactor = 72.0 / resolution;
     113        setSize((int) (pageFormat.getImageableWidth() / g2dFactor), (int) (pageFormat.getImageableHeight() / g2dFactor));
    115114    }
    116115
    117116    /**
     
    154153
    155154    /**
    156155     * Render a page for the printer
    157      *
     156     * <p>
    158157     * Implements java.awt.print.Printable.
    159158     *
    160      * @param g the context into which the page is drawn
     159     * @param g          the context into which the page is drawn
    161160     * @param pageFormat the size and orientation of the page being drawn
    162      * @param page the zero based index of the page to be drawn
    163      *
     161     * @param page       the zero based index of the page to be drawn
    164162     * @return PAGE_EXISTS for page==0 or NO_SUCH_PAGE for page>0
    165      *
    166      * @throws PrinterException thrown when the print job is terminated
    167      *
    168163     */
    169164    @Override
    170     public int print(Graphics g, PageFormat pageFormat, int page) throws
    171                                                     PrinterException {
     165    public int print(Graphics g, PageFormat pageFormat, int page) {
    172166        if (page > 0) { /* stop after first page */
    173167            return NO_SUCH_PAGE;
    174168        }
    175169
     170        Logging.info("Page format " + pageFormat.getImageableX() + ", " + pageFormat.getImageableY() + ", width " + pageFormat.getWidth() +" height " + pageFormat.getHeight());
     171
    176172        initialize(pageFormat);
    177173
    178174        Graphics2D g2d = (Graphics2D) g;
    179175        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    180         paintMap(g2d, pageFormat);
    181         paintMapScale(g2d, pageFormat);
     176        paintMap(g2d);
     177        paintMapScale(g2d);
    182178        paintMapAttribution(g2d, pageFormat);
    183179        return PAGE_EXISTS;
    184180    }
     
    185181
    186182    /**
    187183     * Paint the map
    188      *
     184     * <p>
    189185     * This implementation is derived from MapView's paint and
    190186     * from other JOSM core components.
    191187     *
    192188     * @param g2d the graphics context to use for painting
    193      * @param pageFormat the size and orientation of the page being drawn
    194189     */
    195     public void paintMap(Graphics2D g2d, PageFormat pageFormat) {
    196         AffineTransform at = g2d.getTransform();
     190    public void paintMap(Graphics2D g2d) {
     191        AffineTransform originalTransform = g2d.getTransform();
    197192        g2d.scale(g2dFactor, g2dFactor);
    198193
    199         Bounds box = getRealBounds();
     194        Bounds box = MainApplication.getMap().mapView.getRealBounds();
    200195        for (Layer l : getLayerManager().getVisibleLayersInZOrder()) {
     196            paintLayer(l, g2d);
    201197            if (l.getOpacity() < 1) {
    202198                g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) l.getOpacity()));
    203199            }
     
    205201            g2d.setPaintMode();
    206202        }
    207203
    208         g2d.setTransform(at);
     204        g2d.setTransform(originalTransform);
    209205    }
    210206
    211207    /**
    212208     * Paint a linear scale and a lexical scale
    213      *
     209     * <p>
    214210     * This implementation is derived from JOSM's MapScaler,
    215211     * NavigatableComponent and SystemOfMeasurement.
    216212     *
    217213     * @param g2d the graphics context to use for painting
    218      * @param pageFormat the size and orientation of the page being drawn
    219214     */
    220     public void paintMapScale(Graphics2D g2d, PageFormat pageFormat) {
     215    public void paintMapScale(Graphics2D g2d) {
    221216        SystemOfMeasurement som = SystemOfMeasurement.getSystemOfMeasurement();
    222217        double dist100px = getDist100Pixel() / g2dFactor;
    223218        double dist = dist100px / som.aValue;
     
    243238
    244239        /* offset from the left paper border to the left end of the bar */
    245240        Rectangle2D bound = g2d.getFontMetrics().getStringBounds("0", g2d);
    246         int xLeft = (int) (bound.getWidth()/2);
     241        int xLeft = (int) (bound.getWidth() / 2);
    247242
    248243        /* offset from the left paper border to the right label */
    249244        String rightLabel = som.getDistText(dist100px * distScale);
    250245        bound = g2d.getFontMetrics().getStringBounds(rightLabel, g2d);
    251         int xRight = xLeft+(int) Math.max(0.95*x, x-bound.getWidth()/2);
     246        int xRight = xLeft + (int) Math.max(0.95 * x, x - bound.getWidth() / 2);
    252247
    253248        // CHECKSTYLE.OFF: SingleSpaceSeparator
    254         int h        = FONT_SIZE / 2; // raster, height of the bar
    255         int yLexical = 3 * h;         // baseline of the lexical scale
    256         int yBar     = 4 * h;         // top of the bar
    257         int yLabel   = 8 * h;         // baseline of the labels
    258         int w  = (int) (distScale * 100.0); // length of the bar
    259         int ws = (int) (distScale * 20.0);   // length of a segment
     249        int h = FONT_SIZE / 2;            // raster, height of the bar
     250        int yLexical = 3 * h;              // baseline of the lexical scale
     251        int yBar = 4 * h;                  // top of the bar
     252        int yLabel = 8 * h;                // baseline of the labels
     253        int w = (int) (distScale * 100.0); // length of the bar
     254        int ws = (int) (distScale * 20.0); // length of a segment
    260255        // CHECKSTYLE.ON: SingleSpaceSeparator
    261256
    262257        /* white background */
    263258        g2d.setColor(Color.WHITE);
    264         g2d.fillRect(xLeft-1, yBar-1, w+2, h+2);
     259        g2d.fillRect(xLeft - 1, yBar - 1, w + 2, h + 2);
    265260
    266261        /* black foreground */
    267262        g2d.setColor(Color.BLACK);
    268263        g2d.drawRect(xLeft, yBar, w, h);
    269264        g2d.fillRect(xLeft, yBar, ws, h);
    270         g2d.fillRect(xLeft+(int) (distScale * 40.0), yBar, ws, h);
    271         g2d.fillRect(xLeft+w-ws, yBar, ws, h);
     265        g2d.fillRect(xLeft + (int) (distScale * 40.0), yBar, ws, h);
     266        g2d.fillRect(xLeft + w - ws, yBar, ws, h);
    272267        g2d.setFont(labelFont);
    273268        paintText(g2d, "0", 0, yLabel);
    274269        paintText(g2d, rightLabel, xRight, yLabel);
     
    287282    /**
    288283     * Paint an attribution text
    289284     *
    290      * @param g2d the graphics context to use for painting
     285     * @param g2d        the graphics context to use for painting
    291286     * @param pageFormat the size and orientation of the page being drawn
    292287     */
    293288    public void paintMapAttribution(Graphics2D g2d, PageFormat pageFormat) {
     
    308303            String line = text.substring(from, to);
    309304
    310305            Rectangle2D bound = g2d.getFontMetrics().getStringBounds(line, g2d);
    311             int x = (int) ((pageFormat.getImageableWidth() - bound.getWidth()) - FONT_SIZE/2);
     306            int x = (int) ((pageFormat.getImageableWidth() - bound.getWidth()) - FONT_SIZE / 2);
    312307
    313308            paintText(g2d, line, x, y);
    314309
     
    320315
    321316    /**
    322317     * Paint a text.
    323      *
     318     * <p>
    324319     * This method will not only draw the letters but also a background which improves redability.
    325320     *
    326      * @param g2d the graphics context to use for painting
     321     * @param g2d  the graphics context to use for painting
    327322     * @param text the text to be drawn
    328      * @param x the x coordinate
    329      * @param y the y coordinate
     323     * @param x    the x coordinate
     324     * @param y    the y coordinate
    330325     */
    331326    public void paintText(Graphics2D g2d, String text, int x, int y) {
    332327        AffineTransform ax = g2d.getTransform();