| 1 | package com.reallifedeveloper.tools.gis; | |
| 2 | ||
| 3 | import java.awt.Color; | |
| 4 | import java.awt.Graphics; | |
| 5 | import java.awt.Graphics2D; | |
| 6 | import java.awt.Paint; | |
| 7 | import java.awt.Rectangle; | |
| 8 | import java.awt.geom.AffineTransform; | |
| 9 | import java.util.ArrayList; | |
| 10 | import java.util.List; | |
| 11 | ||
| 12 | import javax.swing.JPanel; | |
| 13 | ||
| 14 | import org.checkerframework.checker.nullness.qual.Nullable; | |
| 15 | import org.geotools.geometry.jts.LiteShape; | |
| 16 | import org.locationtech.jts.geom.Envelope; | |
| 17 | import org.locationtech.jts.geom.Geometry; | |
| 18 | ||
| 19 | /** | |
| 20 | * A {@code JPanel} that draws {@code com.vividsolutions.jts.geom.Geometry} objects. | |
| 21 | * | |
| 22 | * @author RealLifeDeveloper | |
| 23 | */ | |
| 24 | public class GeometryDrawingPanel extends JPanel { | |
| 25 | ||
| 26 | private static final long serialVersionUID = 1L; | |
| 27 | ||
| 28 | private static final int MARGIN = 5; | |
| 29 | ||
| 30 | /** | |
| 31 | * The {@code Geometry} objects to draw. | |
| 32 | */ | |
| 33 | @SuppressWarnings("serial") // Java 21 warns about java.util.List not being serializable | |
| 34 | private final List<Geometry> geometries = new ArrayList<>(); | |
| 35 | ||
| 36 | /** | |
| 37 | * A transform that scales the geometries to fit the current panel size, and adds margins. | |
| 38 | */ | |
| 39 | private @Nullable AffineTransform geomToScreen; | |
| 40 | ||
| 41 | /** | |
| 42 | * Adds a {@code Geometry} object to be drawn. | |
| 43 | * | |
| 44 | * @param geometry the {@code Geometry} object to add | |
| 45 | */ | |
| 46 | public void addGeometry(Geometry geometry) { | |
| 47 | geometries.add(geometry); | |
| 48 | } | |
| 49 | ||
| 50 | /** | |
| 51 | * Removes all {@code Geometry} objects so that none are drawn. | |
| 52 | */ | |
| 53 | public void clearGeometries() { | |
| 54 |
1
1. clearGeometries : removed call to java/util/List::clear → RUN_ERROR |
geometries.clear(); |
| 55 | } | |
| 56 | ||
| 57 | @Override | |
| 58 | protected void paintComponent(Graphics g) { | |
| 59 |
1
1. paintComponent : removed call to javax/swing/JPanel::paintComponent → SURVIVED |
super.paintComponent(g); |
| 60 | ||
| 61 |
1
1. paintComponent : negated conditional → KILLED |
if (!geometries.isEmpty()) { |
| 62 |
1
1. paintComponent : removed call to com/reallifedeveloper/tools/gis/GeometryDrawingPanel::setTransform → SURVIVED |
setTransform(); |
| 63 | ||
| 64 | Graphics2D g2d = (Graphics2D) g; | |
| 65 | Paint defaultPaint = Color.BLUE; | |
| 66 | ||
| 67 | for (Geometry geom : geometries) { | |
| 68 | @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops") | |
| 69 | LiteShape shape = new LiteShape(geom, geomToScreen, false); | |
| 70 | ||
| 71 |
1
1. paintComponent : removed call to java/awt/Graphics2D::setPaint → KILLED |
g2d.setPaint(defaultPaint); |
| 72 |
1
1. paintComponent : removed call to java/awt/Graphics2D::draw → KILLED |
g2d.draw(shape); |
| 73 | } | |
| 74 | } | |
| 75 | } | |
| 76 | ||
| 77 | private void setTransform() { | |
| 78 | Envelope env = getGeometryBounds(); | |
| 79 | Rectangle visRect = getVisibleRect(); | |
| 80 |
4
1. setTransform : Replaced integer addition with subtraction → SURVIVED 2. setTransform : Replaced integer subtraction with addition → SURVIVED 3. setTransform : Replaced integer addition with subtraction → SURVIVED 4. setTransform : Replaced integer subtraction with addition → SURVIVED |
Rectangle drawingRect = new Rectangle(visRect.x + MARGIN, visRect.y + MARGIN, visRect.width - 2 * MARGIN, |
| 81 | visRect.height - 2 * MARGIN); | |
| 82 | ||
| 83 |
2
1. setTransform : Replaced double division with multiplication → SURVIVED 2. setTransform : Replaced double division with multiplication → SURVIVED |
double scale = Math.min(drawingRect.getWidth() / env.getWidth(), drawingRect.getHeight() / env.getHeight()); |
| 84 |
2
1. setTransform : Replaced double multiplication with division → SURVIVED 2. setTransform : Replaced double subtraction with addition → SURVIVED |
double xoff = MARGIN - scale * env.getMinX(); |
| 85 |
2
1. setTransform : Replaced double addition with subtraction → SURVIVED 2. setTransform : Replaced double multiplication with division → SURVIVED |
double yoff = MARGIN + scale * env.getMaxY(); |
| 86 |
1
1. setTransform : removed negation → SURVIVED |
geomToScreen = new AffineTransform(scale, 0, 0, -scale, xoff, yoff); |
| 87 | } | |
| 88 | ||
| 89 | private Envelope getGeometryBounds() { | |
| 90 | Envelope env = new Envelope(); | |
| 91 | for (Geometry geom : geometries) { | |
| 92 | Envelope geomEnv = geom.getEnvelopeInternal(); | |
| 93 |
1
1. getGeometryBounds : removed call to org/locationtech/jts/geom/Envelope::expandToInclude → SURVIVED |
env.expandToInclude(geomEnv); |
| 94 | } | |
| 95 | ||
| 96 |
1
1. getGeometryBounds : replaced return value with null for com/reallifedeveloper/tools/gis/GeometryDrawingPanel::getGeometryBounds → KILLED |
return env; |
| 97 | } | |
| 98 | } | |
Mutations | ||
| 54 |
1.1 |
|
| 59 |
1.1 |
|
| 61 |
1.1 |
|
| 62 |
1.1 |
|
| 71 |
1.1 |
|
| 72 |
1.1 |
|
| 80 |
1.1 2.2 3.3 4.4 |
|
| 83 |
1.1 2.2 |
|
| 84 |
1.1 2.2 |
|
| 85 |
1.1 2.2 |
|
| 86 |
1.1 |
|
| 93 |
1.1 |
|
| 96 |
1.1 |