summaryrefslogtreecommitdiff
path: root/platform/platform-api/src/com/intellij/ui
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-api/src/com/intellij/ui')
-rw-r--r--platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java11
-rw-r--r--platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java8
-rw-r--r--platform/platform-api/src/com/intellij/ui/GuiUtils.java32
-rw-r--r--platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java25
-rw-r--r--platform/platform-api/src/com/intellij/ui/InplaceButton.java6
-rw-r--r--platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java64
-rw-r--r--platform/platform-api/src/com/intellij/ui/ScreenUtil.java124
-rw-r--r--platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java4
-rw-r--r--platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java156
-rw-r--r--platform/platform-api/src/com/intellij/ui/table/JBTable.java4
10 files changed, 324 insertions, 110 deletions
diff --git a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
index b7ec8556f3d9..67ca238ce077 100644
--- a/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/ColoredListCellRenderer.java
@@ -17,6 +17,7 @@ package com.intellij.ui;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -30,8 +31,15 @@ public abstract class ColoredListCellRenderer<T> extends SimpleColoredComponent
protected boolean mySelected;
protected Color myForeground;
protected Color mySelectionForeground;
+ @Nullable
+ private final JComboBox myComboBox;
public ColoredListCellRenderer() {
+ this(null);
+ }
+
+ public ColoredListCellRenderer(@Nullable JComboBox comboBox) {
+ myComboBox = comboBox;
setFocusBorderAroundIcon(true);
getIpad().left = UIUtil.getListCellHPadding();
getIpad().right = UIUtil.getListCellHPadding();
@@ -40,6 +48,9 @@ public abstract class ColoredListCellRenderer<T> extends SimpleColoredComponent
public Component getListCellRendererComponent(JList list, Object value, int index, boolean selected, boolean hasFocus) {
clear();
+ if (myComboBox != null) {
+ setEnabled(myComboBox.isEnabled());
+ }
setFont(list.getFont());
mySelected = selected;
myForeground = list.getForeground();
diff --git a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
index 76bacb9cb452..a2e8aacc046f 100644
--- a/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
+++ b/platform/platform-api/src/com/intellij/ui/GroupedElementsRenderer.java
@@ -165,22 +165,22 @@ public abstract class GroupedElementsRenderer {
}
@Override
- protected final Color getSelectionBackground() {
+ protected Color getSelectionBackground() {
return UIUtil.getTreeSelectionBackground();
}
@Override
- protected final Color getSelectionForeground() {
+ protected Color getSelectionForeground() {
return UIUtil.getTreeSelectionForeground();
}
@Override
- protected final Color getBackground() {
+ protected Color getBackground() {
return UIUtil.getTreeTextBackground();
}
@Override
- protected final Color getForeground() {
+ protected Color getForeground() {
return UIUtil.getTreeTextForeground();
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/GuiUtils.java b/platform/platform-api/src/com/intellij/ui/GuiUtils.java
index ec378977f76e..9d5dcbea7edf 100644
--- a/platform/platform-api/src/com/intellij/ui/GuiUtils.java
+++ b/platform/platform-api/src/com/intellij/ui/GuiUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -26,7 +26,7 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.CharFilter;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
@@ -47,11 +47,9 @@ import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
public class GuiUtils {
-
private static final Insets paddingFromDialogBoundaries = new Insets(7, 5, 7, 5);
private static final Insets paddingInsideDialog = new Insets(5, 5, 5, 5);
- public static final int lengthForFileField = 25;
private static final CharFilter NOT_MNEMONIC_CHAR_FILTER = new CharFilter() {
@Override
public boolean accept(char ch) {
@@ -78,33 +76,33 @@ public class GuiUtils {
return result;
}
- public static JPanel constructDirectoryBrowserField(final JTextField aTextField, final String aSearchedObjectName) {
- return constructFieldWithBrowseButton(aTextField, new ActionListener() {
+ public static JPanel constructDirectoryBrowserField(final JTextField field, final String objectName) {
+ return constructFieldWithBrowseButton(field, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getDirectoryChooserDescriptor(aSearchedObjectName);
- VirtualFile file = FileChooser.chooseFile(descriptor, aTextField, null, null);
+ FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle("Select " + objectName);
+ VirtualFile file = FileChooser.chooseFile(descriptor, field, null, null);
if (file != null) {
- aTextField.setText(FileUtil.toSystemDependentName(file.getPath()));
- aTextField.postActionEvent();
+ field.setText(FileUtil.toSystemDependentName(file.getPath()));
+ field.postActionEvent();
}
}
});
}
- public static JPanel constructFileURLBrowserField(final TextFieldWithHistory aFieldWithHistory,
- final String aSearchedObjectName) {
- return constructFieldWithBrowseButton(aFieldWithHistory, new ActionListener() {
+ public static JPanel constructFileURLBrowserField(final TextFieldWithHistory field, final String objectName) {
+ return constructFieldWithBrowseButton(field, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
- FileChooserDescriptor descriptor = FileChooserDescriptorFactory.getFileChooserDescriptor(aSearchedObjectName);
- VirtualFile file = FileChooser.chooseFile(descriptor, aFieldWithHistory, null, null);
+ FileChooserDescriptor descriptor =
+ FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor().withTitle("Select " + objectName);
+ VirtualFile file = FileChooser.chooseFile(descriptor, field, null, null);
if (file != null) {
try {
- aFieldWithHistory.setText(VfsUtil.virtualToIoFile(file).toURL().toString());
+ field.setText(VfsUtilCore.virtualToIoFile(file).toURI().toURL().toString());
}
catch (MalformedURLException e1) {
- aFieldWithHistory.setText("");
+ field.setText("");
}
}
}
diff --git a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
index 27324c9d9781..6a99624a620b 100644
--- a/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
+++ b/platform/platform-api/src/com/intellij/ui/HyperlinkLabel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 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.
@@ -20,9 +20,11 @@ import com.intellij.ide.BrowserUtil;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.markup.EffectType;
import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.util.NotNullProducer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.PlatformColors;
import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -42,7 +44,14 @@ import java.util.List;
* @author Eugene Belyaev
*/
public class HyperlinkLabel extends HighlightableComponent {
- private static final TextAttributes BOLD_ATTRIBUTES = new TextAttributes(UIUtil.getLabelTextForeground(), null, null, null, Font.BOLD);
+ private static final TextAttributes BOLD_ATTRIBUTES = new TextAttributes(new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ final Color foreground = UIUtil.getLabelTextForeground();
+ return foreground == null ? UIUtil.getLabelForeground() : foreground;
+ }
+ }), null, null, null, Font.BOLD);
private static final Logger LOG = Logger.getInstance(HyperlinkLabel.class.getName());
@@ -59,7 +68,13 @@ public class HyperlinkLabel extends HighlightableComponent {
public HyperlinkLabel(String text) {
this(text,
PlatformColors.BLUE,
- UIUtil.getLabelBackground(),
+ new JBColor(new NotNullProducer<Color>() {
+ @NotNull
+ @Override
+ public Color produce() {
+ return UIUtil.getLabelBackground();
+ }
+ }),
PlatformColors.BLUE);
}
@@ -209,7 +224,9 @@ public class HyperlinkLabel extends HighlightableComponent {
LOG.error(e);
}
highlightedText.applyToComponent(this);
- ((JComponent)getParent()).revalidate();
+ final JComponent parent = (JComponent)getParent();
+ parent.revalidate();
+ parent.repaint();
adjustSize();
}
diff --git a/platform/platform-api/src/com/intellij/ui/InplaceButton.java b/platform/platform-api/src/com/intellij/ui/InplaceButton.java
index 04ea9161f99c..89dd0dfc34e2 100644
--- a/platform/platform-api/src/com/intellij/ui/InplaceButton.java
+++ b/platform/platform-api/src/com/intellij/ui/InplaceButton.java
@@ -101,7 +101,11 @@ public class InplaceButton extends JComponent implements ActiveComponent {
setIcons(source.getRegular(), source.getInactive(), source.getHovered());
}
- public void setIcons(final Icon regular, final Icon inactive, final Icon hovered) {
+ public void setIcons(final Icon regular, Icon inactive, Icon hovered) {
+ if (regular == null) return;
+ if (inactive == null) inactive = regular;
+ if (hovered == null) hovered = regular;
+
int width = Math.max(regular.getIconWidth(), inactive.getIconWidth());
width = Math.max(width, hovered.getIconWidth());
int height = Math.max(regular.getIconHeight(), inactive.getIconHeight());
diff --git a/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java b/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
index 5ef516210e0d..f859421bbbee 100644
--- a/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
+++ b/platform/platform-api/src/com/intellij/ui/JBListWithHintProvider.java
@@ -18,79 +18,59 @@ package com.intellij.ui;
import com.intellij.openapi.ui.popup.JBPopup;
import com.intellij.psi.PsiElement;
import com.intellij.ui.components.JBList;
-import com.intellij.ui.popup.PopupUpdateProcessorBase;
+import com.intellij.ui.popup.HintUpdateSupply;
+import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
import java.util.Collection;
/**
* @author pegov
+ * @deprecated
+ * @see com.intellij.ui.popup.HintUpdateSupply
*/
public abstract class JBListWithHintProvider extends JBList {
- private JBPopup myHint;
+ {
+ new HintUpdateSupply(this) {
+ @Override
+ protected PsiElement getPsiElementForHint(Object selectedValue) {
+ return JBListWithHintProvider.this.getPsiElementForHint(selectedValue);
+ }
+ };
+ }
public JBListWithHintProvider() {
- addSelectionListener();
}
public JBListWithHintProvider(ListModel dataModel) {
super(dataModel);
- addSelectionListener();
}
public JBListWithHintProvider(Object... listData) {
super(listData);
- addSelectionListener();
}
public JBListWithHintProvider(Collection items) {
super(items);
- addSelectionListener();
}
- private void addSelectionListener() {
- addListSelectionListener(new ListSelectionListener() {
- @Override
- public void valueChanged(final ListSelectionEvent e) {
- if (getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT) != Boolean.TRUE) {
- final Object[] selectedValues = ((JList)e.getSource()).getSelectedValues();
- if (selectedValues.length != 1) return;
-
- final PsiElement element = getPsiElementForHint(selectedValues[0]);
- if (element != null && element.isValid()) {
- updateHint(element);
- }
- }
- }
- });
- }
-
@Nullable
protected abstract PsiElement getPsiElementForHint(final Object selectedValue);
- public void registerHint(final JBPopup hint) {
- hideHint();
- myHint = hint;
+ @Deprecated
+ public void registerHint(JBPopup hint) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).registerHint(hint);
}
-
- public void hideHint() {
- if (myHint != null && myHint.isVisible()) {
- myHint.cancel();
- }
- myHint = null;
+ @Deprecated
+ public void hideHint() {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).hideHint();
}
-
- public void updateHint(PsiElement element) {
- if (myHint == null || !myHint.isVisible()) return;
- final PopupUpdateProcessorBase updateProcessor = myHint.getUserData(PopupUpdateProcessorBase.class);
- if (updateProcessor != null) {
- updateProcessor.updatePopup(element);
- }
+ @Deprecated
+ public void updateHint(PsiElement element) {
+ ObjectUtils.assertNotNull(HintUpdateSupply.getSupply(this)).updateHint(element);
}
-
+
}
diff --git a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
index 75769d25c0db..74fe7bb31108 100644
--- a/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
+++ b/platform/platform-api/src/com/intellij/ui/ScreenUtil.java
@@ -56,22 +56,14 @@ public class ScreenUtil {
}
public static Rectangle getMainScreenBounds() {
- GraphicsConfiguration graphicsConfiguration =
- GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
- Rectangle bounds = graphicsConfiguration.getBounds();
- applyInsets(bounds, getScreenInsets(graphicsConfiguration));
- return bounds;
+ return getScreenRectangle(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice());
}
private static Rectangle[] getAllScreenBounds() {
- final GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
- final GraphicsDevice[] devices = env.getScreenDevices();
+ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
Rectangle[] result = new Rectangle[devices.length];
for (int i = 0; i < devices.length; i++) {
- GraphicsDevice device = devices[i];
- GraphicsConfiguration configuration = device.getDefaultConfiguration();
- result[i] = new Rectangle(configuration.getBounds());
- applyInsets(result[i], getScreenInsets(configuration));
+ result[i] = getScreenRectangle(devices[i]);
}
return result;
}
@@ -86,27 +78,7 @@ public class ScreenUtil {
}
public static Rectangle getScreenRectangle(@NotNull Point p) {
- double distance = -1;
- Rectangle answer = null;
-
- Rectangle[] allScreenBounds = getAllScreenBounds();
- for (Rectangle rect : allScreenBounds) {
- if (rect.contains(p)) {
- return rect;
- }
-
- final double d = findNearestPointOnBorder(rect, p).distance(p.x, p.y);
- if (answer == null || distance > d) {
- distance = d;
- answer = rect;
- }
- }
-
- if (answer == null) {
- throw new IllegalStateException("It's impossible to determine target graphics environment for point (" + p.x + "," + p.y + ")");
- }
-
- return answer;
+ return getScreenRectangle(p.x, p.y);
}
public static GraphicsDevice getScreenDevice(Rectangle bounds) {
@@ -150,11 +122,12 @@ public class ScreenUtil {
}
private static Rectangle applyInsets(Rectangle rect, Insets i) {
- if (i == null) {
- return rect;
- }
-
- return new Rectangle(rect.x + i.left, rect.y + i.top, rect.width - (i.left + i.right), rect.height - (i.top + i.bottom));
+ return (i == null)
+ ? new Rectangle(rect)
+ : new Rectangle(rect.x + i.left,
+ rect.y + i.top,
+ rect.width - (i.left + i.right),
+ rect.height - (i.top + i.bottom));
}
public static Insets getScreenInsets(final GraphicsConfiguration gc) {
@@ -181,8 +154,83 @@ public class ScreenUtil {
return Toolkit.getDefaultToolkit().getScreenInsets(gc);
}
+ /**
+ * Returns a visible area for the specified graphics device.
+ *
+ * @param device one of available devices
+ * @return a visible area rectangle
+ */
+ private static Rectangle getScreenRectangle(GraphicsDevice device) {
+ GraphicsConfiguration configuration = device.getDefaultConfiguration();
+ return applyInsets(configuration.getBounds(), getScreenInsets(configuration));
+ }
+
+ /**
+ * Finds a device that is the closest to the specified point and
+ * returns its visible area.
+ *
+ * @param x the X coordinate of the specified point
+ * @param y the Y coordinate of the specified point
+ * @return a visible area rectangle
+ */
public static Rectangle getScreenRectangle(int x, int y) {
- return getScreenRectangle(new Point(x, y));
+ GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
+ if (devices.length == 0) {
+ return new Rectangle(x, y, 0, 0);
+ }
+ if (devices.length == 1) {
+ return getScreenRectangle(devices[0]);
+ }
+ Rectangle[] rectangles = new Rectangle[devices.length];
+ for (int i = 0; i < devices.length; i++) {
+ GraphicsConfiguration configuration = devices[i].getDefaultConfiguration();
+ Rectangle bounds = configuration.getBounds();
+ rectangles[i] = applyInsets(bounds, getScreenInsets(configuration));
+ if (bounds.contains(x, y)) {
+ return rectangles[i];
+ }
+ }
+ Rectangle bounds = rectangles[0];
+ int minimum = distance(bounds, x, y);
+ for (int i = 1; i < rectangles.length; i++) {
+ int distance = distance(rectangles[i], x, y);
+ if (minimum > distance) {
+ minimum = distance;
+ bounds = rectangles[i];
+ }
+ }
+ return bounds;
+ }
+
+ /**
+ * Normalizes a specified value in the specified range.
+ * If value less than the minimal value,
+ * the method returns the minimal value.
+ * If value greater than the maximal value,
+ * the method returns the maximal value.
+ *
+ * @param value the value to normalize
+ * @param min the minimal value of the range
+ * @param max the maximal value of the range
+ * @return a normalized value
+ */
+ private static int normalize(int value, int min, int max) {
+ return value < min ? min : value > max ? max : value;
+ }
+
+ /**
+ * Returns a square of the distance from
+ * the specified point to the specified rectangle,
+ * which does not contain the specified point.
+ *
+ * @param x the X coordinate of the specified point
+ * @param y the Y coordinate of the specified point
+ * @return a square of the distance
+ */
+ private static int distance(Rectangle bounds, int x, int y) {
+ x -= normalize(x, bounds.x, bounds.x + bounds.width);
+ y -= normalize(y, bounds.y, bounds.y + bounds.height);
+ return x * x + y * y;
}
public static boolean isOutsideOnTheRightOFScreen(Rectangle rect) {
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 97a42176a25b..51535b67f9af 100644
--- a/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
+++ b/platform/platform-api/src/com/intellij/ui/components/JBScrollPane.java
@@ -235,7 +235,7 @@ public class JBScrollPane extends JScrollPane {
}
if (colHead != null) {
Rectangle headerBounds = colHead.getBounds();
- headerBounds.width = viewportBounds.width - headerBounds.x;
+ headerBounds.width = viewportBounds.width;
colHead.setBounds(headerBounds);
}
hideFromView(layout.getCorner(UPPER_RIGHT_CORNER));
@@ -249,7 +249,7 @@ public class JBScrollPane extends JScrollPane {
}
if (rowHead != null) {
Rectangle headerBounds = rowHead.getBounds();
- headerBounds.height = viewportBounds.height - headerBounds.y;
+ headerBounds.height = viewportBounds.height;
rowHead.setBounds(headerBounds);
}
diff --git a/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java b/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java
new file mode 100644
index 000000000000..54b071ab0b94
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/popup/HintUpdateSupply.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2000-2014 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.popup;
+
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiElement;
+import com.intellij.ui.ListUtil;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.table.JBTable;
+import com.intellij.ui.treeStructure.Tree;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+/**
+ * Use this class to make various hints like QuickDocumentation, ShowImplementations, etc.
+ * respond to the selection change in the original component like ProjectView, various GoTo popups, etc.
+ *
+ * @author gregsh
+ */
+public abstract class HintUpdateSupply {
+ private static final Key<HintUpdateSupply> HINT_UPDATE_MARKER = Key.create("HINT_UPDATE_MARKER");
+
+ @Nullable
+ private JBPopup myHint;
+
+ @Nullable
+ public static HintUpdateSupply getSupply(@NotNull JComponent component) {
+ return (HintUpdateSupply)component.getClientProperty(HINT_UPDATE_MARKER);
+ }
+
+ public static void hideHint(@NotNull JComponent component) {
+ HintUpdateSupply supply = getSupply(component);
+ if (supply != null) supply.hideHint();
+ }
+
+ protected HintUpdateSupply(@NotNull JComponent component) {
+ installSupply(component);
+ }
+
+ public HintUpdateSupply(@NotNull final JBTable table) {
+ installSupply(table);
+ ListSelectionListener listener = new ListSelectionListener() {
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(table)) return;
+
+ int selected = ((ListSelectionModel)e.getSource()).getLeadSelectionIndex();
+ int rowCount = table.getRowCount();
+ if (selected == -1 || rowCount == 0) return;
+
+ PsiElement element = getPsiElementForHint(table.getValueAt(Math.min(selected, rowCount - 1), 0));
+ if (element != null && element.isValid()) {
+ updateHint(element);
+ }
+ }
+ };
+ table.getSelectionModel().addListSelectionListener(listener);
+ table.getColumnModel().getSelectionModel().addListSelectionListener(listener);
+ }
+
+ public HintUpdateSupply(@NotNull final Tree tree) {
+ installSupply(tree);
+ tree.addTreeSelectionListener(new TreeSelectionListener() {
+ @Override
+ public void valueChanged(final TreeSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(tree)) return;
+
+ TreePath path = tree.getSelectionPath();
+ if (path != null) {
+ final PsiElement psiElement = getPsiElementForHint(path.getLastPathComponent());
+ if (psiElement != null && psiElement.isValid()) {
+ updateHint(psiElement);
+ }
+ }
+ }
+ });
+ }
+
+ public HintUpdateSupply(@NotNull final JBList list) {
+ installSupply(list);
+ list.addListSelectionListener(new ListSelectionListener() {
+ @Override
+ public void valueChanged(final ListSelectionEvent e) {
+ if (!isHintVisible(HintUpdateSupply.this.myHint) || isSelectedByMouse(list)) return;
+
+ Object[] selectedValues = ((JList)e.getSource()).getSelectedValues();
+ if (selectedValues.length != 1) return;
+
+ PsiElement element = getPsiElementForHint(selectedValues[0]);
+ if (element != null && element.isValid()) {
+ updateHint(element);
+ }
+ }
+ });
+ }
+
+ @Nullable
+ protected abstract PsiElement getPsiElementForHint(@Nullable Object selectedValue);
+
+ private void installSupply(@NotNull JComponent component) {
+ component.putClientProperty(HINT_UPDATE_MARKER, this);
+ }
+
+ public void registerHint(JBPopup hint) {
+ hideHint();
+ myHint = hint;
+ }
+
+ public void hideHint() {
+ if (isHintVisible(myHint)) {
+ myHint.cancel();
+ }
+
+ myHint = null;
+ }
+
+ public void updateHint(PsiElement element) {
+ if (!isHintVisible(myHint)) return;
+
+ PopupUpdateProcessorBase updateProcessor = myHint.getUserData(PopupUpdateProcessorBase.class);
+ if (updateProcessor != null) {
+ updateProcessor.updatePopup(element);
+ }
+ }
+
+ @Contract("!null->true")
+ private static boolean isHintVisible(JBPopup hint) {
+ return hint != null && hint.isVisible();
+ }
+
+ private static boolean isSelectedByMouse(@NotNull JComponent c) {
+ return Boolean.TRUE.equals(c.getClientProperty(ListUtil.SELECTED_BY_MOUSE_EVENT));
+ }
+}
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 bda230eb767e..c1146be40aba 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -424,7 +424,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
if (e instanceof KeyEvent) {
// do not start editing in autoStartsEdit mode on Ctrl-Z and other non-typed events
- if (!UIUtil.isReallyTypedEvent((KeyEvent)e)) return false;
+ if (!UIUtil.isReallyTypedEvent((KeyEvent)e) || ((KeyEvent)e).getKeyChar() == KeyEvent.CHAR_UNDEFINED) return false;
SpeedSearchSupply supply = SpeedSearchSupply.getSupply(this);
if (supply != null && supply.isPopupActive()) {
@@ -743,7 +743,7 @@ public class JBTable extends JTable implements ComponentWithEmptyText, Component
@Override
public void setColor(Color color) {
- if (!UIUtil.isUnderDarcula() || !JBTable.this.getBackground().equals(color)) {
+ if (color != null && (!UIUtil.isUnderDarcula() || !JBTable.this.getBackground().equals(color))) {
//noinspection UseJBColor
color = new Color(UIUtil.getGrayFilter().filterRGB(0, 0, color.getRGB()));
}