From 0e0ac3219b88229686931e7ca90bb30bb54cae4a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 21 Jun 2012 17:05:54 +0200 Subject: [PATCH] all-in-one fix (IDEA-87611 file colors in Hierarchy views, StripeTable is based on JBTable decorator, file colors in trees refactoring and cleanup) --- .../ide/hierarchy/HierarchyBrowserBaseEx.java | 32 ++++++++ .../ide/hierarchy/HierarchyNodeRenderer.java | 38 ++++----- .../ide/projectView/impl/ProjectViewTree.java | 66 ++++++++++------ .../com/intellij/openapi/ui/StripeTable.java | 77 ++----------------- .../com/intellij/ui/components/JBList.java | 3 +- .../src/com/intellij/ui/table/JBTable.java | 4 +- .../intellij/ide/ui/laf/darcula.properties | 12 ++- .../internal/inspector/UiInspectorAction.java | 3 +- .../ui/NotificationsConfigurablePanel.java | 3 +- .../util/src/com/intellij/util/ui/UIUtil.java | 10 ++- 10 files changed, 123 insertions(+), 125 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java index 3691be93d500..baa7ca820ede 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java @@ -26,6 +26,7 @@ import com.intellij.ide.dnd.DnDDragStartBean; import com.intellij.ide.dnd.DnDManager; import com.intellij.ide.dnd.DnDSource; import com.intellij.ide.dnd.aware.DnDAwareTree; +import com.intellij.ide.projectView.impl.ProjectViewTree; import com.intellij.ide.projectView.impl.TransferableWrapper; import com.intellij.ide.util.scopeChooser.EditScopesDialog; import com.intellij.ide.util.treeView.NodeDescriptor; @@ -48,6 +49,7 @@ import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Alarm; import com.intellij.util.EditSourceOnDoubleClickHandler; +import com.intellij.util.NullableFunction; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -203,6 +205,16 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem protected final JTree createTree(boolean dndAware) { final Tree tree; + final NullableFunction toPsiConverter = new NullableFunction() { + @Override + public PsiElement fun(Object o) { + if (o instanceof HierarchyNodeDescriptor) { + return ((HierarchyNodeDescriptor)o).getContainingFile(); + } + return null; + } + }; + if (dndAware) { tree = new DnDAwareTree(new DefaultTreeModel(new DefaultMutableTreeNode(""))) { @Override @@ -210,6 +222,16 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem super.removeNotify(); myRefreshAction.unregisterCustomShortcutSet(this); } + + @Override + public boolean isFileColorsEnabled() { + return ProjectViewTree.isFileColorsEnabledFor(this); + } + + @Override + public Color getFileColorFor(Object object) { + return ProjectViewTree.getColorForObject(object, myProject, toPsiConverter); + } }; if (!ApplicationManager.getApplication().isHeadlessEnvironment()) { @@ -254,6 +276,16 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem super.removeNotify(); myRefreshAction.unregisterCustomShortcutSet(this); } + + @Override + public boolean isFileColorsEnabled() { + return ProjectViewTree.isFileColorsEnabledFor(this); + } + + @Override + public Color getFileColorFor(Object object) { + return ProjectViewTree.getColorForObject(object, myProject, toPsiConverter); + } }; } configureTree(tree); diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java index 2f92f23370af..c26aa48e22b3 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyNodeRenderer.java @@ -16,16 +16,28 @@ package com.intellij.ide.hierarchy; -import com.intellij.psi.PsiFile; -import com.intellij.ui.ColoredTreeCellRenderer; -import com.intellij.ui.FileColorManager; -import org.jetbrains.annotations.Nullable; +import com.intellij.ide.util.treeView.NodeRenderer; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import java.awt.*; -public final class HierarchyNodeRenderer extends ColoredTreeCellRenderer { +/** + * @author Konstantin Bulenkov + */ +public final class HierarchyNodeRenderer extends NodeRenderer { + public HierarchyNodeRenderer() { + setOpaque(false); + setIconOpaque(false); + setTransparentIconBackground(true); + } + + @Override + protected void doPaint(Graphics2D g) { + super.doPaint(g); + setOpaque(false); + } + public void customizeCellRenderer(final JTree tree, final Object value, final boolean selected, final boolean expanded, final boolean leaf, final int row, final boolean hasFocus) { if (value instanceof DefaultMutableTreeNode) { @@ -40,23 +52,7 @@ public final class HierarchyNodeRenderer extends ColoredTreeCellRenderer { else{ setIcon(descriptor.getClosedIcon()); } - if (!selected) { - final Color color = getBackgroundColor(descriptor); - if (color != null) { - setBackground(color); - } - } } } } - - @Nullable - private static Color getBackgroundColor(final HierarchyNodeDescriptor descriptor) { - final PsiFile psiFile = descriptor.getContainingFile(); - if (psiFile != null && psiFile.isValid()) { - final FileColorManager colorManager = FileColorManager.getInstance(descriptor.getProject()); - return colorManager.getRendererBackground(psiFile); - } - return null; - } } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewTree.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewTree.java index 2aa88bbc2a6a..06776ef0aad7 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewTree.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewTree.java @@ -29,8 +29,11 @@ import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.ColorUtil; import com.intellij.ui.FileColorManager; import com.intellij.ui.tabs.FileColorManagerImpl; +import com.intellij.util.NullableFunction; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeModel; import java.awt.*; @@ -80,12 +83,16 @@ public abstract class ProjectViewTree extends DnDAwareTree { @Override public boolean isFileColorsEnabled() { + return isFileColorsEnabledFor(this); + } + + public static boolean isFileColorsEnabledFor(JTree tree) { final boolean enabled = FileColorManagerImpl._isEnabled() && FileColorManagerImpl._isEnabledForProjectView(); - final boolean opaque = isOpaque(); + final boolean opaque = tree.isOpaque(); if (enabled && opaque) { - setOpaque(false); + tree.setOpaque(false); } else if (!enabled && !opaque) { - setOpaque(true); + tree.setOpaque(true); } return enabled; } @@ -93,29 +100,42 @@ public abstract class ProjectViewTree extends DnDAwareTree { @Nullable @Override public Color getFileColorFor(Object object) { + return getColorForObject(object, getProject(), new NullableFunction() { + @Override + public PsiElement fun(Object object) { + if (object instanceof AbstractTreeNode) { + final Object element = ((AbstractTreeNode)object).getValue(); + if (element instanceof PsiElement) { + return (PsiElement)element; + } + } + return null; + } + }); + } + + @Nullable + public static Color getColorForObject(Object object, Project project, @NotNull NullableFunction converter) { Color color = null; - if (object instanceof AbstractTreeNode) { - final Object element = ((AbstractTreeNode)object).getValue(); - if (element instanceof PsiElement) { - final PsiElement psi = (PsiElement)element; - if (!psi.isValid()) return null; + final PsiElement psi = converter.fun(object); + if (psi != null) { + if (!psi.isValid()) return null; - final VirtualFile file = PsiUtilCore.getVirtualFile(psi); + final VirtualFile file = PsiUtilCore.getVirtualFile(psi); - if (file != null) { - color = FileColorManager.getInstance(getProject()).getFileColor(file); - } else if (psi instanceof PsiDirectory) { - color = FileColorManager.getInstance(getProject()).getFileColor(((PsiDirectory)psi).getVirtualFile()); - } else if (psi instanceof PsiDirectoryContainer) { - final PsiDirectory[] dirs = ((PsiDirectoryContainer)psi).getDirectories(); - for (PsiDirectory dir : dirs) { - Color c = FileColorManager.getInstance(getProject()).getFileColor(dir.getVirtualFile()); - if (c != null && color == null) { - color = c; - } else if (c != null) { - color = null; - break; - } + if (file != null) { + color = FileColorManager.getInstance(project).getFileColor(file); + } else if (psi instanceof PsiDirectory) { + color = FileColorManager.getInstance(project).getFileColor(((PsiDirectory)psi).getVirtualFile()); + } else if (psi instanceof PsiDirectoryContainer) { + final PsiDirectory[] dirs = ((PsiDirectoryContainer)psi).getDirectories(); + for (PsiDirectory dir : dirs) { + Color c = FileColorManager.getInstance(project).getFileColor(dir.getVirtualFile()); + if (c != null && color == null) { + color = c; + } else if (c != null) { + color = null; + break; } } } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/StripeTable.java b/platform/platform-api/src/com/intellij/openapi/ui/StripeTable.java index 2ccf31136a02..e679f70b2864 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/StripeTable.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/StripeTable.java @@ -17,25 +17,19 @@ package com.intellij.openapi.ui; import com.intellij.ui.Gray; -import com.intellij.ui.ScrollPaneFactory; -import com.intellij.ui.components.JBViewport; -import com.intellij.util.ui.Table; -import com.intellij.util.ui.UIUtil; +import com.intellij.ui.table.JBTable; import javax.swing.*; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; -import javax.swing.table.TableColumn; import javax.swing.table.TableModel; import java.awt.*; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; /** * @author spleaner + * @author Konstantin Bulenkov */ -public class StripeTable extends Table { - private static final Color EVEN_ROW_COLOR = new Color(241, 245, 250); +public class StripeTable extends JBTable { private static final Color GRID_COLOR = Gray._217; private static final CellRendererPane RENDER_PANE = new CellRendererPane(); @@ -45,10 +39,11 @@ public class StripeTable extends Table { setAutoResizeMode(AUTO_RESIZE_OFF); setTableHeader(createTableHeader()); getTableHeader().setReorderingAllowed(false); - setOpaque(false); + //setOpaque(false); setGridColor(GRID_COLOR); setIntercellSpacing(new Dimension(1, 0)); setShowGrid(false); + setStriped(true); } private JTableHeader createTableHeader() { @@ -73,66 +68,4 @@ public class StripeTable extends Table { ((JComponent)component).setOpaque(false); RENDER_PANE.paintComponent(g, component, null, x, 0, width, table.getTableHeader().getHeight(), true); } - - @Override - public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { - Component component = super.prepareRenderer(renderer, row, column); - if (component instanceof JComponent) { - ((JComponent)component).setOpaque(getSelectionModel().isSelectedIndex(row) || row % 2 == 0 ); - if (!getSelectionModel().isSelectedIndex(row) && row % 2 == 0) component.setBackground(EVEN_ROW_COLOR); - } - - return component; - } - - public static JScrollPane createScrollPane(JTable table) { - JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table); - // Fix GTK background - if (UIUtil.isUnderGTKLookAndFeel()) { - scrollPane.setBackground(UIUtil.getTreeTextBackground()); - } - scrollPane.setViewport(new StripedViewport(table)); - scrollPane.getViewport().setView(table); - scrollPane.setBorder(UIManager.getBorder("Table.scrollPaneBorder")); - return scrollPane; - } - - private static class StripedViewport extends JBViewport { - private final JTable myTable; - - public StripedViewport(JTable table) { - myTable = table; - setOpaque(false); - initListeners(); - } - - private void initListeners() { - PropertyChangeListener listener = createTableColumnWidthListener(); - for (int i = 0; i < myTable.getColumnModel().getColumnCount(); i++) { - myTable.getColumnModel().getColumn(i).addPropertyChangeListener(listener); - } - } - - private PropertyChangeListener createTableColumnWidthListener() { - return new PropertyChangeListener() { - public void propertyChange(PropertyChangeEvent evt) { - repaint(); - } - }; - } - - @Override - protected void paintComponent(Graphics g) { - int x = 0; - for (int i = 0; i < myTable.getColumnCount(); i++) { - TableColumn column = myTable.getColumnModel().getColumn(i); - x += column.getWidth(); - g.setColor(GRID_COLOR); - g.drawLine(x - 1, g.getClipBounds().y, x - 1, getHeight()); - } - - super.paintComponent(g); - } - } - } 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 e73b6c0558d9..cf1dfa1b90ad 100644 --- a/platform/platform-api/src/com/intellij/ui/components/JBList.java +++ b/platform/platform-api/src/com/intellij/ui/components/JBList.java @@ -22,7 +22,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.ComponentWithExpandableItems; import com.intellij.ui.ExpandableItemsHandler; import com.intellij.ui.ExpandableItemsHandlerFactory; -import com.intellij.ui.table.JBTable; import com.intellij.util.ArrayUtil; import com.intellij.util.NotNullFunction; import com.intellij.util.ui.AsyncProcessIcon; @@ -232,7 +231,7 @@ public class JBList extends JList implements ComponentWithEmptyText, ComponentWi public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if (!isSelected && index % 2 == 0) { - setBackground(JBTable.DECORATED_ROW_BG_COLOR); + setBackground(UIUtil.getDecoratedRowColor()); } return this; } 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 342f8578e0e1..59461c9ad68b 100644 --- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java +++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java @@ -41,7 +41,6 @@ import java.util.Comparator; import java.util.EventObject; public class JBTable extends JTable implements ComponentWithEmptyText, ComponentWithExpandableItems { - public static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249); private StatusText myEmptyText; private ExpandableItemsHandler myExpandableItemsHandler; @@ -455,6 +454,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component private static boolean isTableDecorationSupported() { return UIUtil.isUnderAlloyLookAndFeel() || UIUtil.isUnderNativeMacLookAndFeel() + || UIUtil.isUnderDarcula() || UIUtil.isUnderQuaquaLookAndFeel() || UIUtil.isUnderMetalLookAndFeel() || UIUtil.isUnderNimbusLookAndFeel() @@ -476,7 +476,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component } if (isTableDecorationSupported() && isStriped() && result instanceof JComponent) { - final Color bg = row % 2 == 1 ? getBackground() : DECORATED_ROW_BG_COLOR; + final Color bg = row % 2 == 1 ? getBackground() : UIUtil.getDecoratedRowColor(); final JComponent c = (JComponent)result; final boolean cellSelected = isCellSelected(row, column); if (!cellSelected || (!hasFocus() && !getSelectionBackground().equals(c.getBackground()))) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula.properties index 389db6c52ea9..e30a98c4af5e 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula.properties @@ -37,6 +37,16 @@ Focus.color=ff0000 TextField.background=444444 TextField.foreground=ffffff +TextField.caretForeground=ffffff + +TextArea.background=444444 +TextArea.foreground=ffffff +TextArea.caretForeground=ffffff + +TextPane.background=444444 +TextPane.foreground=ffffff +TextPane.caretForeground=ffffff + CheckBox.background=444444 CheckBox.foreground=ffffff RadioButton.foreground=ffffff @@ -45,6 +55,6 @@ StatusBar.topColor=2c2c2c StatusBar.top2Color=2c2c2c StatusBar.bottomColor=2c2c2c -TextField.caretForeground=ffffff + MenuItem.acceleratorForeground=ffffff PopupMenu.background=444444 \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java b/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java index 05780ab6c94b..36650aea2326 100644 --- a/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java +++ b/platform/platform-impl/src/com/intellij/internal/inspector/UiInspectorAction.java @@ -27,6 +27,7 @@ import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.ui.StripeTable; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.components.JBScrollPane; import com.intellij.util.containers.HashMap; import com.intellij.util.ui.ColorIcon; import com.intellij.util.ui.UIUtil; @@ -437,7 +438,7 @@ public class UiInspectorAction extends ToggleAction implements DumbAware { table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN); - add(StripeTable.createScrollPane(table), BorderLayout.CENTER); + add(new JBScrollPane(table), BorderLayout.CENTER); myDimensionComponent = new DimensionsComponent(component); add(myDimensionComponent, BorderLayout.SOUTH); } diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java index ce393f14d446..157d1ca7a42f 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsConfigurablePanel.java @@ -21,6 +21,7 @@ import com.intellij.notification.impl.NotificationsConfigurationImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.ui.ComboBoxTableRenderer; import com.intellij.openapi.ui.StripeTable; +import com.intellij.ui.components.JBScrollPane; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; @@ -50,7 +51,7 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable setLayout(new BorderLayout()); myTable = new NotificationsTable(); - JScrollPane scrollPane = StripeTable.createScrollPane(myTable); + JScrollPane scrollPane = new JBScrollPane(myTable); scrollPane.setBorder(new LineBorder(UIUtil.getBorderColor())); add(scrollPane, BorderLayout.CENTER); myDisplayBalloons = new JCheckBox("Display balloon notifications"); diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 334af8c5266f..4e061c7a4f74 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -889,11 +889,11 @@ public class UIUtil { } public static boolean isFullRowSelectionLAF() { - return isUnderNimbusLookAndFeel() || isUnderQuaquaLookAndFeel(); + return isUnderNimbusLookAndFeel() || isUnderQuaquaLookAndFeel() || isUnderDarcula(); } public static boolean isUnderNativeMacLookAndFeel() { - return isUnderAquaLookAndFeel() || isUnderQuaquaLookAndFeel(); + return isUnderAquaLookAndFeel() || isUnderQuaquaLookAndFeel() || isUnderDarcula(); } public static int getListCellHPadding() { @@ -2332,5 +2332,11 @@ public class UIUtil { component.setBorder(border); } } + + private static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249); + private static final Color DECORATED_ROW_BG_COLOR_DARK = new Color(242-100, 245-100, 249-100); + public static Color getDecoratedRowColor() { + return UIUtil.isUnderDarcula() ? DECORATED_ROW_BG_COLOR_DARK : DECORATED_ROW_BG_COLOR; + } }