cleanup (inspection "Java | Class structure | Utility class is not 'final'")
[idea/community.git] / platform / util / ui / src / com / intellij / util / ui / ScrollUtil.java
1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2
3 package com.intellij.util.ui;
4
5 import org.intellij.lang.annotations.JdkConstants;
6 import org.jetbrains.annotations.Nullable;
7
8 import javax.swing.*;
9 import java.awt.*;
10
11 /**
12  * @author Konstantin Bulenkov
13  */
14 public final class ScrollUtil {
15   private ScrollUtil() {}
16
17
18   @Nullable
19   public static JScrollPane findScrollPane(JComponent c) {
20     if (c == null) return null;
21     return UIUtil.findComponentOfType(c, JScrollPane.class);
22   }
23
24   @Nullable
25   public static JScrollBar findVerticalScrollBar(JComponent c) {
26     return findScrollBar(c, Adjustable.VERTICAL);
27   }
28
29   @Nullable
30   public static JScrollBar findHorizontalScrollBar(JComponent c) {
31     return findScrollBar(c, Adjustable.HORIZONTAL);
32   }
33
34   @Nullable
35   private static JScrollBar findScrollBar(JComponent c, @JdkConstants.AdjustableOrientation int orientation) {
36     if (c == null) return null;
37     if (c instanceof JScrollBar && ((JScrollBar)c).getOrientation() == orientation) {
38       return (JScrollBar)c;
39     }
40     for (Component comp : c.getComponents()) {
41       if (comp instanceof JComponent) {
42         final JScrollBar scrollBar = findScrollBar((JComponent)comp, orientation);
43         if (scrollBar != null) {
44           return scrollBar;
45         }
46       }
47     }
48     return null;
49   }
50
51   public static void scrollVertically(JComponent c, int position) {
52     final JScrollPane pane = findScrollPane(c);
53     if (pane != null) {
54       final JScrollBar bar = pane.getVerticalScrollBar();
55       if (bar != null) {
56         bar.setValue(position);
57       }
58     } else {
59       final JScrollBar scrollBar = findVerticalScrollBar(c);
60       if (scrollBar != null) {
61         scrollBar.setValue(position);
62       }
63     }
64   }
65
66   public static void scrollHorizontally(JComponent c, int position) {
67     final JScrollPane pane = findScrollPane(c);
68     if (pane != null) {
69       final JScrollBar bar = pane.getHorizontalScrollBar();
70       if (bar != null) {
71         bar.setValue(position);
72       }
73     } else {
74       final JScrollBar scrollBar = findHorizontalScrollBar(c);
75       if (scrollBar != null) {
76         scrollBar.setValue(position);
77       }
78     }
79   }
80
81   public static void center(final JComponent c, final Rectangle r) {
82     center(c, r, false);
83   }
84
85   public static void center(final JComponent c, final Rectangle r, final boolean withInsets) {
86     final Rectangle visible = c.getVisibleRect();
87     visible.x = r.x - (visible.width - r.width) / 2;
88     visible.y = r.y - (visible.height - r.height) / 2;
89
90     Rectangle bounds = new Rectangle(c.getWidth(), c.getHeight());
91     if (!withInsets) JBInsets.removeFrom(bounds, c.getInsets());
92
93     if (visible.x < bounds.x) {
94       visible.x = bounds.x;
95     }
96
97     if (visible.x + visible.width > bounds.x + bounds.width) {
98       visible.x = bounds.x + bounds.width - visible.width;
99     }
100
101     if (visible.y < bounds.y) {
102       visible.y = bounds.y;
103     }
104
105     if (visible.y + visible.height > bounds.y + bounds.height) {
106       visible.y = bounds.y + bounds.height - visible.height;
107     }
108
109     c.scrollRectToVisible(visible);
110   }
111
112   public enum ScrollBias {
113     /**
114      * take the policy of the viewport
115      */
116     VIEWPORT,
117     UNCHANGED,      // don't scroll if it fills the visible area, otherwise take the policy of the viewport
118     FIRST,          // scroll the first part of the region into view
119     CENTER,         // center the region
120     LAST           // scroll the last part of the region into view
121   }
122
123   public static void scroll(JComponent c, Rectangle r, ScrollBias horizontalBias, ScrollBias verticalBias) {
124     Rectangle visible = c.getVisibleRect();
125     Rectangle dest = new Rectangle(r);
126
127     if (dest.width > visible.width) {
128       if (horizontalBias == ScrollBias.VIEWPORT) {
129         // leave as is
130       }
131       else if (horizontalBias == ScrollBias.UNCHANGED) {
132         if (dest.x <= visible.x && dest.x + dest.width >= visible.x + visible.width) {
133           dest.width = visible.width;
134         }
135       }
136       else {
137         if (horizontalBias == ScrollBias.CENTER) {
138           dest.x += (dest.width - visible.width) / 2;
139         }
140         else if (horizontalBias == ScrollBias.LAST) dest.x += dest.width - visible.width;
141
142         dest.width = visible.width;
143       }
144     }
145
146     if (dest.height > visible.height) {
147       // same code as above in the other direction
148     }
149
150     if (!visible.contains(dest)) c.scrollRectToVisible(dest);
151   }
152 }