From d97b48aa42e8b46da804659145f0c3b3c4e39310 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Fri, 13 Jun 2014 14:50:43 +0200 Subject: [PATCH] Platform: OS X scrollbars: removed JLayeredPane-hack to avoid problems like: IDEA-125075 Database tools navigation problems: PgUp / PgDown IDEA-122956 Popups in Project Structure dialog have wrong initial size sometimes The trick is to return 'false' isOptimizedDrawingEnabled when we have overlaid scrollbars (same trick is used by JLayeredPane) --- .../intellij/ui/components/JBScrollPane.java | 121 ++++-------------- .../src/com/intellij/ui/table/JBTable.java | 40 ------ 2 files changed, 28 insertions(+), 133 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java index e0c326ad1edb..90abce6c6091 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java @@ -33,7 +33,7 @@ import java.lang.reflect.Method; public class JBScrollPane extends JScrollPane { private int myViewportBorderWidth = -1; - private JLayeredPane myLayeredPane; + private boolean myHasOverlayScrollbars; public JBScrollPane(int viewportWidth) { init(false); @@ -64,89 +64,14 @@ public class JBScrollPane extends JScrollPane { if (c == null) return null; if (!(c instanceof JViewport)) { - // if asked for a viewport child, take a viewport. - // If not (e.g asked for a scrollbar), go straight to JLayeredPane Container vp = c.getParent(); if (vp instanceof JViewport) c = vp; } c = c.getParent(); - if (c instanceof JLayeredPane) { - c = c.getParent(); - } - if (!(c instanceof JBScrollPane)) return null; + if (!(c instanceof JScrollPane)) return null; - return (JBScrollPane)c; - } - - @Override - public void setVerticalScrollBar(JScrollBar c) { - JScrollBar old = getVerticalScrollBar(); - super.setVerticalScrollBar(c); - transferToLayeredPane(old, c, ScrollPaneConstants.VERTICAL_SCROLLBAR); - } - - @Override - public void setHorizontalScrollBar(JScrollBar c) { - JScrollBar old = getHorizontalScrollBar(); - super.setHorizontalScrollBar(c); - transferToLayeredPane(old, c, ScrollPaneConstants.HORIZONTAL_SCROLLBAR); - } - - @Override - public void setColumnHeader(JViewport c) { - JViewport old = getColumnHeader(); - super.setColumnHeader(c); - transferToLayeredPane(old, c, ScrollPaneConstants.COLUMN_HEADER); - } - - @Override - public void setRowHeader(JViewport c) { - JViewport old = getRowHeader(); - super.setRowHeader(c); - transferToLayeredPane(old, c, ScrollPaneConstants.ROW_HEADER); - } - - @Override - public void setViewport(JViewport c) { - JViewport old = getViewport(); - super.setViewport(c); - transferToLayeredPane(old, c, ScrollPaneConstants.VIEWPORT); - } - - @Override - public void setCorner(String key, Component c) { - Component old = getCorner(key); - super.setCorner(key, c); - transferToLayeredPane(old, c, key); - } - - private void transferToLayeredPane(Component old, Component c, String key) { - if (!ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return; - - JLayeredPane pane = getLayoutPane(); - LayoutManager layout = getLayout(); - - if (old != null && old != c) { - pane.remove(old); - layout.removeLayoutComponent(old); - } - - if (c != null) { - if (ScrollPaneConstants.VERTICAL_SCROLLBAR.equals(key) || ScrollPaneConstants.HORIZONTAL_SCROLLBAR.equals(key)) { - pane.setLayer(c, JLayeredPane.PALETTE_LAYER); - } - pane.add(c); - layout.addLayoutComponent(key, c); - } - } - - @NotNull - private JLayeredPane getLayoutPane() { - if (myLayeredPane == null) { - myLayeredPane = new JLayeredPane(); - } - return myLayeredPane; + return (JScrollPane)c; } private void init() { @@ -154,9 +79,6 @@ public class JBScrollPane extends JScrollPane { } private void init(boolean setupCorners) { - if (ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) { - add(getLayoutPane()); - } setLayout(new ScrollPaneLayout()); if (setupCorners) { @@ -178,6 +100,11 @@ public class JBScrollPane extends JScrollPane { updateViewportBorder(); } + @Override + public boolean isOptimizedDrawingEnabled() { + return !myHasOverlayScrollbars; + } + private void updateViewportBorder() { setViewportBorder(new ViewportBorder(myViewportBorderWidth >= 0 ? myViewportBorderWidth : 1)); } @@ -206,19 +133,21 @@ public class JBScrollPane extends JScrollPane { public void layout() { super.layout(); - if (!ButtonlessScrollBarUI.isMacOverlayScrollbarSupported()) return; - LayoutManager layout = getLayout(); - if (layout instanceof ScrollPaneLayout && myLayeredPane != null) { - relayoutScrollbars(this, (ScrollPaneLayout)layout, myLayeredPane); + if (layout instanceof ScrollPaneLayout) { + myHasOverlayScrollbars = relayoutScrollbars( + this, (ScrollPaneLayout)layout, + myHasOverlayScrollbars // should be relayouted if was changed previously + ); + } + else { + myHasOverlayScrollbars = false; } } - private static void relayoutScrollbars(@NotNull JComponent container, - @NotNull ScrollPaneLayout layout, - @NotNull JLayeredPane layeredPane) { + private static boolean relayoutScrollbars(@NotNull JComponent container, @NotNull ScrollPaneLayout layout, boolean forceRelayout) { JViewport viewport = layout.getViewport(); - if (viewport == null) return; + if (viewport == null) return false; JScrollBar vsb = layout.getVerticalScrollBar(); JScrollBar hsb = layout.getHorizontalScrollBar(); @@ -229,7 +158,14 @@ public class JBScrollPane extends JScrollPane { boolean extendsViewportUnderVScrollbar = vsb != null && shouldExtendViewportUnderScrollbar(vsb); boolean extendsViewportUnderHScrollbar = hsb != null && shouldExtendViewportUnderScrollbar(hsb); - + boolean hasOverlayScrollbars = extendsViewportUnderVScrollbar || extendsViewportUnderHScrollbar; + + if (!hasOverlayScrollbars && !forceRelayout) return false; + + container.setComponentZOrder(viewport, container.getComponentCount() - 1); + if (vsb != null) container.setComponentZOrder(vsb, 0); + if (hsb != null) container.setComponentZOrder(hsb, 0); + if (extendsViewportUnderVScrollbar) { viewportBounds.x = Math.min(viewportBounds.x, vsb.getX()); viewportBounds.width = Math.max(viewportBounds.width, vsb.getX() + vsb.getWidth()); @@ -270,9 +206,8 @@ public class JBScrollPane extends JScrollPane { } viewport.setBounds(viewportBounds); - Insets insets = container.getInsets(); - if (insets == null) insets = new Insets(0, 0, 0, 0); - layeredPane.setBounds(0, 0, container.getWidth() - insets.right, container.getHeight() - insets.bottom); + + return hasOverlayScrollbars; } private static boolean shouldExtendViewportUnderScrollbar(@Nullable JScrollBar scrollbar) { diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java index f8e91cb5cebf..d8736f6fc08e 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -19,7 +19,6 @@ import com.intellij.Patches; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.ui.*; -import com.intellij.ui.components.JBScrollPane; import com.intellij.ui.components.JBViewport; import com.intellij.ui.speedSearch.SpeedSearchSupply; import com.intellij.util.ui.*; @@ -134,45 +133,6 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component boolean marker = Patches.SUN_BUG_ID_4503845; // Don't remove. It's a marker for find usages } - @Override - protected void configureEnclosingScrollPane() { - super.configureEnclosingScrollPane(); - - // base class' method doesn't expect layered pane between the viewport and the scrollpane (required for mac scrollbars) - JBScrollPane sp = getJBScrollPane(); - if (sp == null) return; - - JViewport viewport = sp.getViewport(); - if (viewport == null || viewport.getView() != this) return; - sp.setColumnHeaderView(getTableHeader()); - } - - @Override - protected void unconfigureEnclosingScrollPane() { - super.unconfigureEnclosingScrollPane(); - - JBScrollPane sp = getJBScrollPane(); - if (sp == null) return; - - JViewport viewport = sp.getViewport(); - if (viewport == null || viewport.getView() != this) return; - sp.setColumnHeaderView(null); - } - - private JBScrollPane getJBScrollPane() { - Container p = getParent(); - if (p instanceof JViewport) { - Container gp = p.getParent(); - if (gp instanceof JLayeredPane) { - Container ggp = gp.getParent(); - if (ggp instanceof JBScrollPane) { - return (JBScrollPane)ggp; - } - } - } - return null; - } - @Override public int getRowHeight() { if (myRowHeightIsComputing) {