LightScrollPane.java

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
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane::setBorder → NO_COVERAGE

53

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollPane::setBorder → NO_COVERAGE

56

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE

57

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollBar::setOpaque → NO_COVERAGE

58

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollBar::setUI → NO_COVERAGE

61

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE

62

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollBar::setOpaque → NO_COVERAGE

63

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollBar::setUI → NO_COVERAGE

66

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JLayeredPane::setLayer → NO_COVERAGE

67

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JLayeredPane::setLayer → NO_COVERAGE

69

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollPane::setVerticalScrollBarPolicy → NO_COVERAGE

70

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollPane::setHorizontalScrollBarPolicy → NO_COVERAGE

71

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JScrollPane::setLayout → NO_COVERAGE

80

1.1
Location : layoutContainer
Killed by : none
removed call to javax/swing/JViewport::setBounds → NO_COVERAGE

2.2
Location : layoutContainer
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

85

1.1
Location : lambda$layoutContainer$0
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane::displayScrollBarsIfNecessary → NO_COVERAGE

2.2
Location : layoutContainer
Killed by : none
removed call to javax/swing/SwingUtilities::invokeLater → NO_COVERAGE

93

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane::setLayout → NO_COVERAGE

98

1.1
Location : layoutContainer
Killed by : none
removed call to java/awt/BorderLayout::layoutContainer → NO_COVERAGE

102

1.1
Location : layoutContainer
Killed by : none
removed call to javax/swing/JScrollPane::setBounds → NO_COVERAGE

106

1.1
Location : layoutContainer
Killed by : none
negated conditional → NO_COVERAGE

107

1.1
Location : layoutContainer
Killed by : none
negated conditional → NO_COVERAGE

111

1.1
Location : layoutContainer
Killed by : none
negated conditional → NO_COVERAGE

113

1.1
Location : layoutContainer
Killed by : none
removed call to javax/swing/JScrollBar::setBounds → NO_COVERAGE

114

1.1
Location : layoutContainer
Killed by : none
negated conditional → NO_COVERAGE

116

1.1
Location : layoutContainer
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : layoutContainer
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

123

1.1
Location : layoutContainer
Killed by : none
negated conditional → NO_COVERAGE

125

1.1
Location : layoutContainer
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : layoutContainer
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

3.3
Location : layoutContainer
Killed by : none
removed call to javax/swing/JScrollBar::setBounds → NO_COVERAGE

134

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane::add → NO_COVERAGE

135

1.1
Location : <init>
Killed by : none
removed call to javax/swing/JLayeredPane::setBackground → NO_COVERAGE

140

1.1
Location : displayScrollBarsIfNecessary
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane::displayVerticalScrollBarIfNecessary → NO_COVERAGE

141

1.1
Location : displayScrollBarsIfNecessary
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane::displayHorizontalScrollBarIfNecessary → NO_COVERAGE

148

1.1
Location : displayVerticalScrollBarIfNecessary
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : displayVerticalScrollBarIfNecessary
Killed by : none
negated conditional → NO_COVERAGE

150

1.1
Location : displayVerticalScrollBarIfNecessary
Killed by : none
removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE

157

1.1
Location : displayHorizontalScrollBarIfNecessary
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : displayHorizontalScrollBarIfNecessary
Killed by : none
negated conditional → NO_COVERAGE

159

1.1
Location : displayHorizontalScrollBarIfNecessary
Killed by : none
removed call to javax/swing/JScrollBar::setVisible → NO_COVERAGE

165

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setOpaque → NO_COVERAGE

166

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setFocusable → NO_COVERAGE

167

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setFocusPainted → NO_COVERAGE

168

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setBorderPainted → NO_COVERAGE

169

1.1
Location : <init>
Killed by : none
removed call to com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarButton::setBorder → NO_COVERAGE

177

1.1
Location : createDecreaseButton
Killed by : none
replaced return value with null for com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarUI::createDecreaseButton → NO_COVERAGE

182

1.1
Location : createIncreaseButton
Killed by : none
replaced return value with null for com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarUI::createIncreaseButton → NO_COVERAGE

192

1.1
Location : getMinimumThumbSize
Killed by : none
replaced return value with null for com/jsql/view/swing/scrollpane/LightScrollPane$MyScrollBarUI::getMinimumThumbSize → NO_COVERAGE

198

1.1
Location : paintThumb
Killed by : none
negated conditional → NO_COVERAGE

200

1.1
Location : paintThumb
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

201

1.1
Location : paintThumb
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

203

1.1
Location : paintThumb
Killed by : none
negated conditional → NO_COVERAGE

205

1.1
Location : paintThumb
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

209

1.1
Location : paintThumb
Killed by : none
negated conditional → NO_COVERAGE

210

1.1
Location : paintThumb
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

216

1.1
Location : paintThumb
Killed by : none
removed call to java/awt/Graphics2D::setRenderingHint → NO_COVERAGE

229

1.1
Location : paintThumb
Killed by : none
removed call to java/awt/Graphics2D::setColor → NO_COVERAGE

232

1.1
Location : paintThumb
Killed by : none
removed call to java/awt/Graphics2D::fillRect → NO_COVERAGE

234

1.1
Location : paintThumb
Killed by : none
removed call to java/awt/Graphics2D::dispose → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1