all-in-one fix (IDEA-87611 file colors in Hierarchy views, StripeTable is based on JBTable decorator, file colors in trees refactoring and cleanup)

This commit is contained in:
Konstantin Bulenkov
2012-06-21 17:08:42 +02:00
parent 85bf22894c
commit 0e0ac3219b
10 changed files with 123 additions and 125 deletions
@@ -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<Object, PsiElement> toPsiConverter = new NullableFunction<Object, PsiElement>() {
@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);
@@ -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;
}
}
@@ -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<Object, PsiElement>() {
@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<Object, PsiElement> 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;
}
}
}
@@ -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);
}
}
}
@@ -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;
}
@@ -41,7 +41,6 @@ import java.util.Comparator;
import java.util.EventObject;
public class JBTable extends JTable implements ComponentWithEmptyText, ComponentWithExpandableItems<TableCell> {
public static final Color DECORATED_ROW_BG_COLOR = new Color(242, 245, 249);
private StatusText myEmptyText;
private ExpandableItemsHandler<TableCell> 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()))) {
@@ -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
@@ -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);
}
@@ -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");
@@ -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;
}
}