1 | package com.jsql.view.swing.scrollpane; | |
2 | ||
3 | import com.jsql.util.LogLevelUtil; | |
4 | import com.jsql.view.swing.util.UiUtil; | |
5 | import org.apache.logging.log4j.LogManager; | |
6 | import org.apache.logging.log4j.Logger; | |
7 | ||
8 | import javax.swing.*; | |
9 | import javax.swing.plaf.basic.BasicScrollBarUI; | |
10 | import java.awt.*; | |
11 | ||
12 | public class LightScrollPane extends JComponent { | |
13 | | |
14 | /** | |
15 | * Log4j logger sent to view. | |
16 | */ | |
17 | private static final Logger LOGGER = LogManager.getRootLogger(); | |
18 | | |
19 | protected int scrollBarAlpha = 25; | |
20 | | |
21 | protected int scrollBarAlphaRollover = 100; | |
22 | | |
23 | private static final int THUMB_BORDER_SIZE = 0; | |
24 | | |
25 | public static final int THUMB_SIZE = 15; | |
26 | | |
27 | protected Color colorThumb = Color.DARK_GRAY; | |
28 | ||
29 | public final JScrollPane scrollPane; | |
30 | | |
31 | private final JScrollBar verticalScrollBar; | |
32 | | |
33 | private final JScrollBar horizontalScrollBar; | |
34 | ||
35 | /** | |
36 | * Create a scrollpane with top and left border for default component and a slide one. | |
37 | * A component slided to the right will normally hide the left border, JScrollPanePixelBorder fix this. | |
38 | * @param top Border top size | |
39 | * @param left Border left size | |
40 | * @param bottom Border bottom size | |
41 | * @param right Border right size | |
42 | * @param c Component to decorate | |
43 | */ | |
44 | public LightScrollPane(int top, int left, int bottom, int right, JComponent c) { | |
45 | | |
46 | this(c); | |
47 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane::setBorder → NO_COVERAGE |
this.setBorder(BorderFactory.createMatteBorder(top, left, bottom, right, UiUtil.COLOR_COMPONENT_BORDER)); |
48 | } | |
49 | | |
50 | public LightScrollPane(JComponent component) { | |
51 | | |
52 | this.scrollPane = new JScrollPanePixelBorder(component); | |
53 |
1
1. <init> : removed call to javax/swing/JScrollPane::setBorder → NO_COVERAGE |
this.scrollPane.setBorder(BorderFactory.createEmptyBorder()); |
54 | | |
55 | this.verticalScrollBar = this.scrollPane.getVerticalScrollBar(); | |
56 |
1
1. <init> : removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE |
this.verticalScrollBar.setVisible(false); |
57 |
1
1. <init> : removed call to javax/swing/JScrollBar::setOpaque → NO_COVERAGE |
this.verticalScrollBar.setOpaque(false); |
58 |
1
1. <init> : removed call to javax/swing/JScrollBar::setUI → NO_COVERAGE |
this.verticalScrollBar.setUI(new MyScrollBarUI()); |
59 | ||
60 | this.horizontalScrollBar = this.scrollPane.getHorizontalScrollBar(); | |
61 |
1
1. <init> : removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE |
this.horizontalScrollBar.setVisible(false); |
62 |
1
1. <init> : removed call to javax/swing/JScrollBar::setOpaque → NO_COVERAGE |
this.horizontalScrollBar.setOpaque(false); |
63 |
1
1. <init> : removed call to javax/swing/JScrollBar::setUI → NO_COVERAGE |
this.horizontalScrollBar.setUI(new MyScrollBarUI()); |
64 | ||
65 | var layeredPane = new JLayeredPane(); | |
66 |
1
1. <init> : removed call to javax/swing/JLayeredPane::setLayer → NO_COVERAGE |
layeredPane.setLayer(this.verticalScrollBar, JLayeredPane.PALETTE_LAYER); |
67 |
1
1. <init> : removed call to javax/swing/JLayeredPane::setLayer → NO_COVERAGE |
layeredPane.setLayer(this.horizontalScrollBar, JLayeredPane.PALETTE_LAYER); |
68 | ||
69 |
1
1. <init> : removed call to javax/swing/JScrollPane::setVerticalScrollBarPolicy → NO_COVERAGE |
this.scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); |
70 |
1
1. <init> : removed call to javax/swing/JScrollPane::setHorizontalScrollBarPolicy → NO_COVERAGE |
this.scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); |
71 |
1
1. <init> : removed call to javax/swing/JScrollPane::setLayout → NO_COVERAGE |
this.scrollPane.setLayout(new ScrollPaneLayout() { |
72 | | |
73 | @Override | |
74 | public void layoutContainer(Container parent) { | |
75 | | |
76 | // Fix #13412: NullPointerException on setBounds() | |
77 | // Fix #48549: IllegalStateException on setBounds() | |
78 | // Implementation by sun.swing.SwingUtilities2.getFontMetrics() | |
79 | try { | |
80 |
2
1. layoutContainer : removed call to javax/swing/JViewport::setBounds → NO_COVERAGE 2. layoutContainer : Replaced integer subtraction with addition → NO_COVERAGE |
this.viewport.setBounds(0, 0, LightScrollPane.this.getWidth(), LightScrollPane.this.getHeight() - 1); |
81 | } catch (NullPointerException e) { | |
82 | LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e); | |
83 | } | |
84 | | |
85 |
2
1. lambda$layoutContainer$0 : removed call to com/jsql/view/swing/scrollpane/LightScrollPane::displayScrollBarsIfNecessary → NO_COVERAGE 2. layoutContainer : removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE |
SwingUtilities.invokeLater(() -> LightScrollPane.this.displayScrollBarsIfNecessary(this.viewport)); |
86 | } | |
87 | }); | |
88 | | |
89 | layeredPane.add(this.horizontalScrollBar); | |
90 | layeredPane.add(this.verticalScrollBar); | |
91 | layeredPane.add(this.scrollPane); | |
92 | ||
93 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane::setLayout → NO_COVERAGE |
this.setLayout(new BorderLayout() { |
94 | | |
95 | @Override | |
96 | public void layoutContainer(Container target) { | |
97 | | |
98 |
1
1. layoutContainer : removed call to java/awt/BorderLayout::layoutContainer → NO_COVERAGE |
super.layoutContainer(target); |
99 | int width = LightScrollPane.this.getWidth(); | |
100 | int height = LightScrollPane.this.getHeight(); | |
101 | | |
102 |
1
1. layoutContainer : removed call to javax/swing/JScrollPane::setBounds → NO_COVERAGE |
LightScrollPane.this.scrollPane.setBounds(0, 0, width, height); |
103 | ||
104 | int scrollBarSize = THUMB_SIZE; | |
105 | int cornerOffset = | |
106 |
1
1. layoutContainer : negated conditional → NO_COVERAGE |
LightScrollPane.this.verticalScrollBar.isVisible() |
107 |
1
1. layoutContainer : negated conditional → NO_COVERAGE |
&& LightScrollPane.this.horizontalScrollBar.isVisible() |
108 | ? scrollBarSize | |
109 | : 0; | |
110 | | |
111 |
1
1. layoutContainer : negated conditional → NO_COVERAGE |
if (LightScrollPane.this.verticalScrollBar.isVisible()) { |
112 | | |
113 |
1
1. layoutContainer : removed call to javax/swing/JScrollBar::setBounds → NO_COVERAGE |
LightScrollPane.this.verticalScrollBar.setBounds( |
114 |
1
1. layoutContainer : negated conditional → NO_COVERAGE |
LightScrollPane.this.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT |
115 | ? 0 | |
116 |
2
1. layoutContainer : Replaced integer subtraction with addition → NO_COVERAGE 2. layoutContainer : Replaced integer subtraction with addition → NO_COVERAGE |
: width - scrollBarSize, |
117 | 0, | |
118 | scrollBarSize, | |
119 | height - cornerOffset | |
120 | ); | |
121 | } | |
122 | | |
123 |
1
1. layoutContainer : negated conditional → NO_COVERAGE |
if (LightScrollPane.this.horizontalScrollBar.isVisible()) { |
124 | | |
125 |
3
1. layoutContainer : Replaced integer subtraction with addition → NO_COVERAGE 2. layoutContainer : Replaced integer subtraction with addition → NO_COVERAGE 3. layoutContainer : removed call to javax/swing/JScrollBar::setBounds → NO_COVERAGE |
LightScrollPane.this.horizontalScrollBar.setBounds( |
126 | 0, | |
127 | height - scrollBarSize, | |
128 | width - cornerOffset, | |
129 | scrollBarSize | |
130 | ); | |
131 | } | |
132 | } | |
133 | }); | |
134 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane::add → NO_COVERAGE |
this.add(layeredPane, BorderLayout.CENTER); |
135 |
1
1. <init> : removed call to javax/swing/JLayeredPane::setBackground → NO_COVERAGE |
layeredPane.setBackground(Color.BLUE); |
136 | } | |
137 | ||
138 | private void displayScrollBarsIfNecessary(JViewport viewPort) { | |
139 | | |
140 |
1
1. displayScrollBarsIfNecessary : removed call to com/jsql/view/swing/scrollpane/LightScrollPane::displayVerticalScrollBarIfNecessary → NO_COVERAGE |
this.displayVerticalScrollBarIfNecessary(viewPort); |
141 |
1
1. displayScrollBarsIfNecessary : removed call to com/jsql/view/swing/scrollpane/LightScrollPane::displayHorizontalScrollBarIfNecessary → NO_COVERAGE |
this.displayHorizontalScrollBarIfNecessary(viewPort); |
142 | } | |
143 | ||
144 | private void displayVerticalScrollBarIfNecessary(JViewport viewPort) { | |
145 | | |
146 | Rectangle viewRect = viewPort.getViewRect(); | |
147 | Dimension viewSize = viewPort.getViewSize(); | |
148 |
2
1. displayVerticalScrollBarIfNecessary : changed conditional boundary → NO_COVERAGE 2. displayVerticalScrollBarIfNecessary : negated conditional → NO_COVERAGE |
boolean isDisplayingVerticalScrollBar = viewSize.getHeight() > viewRect.getHeight(); |
149 | | |
150 |
1
1. displayVerticalScrollBarIfNecessary : removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE |
this.verticalScrollBar.setVisible(isDisplayingVerticalScrollBar); |
151 | } | |
152 | ||
153 | private void displayHorizontalScrollBarIfNecessary(JViewport viewPort) { | |
154 | | |
155 | Rectangle viewRect = viewPort.getViewRect(); | |
156 | Dimension viewSize = viewPort.getViewSize(); | |
157 |
2
1. displayHorizontalScrollBarIfNecessary : changed conditional boundary → NO_COVERAGE 2. displayHorizontalScrollBarIfNecessary : negated conditional → NO_COVERAGE |
boolean isDisplayingHorizontalScrollBar = viewSize.getWidth() > viewRect.getWidth(); |
158 | | |
159 |
1
1. displayHorizontalScrollBarIfNecessary : removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE |
this.horizontalScrollBar.setVisible(isDisplayingHorizontalScrollBar); |
160 | } | |
161 | ||
162 | private static class MyScrollBarButton extends JButton { | |
163 | private MyScrollBarButton() { | |
164 | ||
165 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setOpaque → NO_COVERAGE |
this.setOpaque(false); |
166 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setFocusable → NO_COVERAGE |
this.setFocusable(false); |
167 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setFocusPainted → NO_COVERAGE |
this.setFocusPainted(false); |
168 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setBorderPainted → NO_COVERAGE |
this.setBorderPainted(false); |
169 |
1
1. <init> : removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setBorder → NO_COVERAGE |
this.setBorder(BorderFactory.createEmptyBorder()); |
170 | } | |
171 | } | |
172 | ||
173 | private class MyScrollBarUI extends BasicScrollBarUI { | |
174 | | |
175 | @Override | |
176 | protected JButton createDecreaseButton(int orientation) { | |
177 |
1
1. createDecreaseButton : replaced return value with null for com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarUI::createDecreaseButton → NO_COVERAGE |
return new MyScrollBarButton(); |
178 | } | |
179 | ||
180 | @Override | |
181 | protected JButton createIncreaseButton(int orientation) { | |
182 |
1
1. createIncreaseButton : replaced return value with null for com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarUI::createIncreaseButton → NO_COVERAGE |
return new MyScrollBarButton(); |
183 | } | |
184 | ||
185 | @Override | |
186 | protected void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) { | |
187 | // Nothing | |
188 | } | |
189 | ||
190 | @Override | |
191 | protected Dimension getMinimumThumbSize() { | |
192 |
1
1. getMinimumThumbSize : replaced return value with null for com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarUI::getMinimumThumbSize → NO_COVERAGE |
return new Dimension(THUMB_SIZE, 24 + 2*2); |
193 | } | |
194 | | |
195 | @Override | |
196 | protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) { | |
197 | | |
198 |
1
1. paintThumb : negated conditional → NO_COVERAGE |
int alpha = this.isThumbRollover() ? LightScrollPane.this.scrollBarAlphaRollover : LightScrollPane.this.scrollBarAlpha; |
199 | int orientation = this.scrollbar.getOrientation(); | |
200 |
1
1. paintThumb : Replaced integer addition with subtraction → NO_COVERAGE |
int x = thumbBounds.x + THUMB_BORDER_SIZE; |
201 |
1
1. paintThumb : Replaced integer addition with subtraction → NO_COVERAGE |
int y = thumbBounds.y + THUMB_BORDER_SIZE; |
202 | ||
203 |
1
1. paintThumb : negated conditional → NO_COVERAGE |
int width = orientation == Adjustable.VERTICAL |
204 | ? THUMB_SIZE | |
205 |
1
1. paintThumb : Replaced integer subtraction with addition → NO_COVERAGE |
: thumbBounds.width - THUMB_BORDER_SIZE * 2; |
206 | ||
207 | width = Math.max(width, THUMB_SIZE); | |
208 | ||
209 |
1
1. paintThumb : negated conditional → NO_COVERAGE |
int height = orientation == Adjustable.VERTICAL |
210 |
1
1. paintThumb : Replaced integer subtraction with addition → NO_COVERAGE |
? thumbBounds.height - THUMB_BORDER_SIZE * 2 |
211 | : THUMB_SIZE; | |
212 | ||
213 | height = Math.max(height, THUMB_SIZE); | |
214 | ||
215 | var graphics2D = (Graphics2D) g.create(); | |
216 |
1
1. paintThumb : removed call to java/awt/Graphics2D::setRenderingHint → NO_COVERAGE |
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
217 | | |
218 | // Fix macOS Color.DARK_GRAY and alpha incompatibility | |
219 | Color colorThumbAlpha; | |
220 | | |
221 | try { | |
222 | colorThumbAlpha = new Color(LightScrollPane.this.colorThumb.getRed(), LightScrollPane.this.colorThumb.getGreen(), LightScrollPane.this.colorThumb.getBlue(), alpha); | |
223 | } catch (NullPointerException e) { | |
224 | | |
225 | colorThumbAlpha = Color.GRAY; | |
226 | LOGGER.log(LogLevelUtil.IGNORE, e); | |
227 | } | |
228 | | |
229 |
1
1. paintThumb : removed call to java/awt/Graphics2D::setColor → NO_COVERAGE |
graphics2D.setColor(colorThumbAlpha); |
230 | | |
231 | // Unhandled NoClassDefFoundError #65554: Could not initialize class sun.dc.pr.Rasterizer | |
232 |
1
1. paintThumb : removed call to java/awt/Graphics2D::fillRect → NO_COVERAGE |
graphics2D.fillRect(x, y, width, height); |
233 | | |
234 |
1
1. paintThumb : removed call to java/awt/Graphics2D::dispose → NO_COVERAGE |
graphics2D.dispose(); |
235 | } | |
236 | } | |
237 | } | |
Mutations | ||
47 |
1.1 |
|
53 |
1.1 |
|
56 |
1.1 |
|
57 |
1.1 |
|
58 |
1.1 |
|
61 |
1.1 |
|
62 |
1.1 |
|
63 |
1.1 |
|
66 |
1.1 |
|
67 |
1.1 |
|
69 |
1.1 |
|
70 |
1.1 |
|
71 |
1.1 |
|
80 |
1.1 2.2 |
|
85 |
1.1 2.2 |
|
93 |
1.1 |
|
98 |
1.1 |
|
102 |
1.1 |
|
106 |
1.1 |
|
107 |
1.1 |
|
111 |
1.1 |
|
113 |
1.1 |
|
114 |
1.1 |
|
116 |
1.1 2.2 |
|
123 |
1.1 |
|
125 |
1.1 2.2 3.3 |
|
134 |
1.1 |
|
135 |
1.1 |
|
140 |
1.1 |
|
141 |
1.1 |
|
148 |
1.1 2.2 |
|
150 |
1.1 |
|
157 |
1.1 2.2 |
|
159 |
1.1 |
|
165 |
1.1 |
|
166 |
1.1 |
|
167 |
1.1 |
|
168 |
1.1 |
|
169 |
1.1 |
|
177 |
1.1 |
|
182 |
1.1 |
|
192 |
1.1 |
|
198 |
1.1 |
|
200 |
1.1 |
|
201 |
1.1 |
|
203 |
1.1 |
|
205 |
1.1 |
|
209 |
1.1 |
|
210 |
1.1 |
|
216 |
1.1 |
|
229 |
1.1 |
|
232 |
1.1 |
|
234 |
1.1 |