1 | package com.jsql.view.swing.ui; | |
2 | ||
3 | import com.jsql.util.I18nUtil; | |
4 | ||
5 | import javax.swing.*; | |
6 | import javax.swing.border.Border; | |
7 | import javax.swing.border.CompoundBorder; | |
8 | import java.awt.*; | |
9 | ||
10 | /** | |
11 | * The ComponentBorder class allows you to place a real component in | |
12 | * the space reserved for painting the Border of a component. | |
13 | * | |
14 | * This class takes advantage of the knowledge that all Swing components are | |
15 | * also Containers. By default, the layout manager is null, so we should be | |
16 | * able to place a child component anywhere in the parent component. In order | |
17 | * to prevent the child component from painting over top of the parent | |
18 | * component a Border is added to the parent component such that the insets of | |
19 | * the Border will reserve space for the child component to be painted without | |
20 | * affecting the parent component. | |
21 | */ | |
22 | public class ComponentBorder implements Border { | |
23 | | |
24 | public enum Edge { | |
25 | TOP, | |
26 | LEFT, | |
27 | BOTTOM, | |
28 | RIGHT | |
29 | } | |
30 | ||
31 | public static final float LEADING = 0.0f; | |
32 | public static final float CENTER = 0.5f; | |
33 | public static final float TRAILING = 1.0f; | |
34 | ||
35 | private JComponent parent; | |
36 | private final JComponent component; | |
37 | private Edge edge; | |
38 | private float alignment; | |
39 | private int gap = 5; | |
40 | private boolean adjustInsets = true; | |
41 | private Insets borderInsets = new Insets(0, 0, 0, 0); | |
42 | | |
43 | private int addX; | |
44 | private int addY; | |
45 | ||
46 | /** | |
47 | * Convenience constructor that uses the default edge (Edge.RIGHT) and | |
48 | * alignment (CENTER). | |
49 | * @param component the component to be added in the Border area | |
50 | */ | |
51 | public ComponentBorder(JComponent component) { | |
52 | this(component, Edge.RIGHT); | |
53 | } | |
54 | ||
55 | public ComponentBorder(JComponent component, int addX, int addY) { | |
56 | | |
57 | this(component, Edge.RIGHT); | |
58 | ||
59 | this.addX = addX; | |
60 | this.addY = addY; | |
61 | } | |
62 | ||
63 | /** | |
64 | * Convenience constructor that uses the default alignment (CENTER). | |
65 | * @param component the component to be added in the Border area | |
66 | * @param edge a valid Edge enum of TOP, LEFT, BOTTOM, RIGHT | |
67 | */ | |
68 | public ComponentBorder(JComponent component, Edge edge) { | |
69 | this(component, edge, CENTER); | |
70 | } | |
71 | ||
72 | /** | |
73 | * Main constructor to create a ComponentBorder. | |
74 | * @param component the component to be added in the Border area | |
75 | * @param edge a valid Edge enum of TOP, LEFT, BOTTOM, RIGHT | |
76 | * @param alignment the alignment of the component along the | |
77 | * specified Edge. Must be in the range 0 - 1.0. | |
78 | */ | |
79 | public ComponentBorder(JComponent component, Edge edge, float alignment) { | |
80 | | |
81 | this.component = component; | |
82 |
1
1. <init> : removed call to javax/swing/JComponent::setSize → NO_COVERAGE |
component.setSize(component.getPreferredSize()); |
83 |
1
1. <init> : removed call to javax/swing/JComponent::setCursor → NO_COVERAGE |
component.setCursor(Cursor.getDefaultCursor()); |
84 |
1
1. <init> : removed call to com/jsql/view/swing/ui/ComponentBorder::setEdge → NO_COVERAGE |
this.setEdge(edge); |
85 |
1
1. <init> : removed call to com/jsql/view/swing/ui/ComponentBorder::setAlignment → NO_COVERAGE |
this.setAlignment(alignment); |
86 | } | |
87 | ||
88 | public boolean isAdjustInsets() { | |
89 |
2
1. isAdjustInsets : replaced boolean return with false for com/jsql/view/swing/ui/ComponentBorder::isAdjustInsets → NO_COVERAGE 2. isAdjustInsets : replaced boolean return with true for com/jsql/view/swing/ui/ComponentBorder::isAdjustInsets → NO_COVERAGE |
return this.adjustInsets; |
90 | } | |
91 | ||
92 | public void setAdjustInsets(boolean adjustInsets) { | |
93 | this.adjustInsets = adjustInsets; | |
94 | } | |
95 | ||
96 | /** | |
97 | * Get the component alignment along the Border Edge. | |
98 | * @return the alignment | |
99 | */ | |
100 | public float getAlignment() { | |
101 |
1
1. getAlignment : replaced float return with 0.0f for com/jsql/view/swing/ui/ComponentBorder::getAlignment → NO_COVERAGE |
return this.alignment; |
102 | } | |
103 | ||
104 | /** | |
105 | * Set the component alignment along the Border Edge. | |
106 | * @param alignment a value in the range 0 - 1.0. Standard values would be | |
107 | * CENTER (default), LEFT and RIGHT. | |
108 | */ | |
109 | public void setAlignment(float alignment) { | |
110 | | |
111 |
2
1. setAlignment : negated conditional → NO_COVERAGE 2. setAlignment : changed conditional boundary → NO_COVERAGE |
if (alignment > 1.0f) { |
112 | | |
113 | this.alignment = 1.0f; | |
114 | | |
115 | } else { | |
116 | ||
117 | this.alignment = Math.max(alignment, 0.0f); | |
118 | } | |
119 | } | |
120 | ||
121 | /** | |
122 | * Get the Edge the component is positioned along. | |
123 | * @return the Edge | |
124 | */ | |
125 | public Edge getEdge() { | |
126 |
1
1. getEdge : replaced return value with null for com/jsql/view/swing/ui/ComponentBorder::getEdge → NO_COVERAGE |
return this.edge; |
127 | } | |
128 | ||
129 | /** | |
130 | * Set the Edge the component is positioned along. | |
131 | * @param edge the Edge the component is position on. | |
132 | */ | |
133 | public void setEdge(Edge edge) { | |
134 | this.edge = edge; | |
135 | } | |
136 | ||
137 | /** | |
138 | * Get the gap between the border component and the parent component. | |
139 | * @return the gap in pixels. | |
140 | */ | |
141 | public int getGap() { | |
142 |
1
1. getGap : replaced int return with 0 for com/jsql/view/swing/ui/ComponentBorder::getGap → NO_COVERAGE |
return this.gap; |
143 | } | |
144 | ||
145 | /** | |
146 | * Set the gap between the border component and the parent component. | |
147 | * @param gap the gap in pixels (default is 5) | |
148 | */ | |
149 | public void setGap(int gap) { | |
150 | this.gap = gap; | |
151 | } | |
152 | ||
153 | @Override | |
154 | public Insets getBorderInsets(Component c) { | |
155 |
1
1. getBorderInsets : replaced return value with null for com/jsql/view/swing/ui/ComponentBorder::getBorderInsets → NO_COVERAGE |
return this.borderInsets; |
156 | } | |
157 | ||
158 | @Override | |
159 | public boolean isBorderOpaque() { | |
160 |
1
1. isBorderOpaque : replaced boolean return with true for com/jsql/view/swing/ui/ComponentBorder::isBorderOpaque → NO_COVERAGE |
return false; |
161 | } | |
162 | ||
163 | /** | |
164 | * In this case a real component is to be painted. Setting the location | |
165 | * of the component will cause it to be painted at that location. | |
166 | */ | |
167 | @Override | |
168 | public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { | |
169 | | |
170 |
1
1. paintBorder : negated conditional → NO_COVERAGE |
float x2 = ComponentOrientation.RIGHT_TO_LEFT.equals(ComponentOrientation.getOrientation(I18nUtil.getLocaleDefault())) |
171 |
2
1. paintBorder : Replaced float multiplication with division → NO_COVERAGE 2. paintBorder : Replaced float addition with subtraction → NO_COVERAGE |
? this.component.getWidth() * this.component.getAlignmentX() + x |
172 |
3
1. paintBorder : Replaced float multiplication with division → NO_COVERAGE 2. paintBorder : Replaced integer subtraction with addition → NO_COVERAGE 3. paintBorder : Replaced float addition with subtraction → NO_COVERAGE |
: (width - this.component.getWidth()) * this.component.getAlignmentX() + x; |
173 | | |
174 |
3
1. paintBorder : Replaced float addition with subtraction → NO_COVERAGE 2. paintBorder : Replaced integer subtraction with addition → NO_COVERAGE 3. paintBorder : Replaced float multiplication with division → NO_COVERAGE |
float y2 = (height - this.component.getHeight()) * this.component.getAlignmentY() + y; |
175 | | |
176 |
3
1. paintBorder : removed call to javax/swing/JComponent::setLocation → NO_COVERAGE 2. paintBorder : Replaced integer addition with subtraction → NO_COVERAGE 3. paintBorder : Replaced integer addition with subtraction → NO_COVERAGE |
this.component.setLocation((int) x2 + this.addX, (int) y2 + this.addY); |
177 | } | |
178 | ||
179 | /** | |
180 | * Install this Border on the specified component by replacing the | |
181 | * existing Border with a CompoundBorder containing the original Border | |
182 | * and our ComponentBorder | |
183 | * | |
184 | * This method should only be invoked once all the properties of this | |
185 | * class have been set. Installing the Border more than once will cause | |
186 | * unpredictable results. | |
187 | */ | |
188 | public void install(JComponent parent) { | |
189 | | |
190 | this.parent = parent; | |
191 | ||
192 |
1
1. install : removed call to com/jsql/view/swing/ui/ComponentBorder::determineInsetsAndAlignment → NO_COVERAGE |
this.determineInsetsAndAlignment(); |
193 | ||
194 | // Add this Border to the parent | |
195 | var current = parent.getBorder(); | |
196 | ||
197 |
1
1. install : negated conditional → NO_COVERAGE |
if (current == null) { |
198 |
1
1. install : removed call to javax/swing/JComponent::setBorder → NO_COVERAGE |
parent.setBorder(this); |
199 | } else { | |
200 | | |
201 | var compound = new CompoundBorder(current, this); | |
202 |
1
1. install : removed call to javax/swing/JComponent::setBorder → NO_COVERAGE |
parent.setBorder(compound); |
203 | } | |
204 | ||
205 | // Add component to the parent | |
206 | parent.add(this.component); | |
207 | } | |
208 | ||
209 | /** | |
210 | * The insets need to be determined so they are included in the preferred | |
211 | * size of the component the Border is attached to. | |
212 | * | |
213 | * The alignment of the component is determined here so it doesn't need | |
214 | * to be recalculated every time the Border is painted. | |
215 | */ | |
216 | private void determineInsetsAndAlignment() { | |
217 | | |
218 | this.borderInsets = new Insets(0, 0, 0, 0); | |
219 | ||
220 | // The insets will only be updated for the edge the component will be | |
221 | // displayed on. | |
222 | // | |
223 | // The X, Y alignment of the component is controlled by both the edge | |
224 | // and alignment parameters | |
225 |
1
1. determineInsetsAndAlignment : negated conditional → NO_COVERAGE |
if (this.edge == Edge.TOP) { |
226 | | |
227 |
1
1. determineInsetsAndAlignment : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.top = this.component.getPreferredSize().height + this.gap; |
228 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentX → NO_COVERAGE |
this.component.setAlignmentX(this.alignment); |
229 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentY → NO_COVERAGE |
this.component.setAlignmentY(0.0f); |
230 | | |
231 |
1
1. determineInsetsAndAlignment : negated conditional → NO_COVERAGE |
} else if (this.edge == Edge.BOTTOM) { |
232 | | |
233 |
1
1. determineInsetsAndAlignment : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.bottom = this.component.getPreferredSize().height + this.gap; |
234 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentX → NO_COVERAGE |
this.component.setAlignmentX(this.alignment); |
235 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentY → NO_COVERAGE |
this.component.setAlignmentY(1.0f); |
236 | | |
237 |
1
1. determineInsetsAndAlignment : negated conditional → NO_COVERAGE |
} else if (this.edge == Edge.LEFT) { |
238 | | |
239 |
1
1. determineInsetsAndAlignment : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.left = this.component.getPreferredSize().width + this.gap; |
240 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentX → NO_COVERAGE |
this.component.setAlignmentX(0.0f); |
241 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentY → NO_COVERAGE |
this.component.setAlignmentY(this.alignment); |
242 | | |
243 |
1
1. determineInsetsAndAlignment : negated conditional → NO_COVERAGE |
} else if (this.edge == Edge.RIGHT) { |
244 | | |
245 |
1
1. determineInsetsAndAlignment : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.right = this.component.getPreferredSize().width + this.gap; |
246 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentX → NO_COVERAGE |
this.component.setAlignmentX(1.0f); |
247 |
1
1. determineInsetsAndAlignment : removed call to javax/swing/JComponent::setAlignmentY → NO_COVERAGE |
this.component.setAlignmentY(this.alignment); |
248 | } | |
249 | ||
250 |
1
1. determineInsetsAndAlignment : negated conditional → NO_COVERAGE |
if (this.adjustInsets) { |
251 |
1
1. determineInsetsAndAlignment : removed call to com/jsql/view/swing/ui/ComponentBorder::adjustBorderInsets → NO_COVERAGE |
this.adjustBorderInsets(); |
252 | } | |
253 | } | |
254 | ||
255 | /** | |
256 | * The complimentary edges of the Border may need to be adjusted to allow | |
257 | * the component to fit completely in the bounds of the parent component. | |
258 | */ | |
259 | private void adjustBorderInsets() { | |
260 | | |
261 | var parentInsets = this.parent.getInsets(); | |
262 | ||
263 | // May need to adjust the height of the parent component to fit | |
264 | // the component in the Border | |
265 |
2
1. adjustBorderInsets : negated conditional → NO_COVERAGE 2. adjustBorderInsets : negated conditional → NO_COVERAGE |
if (this.edge == Edge.RIGHT || this.edge == Edge.LEFT) { |
266 | | |
267 |
2
1. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE 2. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE |
int parentHeight = this.parent.getPreferredSize().height - parentInsets.top - parentInsets.bottom; |
268 |
1
1. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE |
int diff = this.component.getHeight() - parentHeight; |
269 | ||
270 |
2
1. adjustBorderInsets : changed conditional boundary → NO_COVERAGE 2. adjustBorderInsets : negated conditional → NO_COVERAGE |
if (diff > 0) { |
271 |
1
1. adjustBorderInsets : Replaced float multiplication with division → NO_COVERAGE |
int topDiff = (int) (diff * this.alignment); |
272 |
1
1. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE |
int bottomDiff = diff - topDiff; |
273 |
1
1. adjustBorderInsets : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.top += topDiff; |
274 |
1
1. adjustBorderInsets : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.bottom += bottomDiff; |
275 | } | |
276 | } | |
277 | ||
278 | // May need to adjust the width of the parent component to fit | |
279 | // the component in the Border | |
280 |
2
1. adjustBorderInsets : negated conditional → NO_COVERAGE 2. adjustBorderInsets : negated conditional → NO_COVERAGE |
if (this.edge == Edge.TOP || this.edge == Edge.BOTTOM) { |
281 | | |
282 |
2
1. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE 2. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE |
int parentWidth = this.parent.getPreferredSize().width - parentInsets.left - parentInsets.right; |
283 |
1
1. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE |
int diff = this.component.getWidth() - parentWidth; |
284 | ||
285 |
2
1. adjustBorderInsets : changed conditional boundary → NO_COVERAGE 2. adjustBorderInsets : negated conditional → NO_COVERAGE |
if (diff > 0) { |
286 |
1
1. adjustBorderInsets : Replaced float multiplication with division → NO_COVERAGE |
int leftDiff = (int) (diff * this.alignment); |
287 |
1
1. adjustBorderInsets : Replaced integer subtraction with addition → NO_COVERAGE |
int rightDiff = diff - leftDiff; |
288 |
1
1. adjustBorderInsets : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.left += leftDiff; |
289 |
1
1. adjustBorderInsets : Replaced integer addition with subtraction → NO_COVERAGE |
this.borderInsets.right += rightDiff; |
290 | } | |
291 | } | |
292 | } | |
293 | } | |
Mutations | ||
82 |
1.1 |
|
83 |
1.1 |
|
84 |
1.1 |
|
85 |
1.1 |
|
89 |
1.1 2.2 |
|
101 |
1.1 |
|
111 |
1.1 2.2 |
|
126 |
1.1 |
|
142 |
1.1 |
|
155 |
1.1 |
|
160 |
1.1 |
|
170 |
1.1 |
|
171 |
1.1 2.2 |
|
172 |
1.1 2.2 3.3 |
|
174 |
1.1 2.2 3.3 |
|
176 |
1.1 2.2 3.3 |
|
192 |
1.1 |
|
197 |
1.1 |
|
198 |
1.1 |
|
202 |
1.1 |
|
225 |
1.1 |
|
227 |
1.1 |
|
228 |
1.1 |
|
229 |
1.1 |
|
231 |
1.1 |
|
233 |
1.1 |
|
234 |
1.1 |
|
235 |
1.1 |
|
237 |
1.1 |
|
239 |
1.1 |
|
240 |
1.1 |
|
241 |
1.1 |
|
243 |
1.1 |
|
245 |
1.1 |
|
246 |
1.1 |
|
247 |
1.1 |
|
250 |
1.1 |
|
251 |
1.1 |
|
265 |
1.1 2.2 |
|
267 |
1.1 2.2 |
|
268 |
1.1 |
|
270 |
1.1 2.2 |
|
271 |
1.1 |
|
272 |
1.1 |
|
273 |
1.1 |
|
274 |
1.1 |
|
280 |
1.1 2.2 |
|
282 |
1.1 2.2 |
|
283 |
1.1 |
|
285 |
1.1 2.2 |
|
286 |
1.1 |
|
287 |
1.1 |
|
288 |
1.1 |
|
289 |
1.1 |