Merge remote-tracking branch 'origin/master'
@@ -22,11 +22,10 @@ import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogBuilder;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
||||
import com.intellij.refactoring.ui.MemberSelectionPanel;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -35,8 +34,10 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -115,15 +116,15 @@ public class ChangeSuperClassFix implements LocalQuickFix, HighPriorityAction {
|
||||
private static void changeSuperClass(@NotNull final PsiClass aClass,
|
||||
@NotNull final PsiClass oldSuperClass,
|
||||
@NotNull final PsiClass newSuperClass) {
|
||||
List<PsiMethod> ownMethods = ((PsiExtensibleClass)aClass).getOwnMethods();
|
||||
PsiMethod[] ownMethods = aClass.getMethods();
|
||||
// first is own method, second is parent
|
||||
List<Pair<PsiMethod, Set<PsiMethod>>> oldOverridenMethods =
|
||||
ownMethods.stream().map(m -> {
|
||||
Stream.of(ownMethods).map(m -> {
|
||||
if (m.isConstructor()) return null;
|
||||
PsiMethod[] supers = m.findSuperMethods(oldSuperClass);
|
||||
if (supers.length == 0) return null;
|
||||
return Pair.create(m, ContainerUtil.set(supers));
|
||||
}).collect(Collectors.toList());
|
||||
}).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
|
||||
JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(aClass.getProject());
|
||||
PsiElementFactory factory = psiFacade.getElementFactory();
|
||||
@@ -159,21 +160,28 @@ public class ChangeSuperClassFix implements LocalQuickFix, HighPriorityAction {
|
||||
JavaCodeStyleManager.getInstance(aClass.getProject()).shortenClassReferences(ref);
|
||||
});
|
||||
|
||||
if (ownMethods.isEmpty()) {
|
||||
// should not override methods from a new super class
|
||||
return;
|
||||
}
|
||||
Stream<PsiMethod> memberInfos = oldOverridenMethods.stream().filter(m -> {
|
||||
List<MemberInfo> memberInfos = oldOverridenMethods.stream().filter(m -> {
|
||||
Set<PsiMethod> newSupers = ContainerUtil.set(m.getFirst().findSuperMethods(newSuperClass));
|
||||
return !newSupers.equals(m.getSecond());
|
||||
}).map(m -> m.getFirst());
|
||||
}).map(m -> m.getFirst())
|
||||
.map(m -> {
|
||||
MemberInfo info = new MemberInfo(m);
|
||||
info.setChecked(true);
|
||||
return info;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
List<PsiMethod> toDelete = getOverridenMethodsToDelete(memberInfos, newSuperClass.getName());
|
||||
WriteAction.run(() -> {
|
||||
for (PsiMethod method : toDelete) {
|
||||
method.delete();
|
||||
}
|
||||
});
|
||||
if (memberInfos.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<PsiMethod> toDelete = getOverridenMethodsToDelete(memberInfos, newSuperClass.getName(), aClass.getProject());
|
||||
if (!toDelete.isEmpty()) {
|
||||
WriteAction.run(() -> {
|
||||
for (PsiMethod method : toDelete) {
|
||||
method.delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -182,16 +190,26 @@ public class ChangeSuperClassFix implements LocalQuickFix, HighPriorityAction {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiMethod> getOverridenMethodsToDelete(Stream<PsiMethod> candidates, String newClassName) {
|
||||
DialogBuilder dlg = new DialogBuilder();
|
||||
MemberSelectionPanel panel = new MemberSelectionPanel("<html>Choose members to delete since they are already defined in <b>" + newClassName + "</b>",
|
||||
candidates.map(m -> {
|
||||
MemberInfo info = new MemberInfo(m);
|
||||
info.setChecked(true);
|
||||
return info;
|
||||
}).collect(Collectors.toList()), null);
|
||||
dlg.setCenterPanel(panel);
|
||||
dlg.setTitle("Choose Members");
|
||||
private static List<PsiMethod> getOverridenMethodsToDelete(List<MemberInfo> candidates,
|
||||
String newClassName,
|
||||
Project project) {
|
||||
MemberSelectionPanel panel =
|
||||
new MemberSelectionPanel("<html>Choose members to delete since they are already defined in <b>" + newClassName + "</b>",
|
||||
candidates,
|
||||
null);
|
||||
DialogWrapper dlg = new DialogWrapper(project, false) {
|
||||
|
||||
{
|
||||
setOKButtonText("Remove");
|
||||
setTitle("Choose Members");
|
||||
init();
|
||||
}
|
||||
@NotNull
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return panel;
|
||||
}
|
||||
};
|
||||
return dlg.showAndGet()
|
||||
? panel.getTable().getSelectedMemberInfos().stream().map(info -> (PsiMethod)info.getMember()).collect(Collectors.toList())
|
||||
: Collections.emptyList();
|
||||
|
||||
@@ -749,7 +749,6 @@ public class SimpleDiffViewer extends TwosideTextDiffViewer {
|
||||
gg.setColor(DiffDrawUtil.getDividerColor(getEditor1()));
|
||||
gg.fill(gg.getClipBounds());
|
||||
|
||||
//DividerPolygonUtil.paintSimplePolygons(gg, divider.getWidth(), getEditor1(), getEditor2(), this);
|
||||
DiffDividerDrawUtil.paintPolygons(gg, divider.getWidth(), getEditor1(), getEditor2(), this);
|
||||
|
||||
myFoldingModel.paintOnDivider(gg, divider);
|
||||
|
||||
@@ -399,7 +399,6 @@ public abstract class ThreesideTextDiffViewerEx extends ThreesideTextDiffViewer
|
||||
Editor editor1 = mySide.select(getEditor(ThreeSide.LEFT), getEditor(ThreeSide.BASE));
|
||||
Editor editor2 = mySide.select(getEditor(ThreeSide.BASE), getEditor(ThreeSide.RIGHT));
|
||||
|
||||
//DividerPolygonUtil.paintSimplePolygons(gg, divider.getWidth(), editor1, editor2, myPaintable);
|
||||
DiffDividerDrawUtil.paintPolygons(gg, divider.getWidth(), editor1, editor2, myPaintable);
|
||||
|
||||
myFoldingModel.paintOnDivider(gg, divider, mySide);
|
||||
|
||||
@@ -64,20 +64,11 @@ public class DiffDividerDrawUtil {
|
||||
@NotNull Editor editor1,
|
||||
@NotNull Editor editor2,
|
||||
@NotNull DividerPaintable paintable) {
|
||||
paintPolygons(gg, width, true, true, editor1, editor2, paintable);
|
||||
}
|
||||
|
||||
public static void paintSimplePolygons(@NotNull Graphics2D gg,
|
||||
int width,
|
||||
@NotNull Editor editor1,
|
||||
@NotNull Editor editor2,
|
||||
@NotNull DividerPaintable paintable) {
|
||||
paintPolygons(gg, width, true, false, editor1, editor2, paintable);
|
||||
paintPolygons(gg, width, true, editor1, editor2, paintable);
|
||||
}
|
||||
|
||||
public static void paintPolygons(@NotNull Graphics2D gg,
|
||||
int width,
|
||||
boolean paintBorder,
|
||||
boolean curved,
|
||||
@NotNull Editor editor1,
|
||||
@NotNull Editor editor2,
|
||||
@@ -86,7 +77,7 @@ public class DiffDividerDrawUtil {
|
||||
|
||||
GraphicsConfig config = GraphicsUtil.setupAAPainting(gg);
|
||||
for (DividerPolygon polygon : polygons) {
|
||||
polygon.paint(gg, width, paintBorder, curved);
|
||||
polygon.paint(gg, width, curved);
|
||||
}
|
||||
config.restore();
|
||||
}
|
||||
@@ -160,14 +151,6 @@ public class DiffDividerDrawUtil {
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DividerPolygon createPolygon(@NotNull Transformation[] transformations,
|
||||
int startLine1, int endLine1,
|
||||
int startLine2, int endLine2,
|
||||
@NotNull Color color) {
|
||||
return createPolygon(transformations, startLine1, endLine1, startLine2, endLine2, color, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static DividerPolygon createPolygon(@NotNull Transformation[] transformations,
|
||||
int startLine1, int endLine1,
|
||||
@@ -228,10 +211,6 @@ public class DiffDividerDrawUtil {
|
||||
@NotNull private final Color myColor;
|
||||
private final boolean myResolved;
|
||||
|
||||
public DividerPolygon(int start1, int start2, int end1, int end2, @NotNull Color color) {
|
||||
this(start1, start2, end1, end2, color, false);
|
||||
}
|
||||
|
||||
public DividerPolygon(int start1, int start2, int end1, int end2, @NotNull Color color, boolean resolved) {
|
||||
myStart1 = start1;
|
||||
myStart2 = start2;
|
||||
@@ -241,7 +220,7 @@ public class DiffDividerDrawUtil {
|
||||
myResolved = resolved;
|
||||
}
|
||||
|
||||
public void paint(Graphics2D g, int width, boolean paintBorder, boolean curve) {
|
||||
public void paint(Graphics2D g, int width, boolean curve) {
|
||||
int startY1;
|
||||
int endY1;
|
||||
int startY2;
|
||||
@@ -295,10 +274,6 @@ public class DiffDividerDrawUtil {
|
||||
private final int myEnd2;
|
||||
@Nullable private final EditorColorsScheme myScheme;
|
||||
|
||||
public DividerSeparator(int start1, int start2, int end1, int end2) {
|
||||
this(start1, start2, end1, end2, null);
|
||||
}
|
||||
|
||||
public DividerSeparator(int start1, int start2, int end1, int end2, @Nullable EditorColorsScheme scheme) {
|
||||
myStart1 = start1;
|
||||
myStart2 = start2;
|
||||
|
||||
@@ -83,13 +83,6 @@ public class DiffDrawUtil {
|
||||
return gutterBackground;
|
||||
}
|
||||
|
||||
public static void drawConnectorLineSeparator(@NotNull Graphics2D g,
|
||||
int x1, int x2,
|
||||
int start1, int end1,
|
||||
int start2, int end2) {
|
||||
drawConnectorLineSeparator(g, x1, x2, start1, end1, start2, end2, null);
|
||||
}
|
||||
|
||||
public static void drawConnectorLineSeparator(@NotNull Graphics2D g,
|
||||
int x1, int x2,
|
||||
int start1, int end1,
|
||||
|
||||
@@ -40,22 +40,11 @@ public class DiffLineSeparatorRenderer implements LineMarkerRendererEx, LineSepa
|
||||
@NotNull private final Editor myEditor;
|
||||
@NotNull private final BooleanGetter myCondition;
|
||||
|
||||
public DiffLineSeparatorRenderer(@NotNull Editor editor) {
|
||||
this(editor, BooleanGetter.TRUE);
|
||||
}
|
||||
|
||||
public DiffLineSeparatorRenderer(@NotNull Editor editor, @NotNull BooleanGetter condition) {
|
||||
myEditor = editor;
|
||||
myCondition = condition;
|
||||
}
|
||||
|
||||
public static void drawConnectorLine(@NotNull Graphics2D g,
|
||||
int x1, int x2,
|
||||
int start1, int end1,
|
||||
int start2, int end2) {
|
||||
drawConnectorLine(g, x1, x2, start1, start2, end1 - end2, null);
|
||||
}
|
||||
|
||||
/*
|
||||
* Divider
|
||||
*/
|
||||
|
||||
@@ -115,45 +115,49 @@ public class InspectionsConfigTreeTable extends TreeTable {
|
||||
addMouseMotionListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(final MouseEvent e) {
|
||||
Point point = e.getPoint();
|
||||
int column = columnAtPoint(point);
|
||||
int row = rowAtPoint(point);
|
||||
Point point = e.getPoint();
|
||||
int column = columnAtPoint(point);
|
||||
int row = rowAtPoint(point);
|
||||
|
||||
UIUtil.resetEnabledRollOver(InspectionsConfigTreeTable.this, IS_ENABLED_COLUMN);
|
||||
if (row < 0 || row >= getModel().getRowCount()) return;
|
||||
|
||||
switch (column) {
|
||||
case SEVERITIES_COLUMN:
|
||||
Object maybeIcon = getModel().getValueAt(row, column);
|
||||
if (maybeIcon instanceof MultiScopeSeverityIcon) {
|
||||
MultiScopeSeverityIcon icon = (MultiScopeSeverityIcon)maybeIcon;
|
||||
LinkedHashMap<String, HighlightDisplayLevel> scopeToAverageSeverityMap =
|
||||
icon.getScopeToAverageSeverityMap();
|
||||
JComponent component;
|
||||
if (scopeToAverageSeverityMap.size() == 1 &&
|
||||
icon.getDefaultScopeName().equals(ContainerUtil.getFirstItem(scopeToAverageSeverityMap.keySet()))) {
|
||||
HighlightDisplayLevel level = ContainerUtil.getFirstItem(scopeToAverageSeverityMap.values());
|
||||
JLabel label = new JLabel();
|
||||
label.setIcon(level.getIcon());
|
||||
label.setText(SingleInspectionProfilePanel.renderSeverity(level.getSeverity()));
|
||||
component = label;
|
||||
} else {
|
||||
component = new ScopesAndSeveritiesHintTable(scopeToAverageSeverityMap, icon.getDefaultScopeName());
|
||||
UIUtil.resetEnabledRollOver(InspectionsConfigTreeTable.this, IS_ENABLED_COLUMN);
|
||||
|
||||
switch (column) {
|
||||
case SEVERITIES_COLUMN:
|
||||
Object maybeIcon = getModel().getValueAt(row, column);
|
||||
if (maybeIcon instanceof MultiScopeSeverityIcon) {
|
||||
MultiScopeSeverityIcon icon = (MultiScopeSeverityIcon)maybeIcon;
|
||||
LinkedHashMap<String, HighlightDisplayLevel> scopeToAverageSeverityMap =
|
||||
icon.getScopeToAverageSeverityMap();
|
||||
JComponent component = null;
|
||||
if (scopeToAverageSeverityMap.size() == 1 &&
|
||||
icon.getDefaultScopeName().equals(ContainerUtil.getFirstItem(scopeToAverageSeverityMap.keySet()))) {
|
||||
HighlightDisplayLevel level = ContainerUtil.getFirstItem(scopeToAverageSeverityMap.values());
|
||||
if (level != null) {
|
||||
JLabel label = new JLabel();
|
||||
label.setIcon(level.getIcon());
|
||||
label.setText(SingleInspectionProfilePanel.renderSeverity(level.getSeverity()));
|
||||
component = label;
|
||||
}
|
||||
} else {
|
||||
component = new ScopesAndSeveritiesHintTable(scopeToAverageSeverityMap, icon.getDefaultScopeName());
|
||||
}
|
||||
IdeTooltipManager.getInstance().show(
|
||||
new IdeTooltip(InspectionsConfigTreeTable.this, point, component), false);
|
||||
}
|
||||
IdeTooltipManager.getInstance().show(
|
||||
new IdeTooltip(InspectionsConfigTreeTable.this, point, component), false);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case IS_ENABLED_COLUMN:
|
||||
if (Registry.is("ide.intellij.laf.win10.ui")) {
|
||||
JComponent rc = (JComponent)getColumnModel().getColumn(column).getCellRenderer();
|
||||
rc.putClientProperty(UIUtil.CHECKBOX_ROLLOVER_PROPERTY, row);
|
||||
((AbstractTableModel)getModel()).fireTableCellUpdated(row, column);
|
||||
}
|
||||
break;
|
||||
case IS_ENABLED_COLUMN:
|
||||
if (Registry.is("ide.intellij.laf.win10.ui")) {
|
||||
JComponent rc = (JComponent)getColumnModel().getColumn(column).getCellRenderer();
|
||||
rc.putClientProperty(UIUtil.CHECKBOX_ROLLOVER_PROPERTY, row);
|
||||
((AbstractTableModel)getModel()).fireTableCellUpdated(row, column);
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -61,7 +61,11 @@ public class OnOffButton extends JToggleButton {
|
||||
}
|
||||
|
||||
@Override public void updateUI() {
|
||||
setUI(UIManager.get(getUIClassID()) == null ?
|
||||
// Check that class name is in the UI table before creating UI delegate from it.
|
||||
// If the custom class name is not listed (like for example in system LaFs) then
|
||||
// use the default delegate.
|
||||
Object uiClassName = UIManager.get(getUIClassID());
|
||||
setUI(uiClassName == null ?
|
||||
DefaultOnOffButtonUI.createUI(this) :
|
||||
UIManager.getUI(this));
|
||||
}
|
||||
|
||||
@@ -36,6 +36,8 @@ import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Position;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Arrays;
|
||||
@@ -341,4 +343,28 @@ public class DarculaUIUtil {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class MouseHoverPropertyTrigger extends MouseAdapter {
|
||||
private final JComponent repaintComponent;
|
||||
private final String hoverProperty;
|
||||
|
||||
public MouseHoverPropertyTrigger(@NotNull JComponent repaintComponent, @NotNull String hoverProperty) {
|
||||
this.repaintComponent = repaintComponent;
|
||||
this.hoverProperty = hoverProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
JComponent c = (JComponent)e.getComponent();
|
||||
c.putClientProperty(hoverProperty, Boolean.TRUE);
|
||||
repaintComponent.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
JComponent c = (JComponent)e.getComponent();
|
||||
c.putClientProperty(hoverProperty, Boolean.FALSE);
|
||||
repaintComponent.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.components.JBOptionButton;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import sun.swing.SwingUtilities2;
|
||||
@@ -241,14 +242,11 @@ public class DarculaButtonUI extends BasicButtonUI {
|
||||
}
|
||||
|
||||
protected String layout(AbstractButton b, String text, Icon icon, FontMetrics fm, int width, int height) {
|
||||
Insets i = b.getInsets();
|
||||
viewRect.x = i.left;
|
||||
viewRect.y = i.top;
|
||||
viewRect.width = width - (i.right + viewRect.x);
|
||||
viewRect.height = height - (i.bottom + viewRect.y);
|
||||
textRect.setBounds(0, 0, 0, 0);
|
||||
iconRect.setBounds(0, 0, 0, 0);
|
||||
|
||||
textRect.x = textRect.y = textRect.width = textRect.height = 0;
|
||||
iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
|
||||
viewRect.setBounds(0, 0, width, height);
|
||||
JBInsets.removeFrom(viewRect, b.getInsets());
|
||||
|
||||
if (isComboButton(b)) {
|
||||
viewRect.x += 6;
|
||||
|
||||
@@ -332,7 +332,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
try {
|
||||
hasFocus = false;
|
||||
checkFocus();
|
||||
|
||||
final Rectangle arrowButtonBounds = arrowButton.getBounds();
|
||||
@@ -395,6 +394,7 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB
|
||||
}
|
||||
|
||||
protected void checkFocus() {
|
||||
hasFocus = false;
|
||||
if (!comboBox.isEnabled()) {
|
||||
hasFocus = false;
|
||||
return;
|
||||
@@ -403,7 +403,7 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB
|
||||
hasFocus = hasFocus(comboBox);
|
||||
if (hasFocus) return;
|
||||
|
||||
final ComboBoxEditor ed = comboBox.getEditor();
|
||||
ComboBoxEditor ed = comboBox.getEditor();
|
||||
editor = ed == null ? null : ed.getEditorComponent();
|
||||
if (editor != null) {
|
||||
hasFocus = hasFocus(editor);
|
||||
@@ -411,7 +411,7 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB
|
||||
}
|
||||
|
||||
protected static boolean hasFocus(Component c) {
|
||||
final Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
||||
return owner != null && SwingUtilities.isDescendingFrom(owner, c);
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 113 B After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 112 B After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 15 KiB |
@@ -17,88 +17,400 @@ package com.intellij.ide.ui.laf.intellij;
|
||||
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaComboBoxUI;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.ui.Gray;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import com.intellij.util.IconUtil;
|
||||
import com.intellij.util.ui.JBInsets;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicArrowButton;
|
||||
import javax.swing.plaf.basic.BasicComboBoxEditor;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class WinIntelliJComboBoxUI extends DarculaComboBoxUI {
|
||||
private static final String HOVER_PROPERTY = "JComboBox.mouseHover";
|
||||
private static final String PRESSED_PROPERTY = "JComboBox.mousePressed";
|
||||
|
||||
private static final Border DEFAULT_EDITOR_BORDER = JBUI.Borders.empty(1, 0);
|
||||
private static final Dimension BUTTON_SIZE = JBUI.size(20, 22);
|
||||
|
||||
private MouseListener mouseListener;
|
||||
|
||||
private MouseListener buttonReleaseListener;
|
||||
private MouseListener buttonHoverListener;
|
||||
private PropertyChangeListener propertyListener;
|
||||
|
||||
private MouseListener editorHoverListener;
|
||||
private KeyListener editorKeyListener;
|
||||
private FocusListener editorFocusListener;
|
||||
|
||||
public WinIntelliJComboBoxUI(JComboBox comboBox) {
|
||||
super(comboBox);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new WinIntelliJComboBoxUI((JComboBox)c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g, JComponent c) {
|
||||
final int w = c.getWidth();
|
||||
final int h = c.getHeight();
|
||||
@Override protected void installListeners() {
|
||||
super.installListeners();
|
||||
|
||||
if (!comboBox.isEditable()) {
|
||||
comboBox.addMouseListener(mouseListener = new ComboBoxMouseListener());
|
||||
}
|
||||
|
||||
propertyListener = (evt) -> {
|
||||
if("enabled".equals(evt.getPropertyName())) {
|
||||
setEditorTextFieldBackground();
|
||||
} else if ("editable".equals(evt.getPropertyName())) {
|
||||
if (evt.getNewValue() == Boolean.TRUE) {
|
||||
comboBox.removeMouseListener(mouseListener);
|
||||
} else {
|
||||
comboBox.addMouseListener(mouseListener);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
comboBox.addPropertyChangeListener(propertyListener);
|
||||
}
|
||||
|
||||
@Override public void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
comboBox.removeMouseListener(mouseListener);
|
||||
|
||||
if (propertyListener != null) {
|
||||
comboBox.removePropertyChangeListener(propertyListener);
|
||||
propertyListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void paint(Graphics g, JComponent c) {
|
||||
int w = c.getWidth();
|
||||
int h = c.getHeight();
|
||||
|
||||
if (c.isOpaque()) {
|
||||
final Container parent = c.getParent();
|
||||
Container parent = c.getParent();
|
||||
if (parent != null) {
|
||||
g.setColor(isTableCellEditor(c) && editor != null ? editor.getBackground() : parent.getBackground());
|
||||
g.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
}
|
||||
Rectangle r = rectangleForCurrentValue();
|
||||
|
||||
int bw = JBUI.scale(1);
|
||||
|
||||
g.setColor(getComboBackground());
|
||||
g.fillRect(JBUI.scale(1), JBUI.scale(1), w-2*JBUI.scale(1), h-2*JBUI.scale(1));
|
||||
g.fillRect(bw, bw, w-2*bw, h-2*bw);
|
||||
|
||||
if (!isTableCellEditor(c)) {
|
||||
paintBorder(c, g, 0, 0, w, h);
|
||||
hasFocus = comboBox.hasFocus();
|
||||
paintCurrentValueBackground(g, r, hasFocus);
|
||||
}
|
||||
paintCurrentValue(g, r, hasFocus);
|
||||
|
||||
if (!comboBox.isEditable()) {
|
||||
Rectangle r = rectangleForCurrentValue();
|
||||
paintCurrentValue(g, r, hasFocus);
|
||||
}
|
||||
}
|
||||
|
||||
protected Color getComboBackground() {
|
||||
if (!comboBox.isEnabled() && !comboBox.isEditable()) {
|
||||
return UIManager.getColor("ComboBox.disabledBackground");
|
||||
@Override protected Rectangle rectangleForCurrentValue() {
|
||||
int width = comboBox.getWidth();
|
||||
int height = comboBox.getHeight();
|
||||
Insets insets = getInsets();
|
||||
int buttonSize = height - (insets.top + insets.bottom);
|
||||
if ( arrowButton != null ) {
|
||||
buttonSize = arrowButton.getWidth();
|
||||
}
|
||||
if (comboBox.isEditable()) {
|
||||
final ComboBoxEditor editor = comboBox.getEditor();
|
||||
if (editor != null && editor.getEditorComponent() != null) {
|
||||
return editor.getEditorComponent().getBackground();
|
||||
} else {
|
||||
return Gray.xFF;
|
||||
|
||||
Rectangle rect = (comboBox.getComponentOrientation().isLeftToRight()) ?
|
||||
new Rectangle(insets.left, insets.top,
|
||||
width - (insets.left + insets.right + buttonSize),
|
||||
height - (insets.top + insets.bottom)) :
|
||||
new Rectangle(insets.left + buttonSize, insets.top,
|
||||
width - (insets.left + insets.right + buttonSize),
|
||||
height - (insets.top + insets.bottom));
|
||||
|
||||
if (editor instanceof JComponent) {
|
||||
JBInsets.removeFrom(rect, ((JComponent)editor).getInsets());
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||
Component c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false);
|
||||
|
||||
c.setBackground(getComboBackground());
|
||||
c.setFont(comboBox.getFont());
|
||||
c.setForeground(comboBox.isEnabled() ? UIManager.getColor("Label.foreground") : UIManager.getColor("Label.disabledForeground"));
|
||||
|
||||
// paint selection in table-cell-editor mode correctly
|
||||
boolean changeOpaque = c instanceof JComponent && isTableCellEditor(comboBox) && c.isOpaque();
|
||||
if (changeOpaque) {
|
||||
((JComponent)c).setOpaque(false);
|
||||
}
|
||||
|
||||
Rectangle r = new Rectangle(bounds);
|
||||
Insets i = UIManager.getInsets("ComboBox.padding");
|
||||
if (i == null && c instanceof JComponent) {
|
||||
i = ((JComponent)c).getInsets();
|
||||
}
|
||||
|
||||
JBInsets.removeFrom(r, i);
|
||||
|
||||
currentValuePane.paintComponent(g, c, comboBox, r.x, r.y, r.width, r.height, c instanceof JPanel);
|
||||
|
||||
// return opaque for combobox popup items painting
|
||||
if (changeOpaque) {
|
||||
((JComponent)c).setOpaque(true);
|
||||
}
|
||||
}
|
||||
|
||||
private Color getComboBackground() {
|
||||
if (comboBox.isEnabled() && comboBox.isEditable()) {
|
||||
return UIManager.getColor("TextField.background");
|
||||
} else if (!comboBox.isEnabled()) {
|
||||
return UIManager.getColor("Button.background");
|
||||
} else if (!comboBox.isEditable()) {
|
||||
if (isPressed()) {
|
||||
return UIManager.getColor("Button.intellij.native.pressedBackgroundColor");
|
||||
} else if (isHover()) {
|
||||
return UIManager.getColor("Button.intellij.native.focusedBackgroundColor");
|
||||
}
|
||||
}
|
||||
return comboBox.getBackground();
|
||||
return UIManager.getColor("Button.background");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JButton createArrowButton() {
|
||||
final JButton button = new BasicArrowButton(SwingConstants.SOUTH) {
|
||||
JButton button = new BasicArrowButton(SwingConstants.SOUTH) {
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return JBUI.size(14, 10);
|
||||
return BUTTON_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g) {
|
||||
g.setColor(getComboBackground());
|
||||
g.fillRect(0, 0, getWidth(), getHeight());
|
||||
IconUtil.paintInCenterOf(this, g, MacIntelliJIconCache.getIcon("comboDropTriangle", false, false, isEnabled()));
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
try {
|
||||
int bw = JBUI.scale(1);
|
||||
|
||||
Rectangle2D innerRect = new Rectangle2D.Double(bw, bw, getWidth() - bw*2, getHeight() - bw*2);
|
||||
if (comboBox.isEditable() && comboBox.isEnabled()) {
|
||||
if (isPressed()) {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.pressedBackgroundColor"));
|
||||
} else if (comboBox.hasFocus() || isHover()) {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.focusedBackgroundColor"));
|
||||
} else {
|
||||
g2.setColor(getComboBackground());
|
||||
}
|
||||
} else {
|
||||
g2.setColor(getComboBackground());
|
||||
}
|
||||
|
||||
if (!comboBox.isEnabled()) {
|
||||
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f));
|
||||
}
|
||||
|
||||
g2.fill(innerRect);
|
||||
|
||||
// paint border around button when combobox is editable
|
||||
if (comboBox.isEditable() && comboBox.isEnabled()) {
|
||||
Path2D border = new Path2D.Double(Path2D.WIND_EVEN_ODD);
|
||||
border.append(new Rectangle2D.Double(0, 0, getWidth(), getHeight()), false);
|
||||
border.append(innerRect, false);
|
||||
|
||||
if (getModel().isPressed()) {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.pressedBorderColor"));
|
||||
g2.fill(border);
|
||||
} else if (comboBox.hasFocus() || isHover()) {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.focusedBorderColor"));
|
||||
g2.fill(border);
|
||||
}
|
||||
}
|
||||
|
||||
IconUtil.paintInCenterOf(this, g2, MacIntelliJIconCache.getIcon("comboDropTriangle", false, false, isEnabled()));
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
button.setOpaque(false);
|
||||
button.setBorder(JBUI.Borders.empty());
|
||||
button.setBorder(JBUI.Borders.empty(1, 0, 1, 1));
|
||||
buttonReleaseListener = new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
if (!comboBox.isEditable()) {
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
buttonHoverListener = new DarculaUIUtil.MouseHoverPropertyTrigger(comboBox, HOVER_PROPERTY);
|
||||
|
||||
button.addMouseListener(buttonHoverListener);
|
||||
button.addMouseListener(buttonReleaseListener);
|
||||
return button;
|
||||
}
|
||||
|
||||
@Override public void unconfigureArrowButton() {
|
||||
super.unconfigureArrowButton();
|
||||
if (arrowButton != null) {
|
||||
arrowButton.removeMouseListener(buttonReleaseListener);
|
||||
arrowButton.removeMouseListener(buttonHoverListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ComboBoxEditor createEditor() {
|
||||
ComboBoxEditor comboBoxEditor = new BasicComboBoxEditor.UIResource() {
|
||||
@Override
|
||||
protected JTextField createEditorComponent() {
|
||||
return new JTextField() {
|
||||
{
|
||||
setOpaque(false);
|
||||
setBorder(DEFAULT_EDITOR_BORDER);
|
||||
}
|
||||
|
||||
public void setText(String s) {
|
||||
if (getText().equals(s)) {
|
||||
return;
|
||||
}
|
||||
super.setText(s);
|
||||
}
|
||||
|
||||
@Override public Color getBackground() {
|
||||
return getComboBackground();
|
||||
}
|
||||
@Override public void setBorder(Border border) {}
|
||||
@Override public Border getBorder() {
|
||||
return DEFAULT_EDITOR_BORDER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
Dimension size = super.getPreferredSize();
|
||||
return new Dimension(size.width, BUTTON_SIZE.height);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
Component ec = comboBoxEditor.getEditorComponent();
|
||||
if (ec != null) {
|
||||
editorKeyListener = new KeyAdapter() {
|
||||
@Override public void keyPressed(KeyEvent e) {
|
||||
process(e);
|
||||
}
|
||||
@Override public void keyReleased(KeyEvent e) {
|
||||
process(e);
|
||||
}
|
||||
|
||||
private void process(KeyEvent e) {
|
||||
int code = e.getKeyCode();
|
||||
if ((code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN) && e.getModifiers() == 0) {
|
||||
comboBox.dispatchEvent(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ec.addKeyListener(editorKeyListener);
|
||||
}
|
||||
return comboBoxEditor;
|
||||
}
|
||||
|
||||
@Override protected void configureEditor() {
|
||||
if (editor != null) {
|
||||
editorFocusListener = new FocusAdapter() {
|
||||
@Override public void focusGained(FocusEvent e) {
|
||||
update();
|
||||
}
|
||||
@Override public void focusLost(FocusEvent e) {
|
||||
update();
|
||||
}
|
||||
|
||||
private void update() {
|
||||
if (comboBox != null) {
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
editorHoverListener = new DarculaUIUtil.MouseHoverPropertyTrigger(comboBox, HOVER_PROPERTY);
|
||||
|
||||
if (editor instanceof JTextComponent) {
|
||||
editor.addFocusListener(editorFocusListener);
|
||||
editor.addMouseListener(editorHoverListener);
|
||||
} else {
|
||||
EditorTextField etf = UIUtil.findComponentOfType((JComponent)editor, EditorTextField.class);
|
||||
if (etf != null) {
|
||||
etf.addFocusListener(editorFocusListener);
|
||||
etf.addMouseListener(editorHoverListener);
|
||||
}
|
||||
}
|
||||
|
||||
((JComponent)editor).setBorder(DEFAULT_EDITOR_BORDER);
|
||||
((JComponent)editor).setOpaque(false);
|
||||
|
||||
setEditorTextFieldBackground();
|
||||
}
|
||||
}
|
||||
|
||||
private void setEditorTextFieldBackground() {
|
||||
EditorTextField etf = UIUtil.findComponentOfType((JComponent)editor, EditorTextField.class);
|
||||
if (etf != null && comboBox.isEditable()) {
|
||||
etf.setBackground(getComboBackground());
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void unconfigureEditor() {
|
||||
super.unconfigureEditor();
|
||||
|
||||
if (editorKeyListener != null) {
|
||||
editor.removeKeyListener(editorKeyListener);
|
||||
}
|
||||
|
||||
if (editor instanceof JTextComponent) {
|
||||
if (editorFocusListener != null) {
|
||||
editor.removeFocusListener(editorFocusListener);
|
||||
}
|
||||
|
||||
if (editorHoverListener != null) {
|
||||
editor.removeMouseListener(editorHoverListener);
|
||||
}
|
||||
} else {
|
||||
EditorTextField etf = UIUtil.findComponentOfType((JComponent)editor, EditorTextField.class);
|
||||
if (etf != null) {
|
||||
if (editorHoverListener != null) {
|
||||
etf.removeFocusListener(editorFocusListener);
|
||||
}
|
||||
|
||||
if (editorHoverListener != null) {
|
||||
etf.removeMouseListener(editorHoverListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
|
||||
if (comboBox == null || arrowButton == null) {
|
||||
@@ -107,28 +419,119 @@ public class WinIntelliJComboBoxUI extends DarculaComboBoxUI {
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
try {
|
||||
hasFocus = false;
|
||||
checkFocus();
|
||||
Object eop = ((JComponent)c).getClientProperty("JComponent.error.outline");
|
||||
if (Registry.is("ide.inplace.errors.outline") && Boolean.parseBoolean(String.valueOf(eop))) {
|
||||
g2.translate(x, y);
|
||||
g2.translate(x, y);
|
||||
|
||||
if (Registry.is("ide.inplace.errors.outline") && comboBox.getClientProperty("JComponent.error.outline") == Boolean.TRUE) {
|
||||
DarculaUIUtil.paintErrorBorder(g2, width, height, 0, true, hasFocus);
|
||||
} else if (hasFocus) {
|
||||
g2.setColor(UIManager.getColor("ComboBox.activeBorderColor"));
|
||||
g2.setStroke(new BasicStroke(JBUI.scale(2f)));
|
||||
} else if (comboBox.isEnabled()) {
|
||||
if (comboBox.isEditable()) {
|
||||
if (hasFocus) {
|
||||
g2.setColor(UIManager.getColor("TextField.focusedBorderColor"));
|
||||
} else {
|
||||
g2.setColor(UIManager.getColor(isEditorHover() ? "TextField.hoverBorderColor" : "TextField.borderColor"));
|
||||
}
|
||||
} else {
|
||||
if (isPressed()) {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.pressedBorderColor"));
|
||||
} else if (isHover() || hasFocus) {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.focusedBorderColor"));
|
||||
} else {
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.borderColor"));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
g2.setColor(UIManager.getColor("ComboBox.borderColor"));
|
||||
g2.setColor(UIManager.getColor("Button.intellij.native.borderColor"));
|
||||
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f));
|
||||
}
|
||||
|
||||
g2.translate(x, y);
|
||||
g2.drawRect(JBUI.scale(1), JBUI.scale(1), width-2*JBUI.scale(1), height-2*JBUI.scale(1));
|
||||
|
||||
int bw = JBUI.scale(1);
|
||||
Path2D border = new Path2D.Double(Path2D.WIND_EVEN_ODD);
|
||||
border.append(new Rectangle2D.Double(0, 0, width, height), false);
|
||||
border.append(new Rectangle2D.Double(bw, bw, width - bw*2, height - bw*2), false);
|
||||
g2.fill(border);
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHover() {
|
||||
return comboBox != null && comboBox.getClientProperty(HOVER_PROPERTY) == Boolean.TRUE ||
|
||||
arrowButton != null && arrowButton.getClientProperty(HOVER_PROPERTY) == Boolean.TRUE;
|
||||
}
|
||||
|
||||
private boolean isEditorHover() {
|
||||
JComponent ec = (JComponent)comboBox.getEditor().getEditorComponent();
|
||||
EditorTextField etf = UIUtil.findComponentOfType((JComponent)editor, EditorTextField.class);
|
||||
Editor editor = etf != null ? etf.getEditor() : null;
|
||||
|
||||
return arrowButton != null && arrowButton.getClientProperty(HOVER_PROPERTY) == Boolean.TRUE ||
|
||||
ec != null && ec.getClientProperty(HOVER_PROPERTY) == Boolean.TRUE ||
|
||||
editor != null && editor.getContentComponent().getClientProperty(HOVER_PROPERTY) == Boolean.TRUE;
|
||||
}
|
||||
|
||||
private boolean isPressed() {
|
||||
return comboBox != null && comboBox.getClientProperty(PRESSED_PROPERTY) == Boolean.TRUE ||
|
||||
arrowButton != null && arrowButton.getModel().isPressed();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Insets getInsets() {
|
||||
return JBUI.insets(4, 5).asUIResource();
|
||||
return JBUI.insets(0, 5, 0, 0).asUIResource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Insets getBorderInsets(Component c) {
|
||||
return getInsets();
|
||||
}
|
||||
|
||||
private Dimension getSizeWithIcon(Dimension d) {
|
||||
Insets i = comboBox.getInsets();
|
||||
int iconWidth = BUTTON_SIZE.width + i.right;
|
||||
int iconHeight = BUTTON_SIZE.height + i.top + i.bottom;
|
||||
return new Dimension(Math.max(d.width + 7, iconWidth), iconHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize(JComponent c) {
|
||||
return getSizeWithIcon(super.getPreferredSize(c));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension getMinimumSize(JComponent c) {
|
||||
return getSizeWithIcon(super.getMinimumSize(c));
|
||||
}
|
||||
|
||||
private class ComboBoxMouseListener extends MouseAdapter {
|
||||
@Override public void mousePressed(MouseEvent e) {
|
||||
setPressedProperty(true);
|
||||
}
|
||||
|
||||
@Override public void mouseReleased(MouseEvent e) {
|
||||
setPressedProperty(false);
|
||||
}
|
||||
|
||||
private void setPressedProperty(boolean isPressed) {
|
||||
if (!comboBox.isEditable()) {
|
||||
comboBox.putClientProperty(PRESSED_PROPERTY, Boolean.valueOf(isPressed));
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
setHoverProperty(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
setHoverProperty(false);
|
||||
}
|
||||
|
||||
private void setHoverProperty(boolean isHover) {
|
||||
comboBox.putClientProperty(HOVER_PROPERTY, Boolean.valueOf(isHover));
|
||||
comboBox.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.ide.ui.laf.intellij;
|
||||
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicPasswordFieldUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
import static com.intellij.ide.ui.laf.intellij.WinIntelliJTextFieldUI.HOVER_PROPERTY;
|
||||
|
||||
public class WinIntelliJPasswordFieldUI extends BasicPasswordFieldUI {
|
||||
|
||||
private final JPasswordField passwordField;
|
||||
private MouseListener hoverListener;
|
||||
private FocusListener focusListener;
|
||||
|
||||
public WinIntelliJPasswordFieldUI(JPasswordField passwordField) {
|
||||
this.passwordField = passwordField;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
return new WinIntelliJPasswordFieldUI((JPasswordField)c);
|
||||
}
|
||||
|
||||
@Override public void installListeners() {
|
||||
super.installListeners();
|
||||
hoverListener = new DarculaUIUtil.MouseHoverPropertyTrigger(passwordField, HOVER_PROPERTY);
|
||||
focusListener = new FocusListener() {
|
||||
@Override public void focusGained(FocusEvent e) {
|
||||
passwordField.repaint();
|
||||
}
|
||||
|
||||
@Override public void focusLost(FocusEvent e) {
|
||||
passwordField.repaint();
|
||||
}
|
||||
};
|
||||
|
||||
passwordField.addMouseListener(hoverListener);
|
||||
passwordField.addFocusListener(focusListener);
|
||||
}
|
||||
|
||||
@Override public void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
if (hoverListener != null) {
|
||||
passwordField.removeMouseListener(hoverListener);
|
||||
}
|
||||
|
||||
if (focusListener != null) {
|
||||
passwordField.removeFocusListener(focusListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
JTextComponent c = getComponent();
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
try {
|
||||
Container parent = c.getParent();
|
||||
if (c.isOpaque() && parent != null) {
|
||||
g2.setColor(parent.getBackground());
|
||||
g2.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
}
|
||||
|
||||
if (c.getBorder() instanceof WinIntelliJTextBorder){
|
||||
WinIntelliJTextFieldUI.paintTextFieldBackground(c, g2);
|
||||
}
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,15 +15,16 @@
|
||||
*/
|
||||
package com.intellij.ide.ui.laf.intellij;
|
||||
|
||||
import com.intellij.ide.ui.laf.darcula.DarculaUIUtil;
|
||||
import com.intellij.ide.ui.laf.darcula.ui.DarculaTextFieldUI;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -31,38 +32,38 @@ import java.awt.event.MouseEvent;
|
||||
public class WinIntelliJTextFieldUI extends DarculaTextFieldUI {
|
||||
public static final String HOVER_PROPERTY = "JTextField.hover";
|
||||
|
||||
private MouseListener hoverListener;
|
||||
|
||||
public WinIntelliJTextFieldUI(JTextField textField) {
|
||||
super(textField);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
|
||||
@SuppressWarnings({"MethodOverridesStaticMethodOfSuperclass", "UnusedDeclaration"})
|
||||
public static ComponentUI createUI(JComponent c) {
|
||||
c.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
JComponent c = (JComponent)e.getComponent();
|
||||
c.putClientProperty(HOVER_PROPERTY, Boolean.TRUE);
|
||||
c.repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
JComponent c = (JComponent)e.getComponent();
|
||||
c.putClientProperty(HOVER_PROPERTY, Boolean.FALSE);
|
||||
c.repaint();
|
||||
}
|
||||
});
|
||||
|
||||
return new WinIntelliJTextFieldUI((JTextField)c);
|
||||
}
|
||||
|
||||
@Override public void installListeners() {
|
||||
super.installListeners();
|
||||
hoverListener = new DarculaUIUtil.MouseHoverPropertyTrigger(myTextField, HOVER_PROPERTY);
|
||||
myTextField.addMouseListener(hoverListener);
|
||||
}
|
||||
|
||||
@Override public void uninstallListeners() {
|
||||
super.uninstallListeners();
|
||||
if (hoverListener != null) {
|
||||
myTextField.removeMouseListener(hoverListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintBackground(Graphics g) {
|
||||
JTextComponent c = getComponent();
|
||||
if (UIUtil.getParentOfType(JComboBox.class, c) != null) return;
|
||||
|
||||
Graphics2D g2 = (Graphics2D)g.create();
|
||||
try {
|
||||
JTextComponent c = getComponent();
|
||||
Container parent = c.getParent();
|
||||
|
||||
if (c.isOpaque() && parent != null) {
|
||||
g2.setColor(parent.getBackground());
|
||||
g2.fillRect(0, 0, c.getWidth(), c.getHeight());
|
||||
@@ -71,17 +72,25 @@ public class WinIntelliJTextFieldUI extends DarculaTextFieldUI {
|
||||
if (isSearchField(c)) {
|
||||
Rectangle r = getDrawingRect();
|
||||
paintSearchField(g2, c, r);
|
||||
} else {
|
||||
g2.setColor(c.isEnabled() ? c.getBackground() : UIManager.getColor("Button.background"));
|
||||
|
||||
int bw = JBUI.scale(1);
|
||||
g2.fillRect(bw, bw, c.getWidth() - bw*2, c.getHeight() - bw*2);
|
||||
} else if (c.getBorder() instanceof WinIntelliJTextBorder){
|
||||
paintTextFieldBackground(c, g2);
|
||||
}
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
static void paintTextFieldBackground(JComponent c, Graphics2D g2) {
|
||||
g2.setColor(c.isEnabled() ? c.getBackground() : UIManager.getColor("Button.background"));
|
||||
|
||||
if (!c.isEnabled()) {
|
||||
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.35f));
|
||||
}
|
||||
|
||||
int bw = JBUI.scale(1);
|
||||
g2.fillRect(bw, bw, c.getWidth() - bw*2, c.getHeight() - bw*2);
|
||||
}
|
||||
|
||||
@Override public Dimension getPreferredSize(JComponent c) {
|
||||
Dimension size = super.getPreferredSize(c);
|
||||
size.height = isSearchField(c) ? size.height : JBUI.scale(22);
|
||||
|
||||
@@ -71,8 +71,8 @@ TextArea.selectionForeground=ffffff
|
||||
TextArea.background=ffffff
|
||||
|
||||
PasswordField.background=ffffff
|
||||
PasswordFieldUI=com.intellij.ide.ui.laf.darcula.ui.DarculaPasswordFieldUI
|
||||
PasswordField.border=com.intellij.ide.ui.laf.darcula.ui.DarculaTextBorder
|
||||
PasswordFieldUI=com.intellij.ide.ui.laf.intellij.WinIntelliJPasswordFieldUI
|
||||
PasswordField.border=com.intellij.ide.ui.laf.intellij.WinIntelliJTextBorder
|
||||
|
||||
ProgressBarUI=com.intellij.ide.ui.laf.darcula.ui.DarculaProgressBarUI
|
||||
ProgressBar.border=com.intellij.ide.ui.laf.darcula.ui.DarculaProgressBarBorder
|
||||
@@ -80,8 +80,8 @@ ProgressBar.foreground=808080
|
||||
|
||||
FormattedTextField.background=ffffff
|
||||
|
||||
|
||||
CheckBoxUI=com.intellij.ide.ui.laf.intellij.WinIntelliJCheckBoxUI
|
||||
CheckBox.disabledText=8a8a8a
|
||||
CheckBox.border=com.intellij.ide.ui.laf.darcula.ui.DarculaCheckBoxBorder
|
||||
CheckBox.darcula.inactiveFillColor=00000000
|
||||
CheckBox.darcula.borderColor1=444444
|
||||
@@ -110,13 +110,6 @@ CheckBox.darcula.focused.backgroundColor2=eeeeee
|
||||
CheckBox.darcula.focused.backgroundColor2.selected=3B98FB
|
||||
|
||||
ComboBoxUI=com.intellij.ide.ui.laf.intellij.WinIntelliJComboBoxUI
|
||||
ComboBox.disabledBackground=e1e1e1
|
||||
ComboBox.squareButton=false
|
||||
ComboBox.borderColor=adadad
|
||||
ComboBox.activeBorderColor=0078d7
|
||||
ComboBox.background=ffffff
|
||||
ComboBox.darcula.arrowFillColor=457dd7
|
||||
ComboBox.darcula.arrowFocusedFillColor=2d82ed
|
||||
|
||||
RadioButtonUI=com.intellij.ide.ui.laf.intellij.WinIntelliJRadioButtonUI
|
||||
RadioButton.disabledText=8a8a8a
|
||||
|
||||
@@ -272,7 +272,10 @@ public class NotificationsConfigurablePanel extends JPanel implements Disposable
|
||||
int column = columnAtPoint(point);
|
||||
int row = rowAtPoint(point);
|
||||
|
||||
if (row < 0 || row >= getModel().getRowCount()) return;
|
||||
|
||||
UIUtil.resetEnabledRollOver(NotificationsTreeTable.this, LOG_COLUMN);
|
||||
|
||||
if (column == LOG_COLUMN) {
|
||||
JComponent rc = (JComponent)getColumnModel().getColumn(column).getCellRenderer();
|
||||
rc.putClientProperty(UIUtil.CHECKBOX_ROLLOVER_PROPERTY, row);
|
||||
|
||||
@@ -58,10 +58,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.FocusAdapter;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -69,7 +66,7 @@ import java.util.List;
|
||||
* @author max
|
||||
*/
|
||||
public class EditorTextField extends NonOpaquePanel implements DocumentListener, TextComponent, DataProvider,
|
||||
DocumentBasedComponent, FocusListener {
|
||||
DocumentBasedComponent, FocusListener, MouseListener {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.ui.EditorTextField");
|
||||
public static final Key<Boolean> SUPPLEMENTARY_KEY = Key.create("Supplementary");
|
||||
|
||||
@@ -81,6 +78,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
|
||||
private boolean myWholeTextSelected;
|
||||
private final List<DocumentListener> myDocumentListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private final List<FocusListener> myFocusListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private final List<MouseListener> myMouseListeners = ContainerUtil.createLockFreeCopyOnWriteList();
|
||||
private boolean myIsListenerInstalled;
|
||||
private boolean myIsViewer;
|
||||
private boolean myIsSupplementary;
|
||||
@@ -395,6 +393,7 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
|
||||
remove(editor.getComponent());
|
||||
|
||||
editor.getContentComponent().removeFocusListener(this);
|
||||
editor.getContentComponent().removeMouseListener(this);
|
||||
|
||||
if (!editor.isDisposed()) {
|
||||
EditorFactory.getInstance().releaseEditor(editor);
|
||||
@@ -511,7 +510,8 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
|
||||
editor.putUserData(SUPPLEMENTARY_KEY, myIsSupplementary);
|
||||
editor.getContentComponent().setFocusCycleRoot(false);
|
||||
editor.getContentComponent().addFocusListener(this);
|
||||
|
||||
editor.getContentComponent().addMouseListener(this);
|
||||
|
||||
editor.setPlaceholder(myHintText);
|
||||
|
||||
initOneLineMode(editor);
|
||||
@@ -777,6 +777,53 @@ public class EditorTextField extends NonOpaquePanel implements DocumentListener,
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod")
|
||||
@Override
|
||||
public void addMouseListener(MouseListener l) {
|
||||
myMouseListeners.add(l);
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonSynchronizedMethodOverridesSynchronizedMethod")
|
||||
@Override
|
||||
public void removeMouseListener(MouseListener l) {
|
||||
myMouseListeners.remove(l);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
for (MouseListener listener : myMouseListeners) {
|
||||
listener.mouseClicked(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
for (MouseListener listener : myMouseListeners) {
|
||||
listener.mousePressed(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent e) {
|
||||
for (MouseListener listener : myMouseListeners) {
|
||||
listener.mouseReleased(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseEntered(MouseEvent e) {
|
||||
for (MouseListener listener : myMouseListeners) {
|
||||
listener.mouseEntered(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseExited(MouseEvent e) {
|
||||
for (MouseListener listener : myMouseListeners) {
|
||||
listener.mouseExited(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(String dataId) {
|
||||
if (myEditor != null && myEditor.isRendererMode()) {
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.impl.AbstractEditorTest;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.editor.impl.SoftWrapModelImpl;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.testFramework.EditorTestUtil;
|
||||
import com.intellij.testFramework.TestFileType;
|
||||
@@ -865,7 +866,10 @@ public class SoftWrapApplianceOnDocumentModificationTest extends AbstractEditorT
|
||||
VisualPosition caretPositionBefore = getEditor().getCaretModel().getVisualPosition();
|
||||
|
||||
// Change tab size.
|
||||
final CommonCodeStyleSettings.IndentOptions indentOptions = getCurrentCodeStyleSettings().getIndentOptions();
|
||||
final CommonCodeStyleSettings.IndentOptions indentOptions = getCurrentCodeStyleSettings()
|
||||
.getCommonSettings(PlainTextLanguage.INSTANCE)
|
||||
.getIndentOptions();
|
||||
|
||||
assertNotNull(indentOptions);
|
||||
indentOptions.TAB_SIZE++;
|
||||
|
||||
|
||||
@@ -78,7 +78,6 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSchemes;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.impl.DocumentCommitThread;
|
||||
@@ -607,7 +606,6 @@ public abstract class LightPlatformTestCase extends UsefulTestCase implements Da
|
||||
@NotNull
|
||||
@Override
|
||||
protected CodeStyleSettings getCurrentCodeStyleSettings() {
|
||||
if (CodeStyleSchemes.getInstance().getCurrentScheme() == null) return new CodeStyleSettings();
|
||||
return CodeStyleSettingsManager.getSettings(getProject());
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSchemes;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
|
||||
@@ -296,7 +295,6 @@ public abstract class UsefulTestCase extends TestCase {
|
||||
|
||||
@NotNull
|
||||
protected CodeStyleSettings getCurrentCodeStyleSettings() {
|
||||
if (CodeStyleSchemes.getInstance().getCurrentScheme() == null) return new CodeStyleSettings();
|
||||
return CodeStyleSettingsManager.getInstance().getCurrentSettings();
|
||||
}
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ public class JBUI {
|
||||
try {
|
||||
gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
|
||||
} catch (HeadlessException ignore) {}
|
||||
if (gd != null) {
|
||||
if (gd != null && gd.getDefaultConfiguration() != null) {
|
||||
return sysScale(gd.getDefaultConfiguration());
|
||||
}
|
||||
return 1.0f;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -17,6 +17,7 @@ package com.siyeh.ig.psiutils;
|
||||
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.profile.codeInspection.ProjectInspectionProfileManager;
|
||||
import com.intellij.psi.PsiCall;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
@@ -97,6 +98,7 @@ public class MethodMatcher {
|
||||
}
|
||||
myMethodNamePatterns.set(index, pattern + '|' + methodName);
|
||||
}
|
||||
ProjectInspectionProfileManager.getInstance(method.getProject()).fireProfileChanged();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -218,7 +218,7 @@ public class SvnPropertiesDiffViewer extends TwosideTextDiffViewer {
|
||||
int shift2 = editor2.getScrollingModel().getVerticalScrollOffset() - headerOffset2;
|
||||
double rotate = shift1 == shift2 ? 0 : Math.atan2(shift2 - shift1, clip.width);
|
||||
|
||||
DiffDividerDrawUtil.paintPolygons(gg, divider.getWidth(), false, rotate == 0, editor1, editor2, this);
|
||||
DiffDividerDrawUtil.paintPolygons(gg, divider.getWidth(), rotate == 0, editor1, editor2, this);
|
||||
|
||||
for (DiffChange change : myDiffChanges) {
|
||||
int y1 = editor1.logicalPositionToXY(new LogicalPosition(change.getStartLine(Side.LEFT), 0)).y - shift1;
|
||||
|
||||
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 170 B |
@@ -17,9 +17,13 @@ package com.jetbrains.edu.learning.builtInServer;
|
||||
|
||||
import com.intellij.notification.Notification;
|
||||
import com.intellij.notification.NotificationType;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.ui.AppIcon;
|
||||
import com.jetbrains.edu.learning.StudySettings;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicAuthorizedClient;
|
||||
import com.jetbrains.edu.learning.stepic.EduStepicConnector;
|
||||
@@ -32,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.ide.RestService;
|
||||
import org.jetbrains.io.Responses;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -118,6 +123,8 @@ public class EduStepikRestService extends RestService {
|
||||
StudySettings.getInstance().setUser(stepicUser);
|
||||
sendHtmlResponse(request, context, "/oauthResponsePages/okPage.html");
|
||||
showStepicNotification(NotificationType.INFORMATION, "Authorized as " + stepicUser.getFirstName() + " " + stepicUser.getLastName());
|
||||
JFrame frame = WindowManager.getInstance().findVisibleFrame();
|
||||
ApplicationManager.getApplication().invokeLater(() -> AppIcon.getInstance().requestFocus((IdeFrame)frame));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,5 +3,6 @@
|
||||
The inspection finds commonly used class/interface that could be extended/implemented instead of extending too broad interface or class.
|
||||
<!-- tooltip end -->
|
||||
The inspection works only if a project is built using IntelliJ IDEA build system and a super class is located inside project source files.
|
||||
<p><small>New in 2017.2</small>
|
||||
</body>
|
||||
</html>
|
||||