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 → KILLED |
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 |