From e746328dc9d1b7473f9c32d43cc156136d0c8a2a Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Sat, 10 Sep 2016 22:43:47 +0300 Subject: [PATCH] IDEA-160777 Incorrect background in lists with new scrollbars --- .../com/intellij/ui/components/JBList.java | 26 ++++++ .../ui/components/WideSelectionListUI.java | 88 +++++++++++++++++++ .../util/resources/misc/registry.properties | 1 + 3 files changed, 115 insertions(+) create mode 100644 platform/platform-api/src/com/intellij/ui/components/WideSelectionListUI.java diff --git a/platform/platform-api/src/com/intellij/ui/components/JBList.java b/platform/platform-api/src/com/intellij/ui/components/JBList.java index ac4c065ba13c..b01de23bb4e9 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBList.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBList.java @@ -19,6 +19,7 @@ import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.DataProvider; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; import com.intellij.util.ArrayUtil; @@ -31,7 +32,9 @@ import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; import javax.accessibility.AccessibleRole; import javax.swing.*; +import javax.swing.plaf.ListUI; import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicListUI; import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.datatransfer.StringSelection; @@ -114,6 +117,29 @@ public class JBList extends JList implements ComponentWithEmptyText, Compo } } + @Override + public void repaint(long tm, int x, int y, int width, int height) { + if (width > 0 && height > 0) { + ListUI ui = getUI(); + if (ui instanceof WideSelectionListUI) { + x = 0; + width = getWidth(); + } + super.repaint(tm, x, y, width, height); + } + } + + @Override + public void setUI(ListUI ui) { + if (ui != null && Registry.is("ide.wide.selection.list.ui")) { + Class type = ui.getClass(); + if (type == BasicListUI.class) { + ui = new WideSelectionListUI(); + } + } + super.setUI(ui); + } + public void setPaintBusy(boolean paintBusy) { if (myBusy == paintBusy) return; diff --git a/platform/platform-api/src/com/intellij/ui/components/WideSelectionListUI.java b/platform/platform-api/src/com/intellij/ui/components/WideSelectionListUI.java new file mode 100644 index 000000000000..51a02f5f99fe --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/components/WideSelectionListUI.java @@ -0,0 +1,88 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui.components; + +import java.awt.*; +import javax.swing.*; +import javax.swing.plaf.basic.BasicListUI; + +/** + * @author Sergey.Malenkov + */ +final class WideSelectionListUI extends BasicListUI { + private Rectangle myPaintBounds; + + @Override + public void paint(Graphics g, JComponent c) { + myPaintBounds = g.getClipBounds(); + super.paint(g, c); + } + + @Override + protected void paintCell(Graphics g, + int row, + Rectangle rowBounds, + ListCellRenderer renderer, + ListModel model, + ListSelectionModel selectionModel, + int leadSelectionIndex) { + Rectangle paintBounds = myPaintBounds; + if (paintBounds != null) { + boolean selected = selectionModel.isSelectedIndex(row); + boolean focused = row == leadSelectionIndex && list.hasFocus(); + @SuppressWarnings("unchecked") + Component component = renderer.getListCellRendererComponent(list, model.getElementAt(row), row, selected, focused); + if (component != null) { + if (rendererPane != component.getParent()) rendererPane.add(component); + g.setClip(paintBounds.x, paintBounds.y, paintBounds.width, paintBounds.height); + paintRenderer(g, rowBounds.x, rowBounds.y, rowBounds.width, rowBounds.height, list, component); + g.clipRect(rowBounds.x, rowBounds.y, rowBounds.width, rowBounds.height); + } + } + super.paintCell(g, row, rowBounds, renderer, model, selectionModel, leadSelectionIndex); + } + + private static void paintRenderer(Graphics g, int x, int y, int width, int height, Component owner, Component renderer) { + g.clipRect(0, y, owner.getWidth(), height); + paintBackground(g, y, height, owner, renderer); + if (renderer instanceof Container) { + Component[] children; + Container container = (Container)renderer; + synchronized (container.getTreeLock()) { + children = container.getComponents(); + } + if (children.length > 0) { + renderer.setBounds(x, y, width, height); + renderer.validate(); + for (Component child : children) { + if (0 == child.getX() && width == child.getWidth() && 0 < child.getHeight()) { + paintBackground(g, y + child.getY(), child.getHeight(), owner, child); + } + } + } + } + } + + private static void paintBackground(Graphics g, int y, int height, Component owner, Component child) { + if (child.isOpaque()) { + Color color = child.getBackground(); + if (color != null && !color.equals(owner.getBackground())) { + g.setColor(color); + g.fillRect(0, y, owner.getWidth(), height); + } + } + } +} diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 00712e1432d9..e4857c830652 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -116,6 +116,7 @@ ide.scroll.track.border.paint=false ide.scroll.thumb.border.rounded=false ide.scroll.thumb.small.if.opaque=true mac.scroll.new.ui=true +ide.wide.selection.list.ui=true ide.tooltip.callout=true ide.tooltip.animationCycle=150