diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java index f9f0e5e88008..25c3ecaa92d1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspectionBase.java @@ -41,56 +41,52 @@ public class UnusedSymbolLocalInspectionBase extends BaseJavaLocalInspectionTool public boolean PARAMETER = true; public boolean REPORT_PARAMETER_FOR_PUBLIC_METHODS = true; - private String myClassVisibility = PsiModifier.PUBLIC; - private String myFieldVisibility = PsiModifier.PUBLIC; - private String myMethodVisibility = PsiModifier.PUBLIC; - private String myParameterVisibility = PsiModifier.PUBLIC; + protected String myClassVisibility = PsiModifier.PUBLIC; + protected String myFieldVisibility = PsiModifier.PUBLIC; + protected String myMethodVisibility = PsiModifier.PUBLIC; + protected String myParameterVisibility = PsiModifier.PUBLIC; private boolean myIgnoreAccessors = false; @PsiModifier.ModifierConstant @Nullable public String getClassVisibility() { - if (!CLASS || "none".equals(myClassVisibility)) return null; + if (!CLASS) return null; return myClassVisibility; } @PsiModifier.ModifierConstant @Nullable public String getFieldVisibility() { - if (!FIELD || "none".equals(myFieldVisibility)) return null; + if (!FIELD) return null; return myFieldVisibility; } @PsiModifier.ModifierConstant @Nullable public String getMethodVisibility() { - if (!METHOD || "none".equals(myMethodVisibility)) return null; + if (!METHOD) return null; return myMethodVisibility; } @PsiModifier.ModifierConstant @Nullable public String getParameterVisibility() { - if (!PARAMETER || "none".equals(myParameterVisibility)) return null; + if (!PARAMETER) return null; return myParameterVisibility; } public void setClassVisibility(String classVisibility) { - CLASS = !"none".equals(classVisibility); this.myClassVisibility = classVisibility; } public void setFieldVisibility(String fieldVisibility) { - FIELD = !"none".equals(fieldVisibility); this.myFieldVisibility = fieldVisibility; } public void setMethodVisibility(String methodVisibility) { - METHOD = !"none".equals(methodVisibility); this.myMethodVisibility = methodVisibility; } public void setParameterVisibility(String parameterVisibility) { - PARAMETER = !"none".equals(parameterVisibility); REPORT_PARAMETER_FOR_PUBLIC_METHODS = PsiModifier.PUBLIC.equals(parameterVisibility); this.myParameterVisibility = parameterVisibility; } diff --git a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java index 1fba84acfba5..1097996744ff 100644 --- a/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/deadCode/UnusedDeclarationInspection.java @@ -47,7 +47,7 @@ public class UnusedDeclarationInspection extends UnusedDeclarationInspectionBase public JComponent createOptionsPanel() { JTabbedPane tabs = new JBTabbedPane(SwingConstants.TOP); tabs.add("Entry points", new OptionsPanel()); - tabs.add("On the fly editor settings", myLocalInspectionBase.createOptionsPanel()); + tabs.add("Members to report", myLocalInspectionBase.createOptionsPanel()); return tabs; } diff --git a/java/java-impl/src/com/intellij/codeInspection/ex/ConfigureClassPatternsDialog.java b/java/java-impl/src/com/intellij/codeInspection/ex/ConfigureClassPatternsDialog.java index 0499faf6ed0b..2d7ec8304504 100644 --- a/java/java-impl/src/com/intellij/codeInspection/ex/ConfigureClassPatternsDialog.java +++ b/java/java-impl/src/com/intellij/codeInspection/ex/ConfigureClassPatternsDialog.java @@ -75,7 +75,7 @@ class ConfigureClassPatternsDialog extends DialogWrapper { }) .setButtonComparator("Add", "Remove"); JPanel panel = new JPanel(new BorderLayout()); - panel.add(SeparatorFactory.createSeparator("Mark class as reachable if name matches", null), BorderLayout.NORTH); + panel.add(SeparatorFactory.createSeparator("Mark class as entry point if name matches", null), BorderLayout.NORTH); panel.add(toolbarDecorator.createPanel(), BorderLayout.CENTER); return panel; } diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form index a2c503755c3f..e45b01fb595d 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form +++ b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/OptionsPanel.form @@ -1,94 +1,150 @@
- + - + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java index a520a1bd0566..21edf26a42ad 100644 --- a/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java +++ b/java/java-impl/src/com/intellij/codeInspection/unusedSymbol/UnusedSymbolLocalInspection.java @@ -16,14 +16,36 @@ package com.intellij.codeInspection.unusedSymbol; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.ui.popup.JBPopup; +import com.intellij.openapi.ui.popup.JBPopupAdapter; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.LightweightWindowEvent; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiModifier; -import com.intellij.ui.ListCellRendererWrapper; +import com.intellij.ui.ClickListener; +import com.intellij.ui.UI; +import com.intellij.ui.UserActivityProviderComponent; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Consumer; +import com.intellij.util.Producer; import com.intellij.util.VisibilityUtil; +import com.intellij.util.containers.HashSet; +import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseEvent; +import java.util.Hashtable; +import java.util.Set; /** * User: anna @@ -40,49 +62,38 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase public class OptionsPanel { private JCheckBox myCheckLocalVariablesCheckBox; - private JComboBox myCheckClassesCheckBox; - private JComboBox myCheckFieldsCheckBox; - private JComboBox myCheckMethodsCheckBox; - private JComboBox myCheckParametersCheckBox; + private JCheckBox myCheckClassesCheckBox; + private JCheckBox myCheckFieldsCheckBox; + private JCheckBox myCheckMethodsCheckBox; + private JCheckBox myCheckParametersCheckBox; + private JCheckBox myAccessors; private JPanel myPanel; - private JCheckBox myCheckGettersSettersCheckBox; + private JLabel myClassVisibilityCb; + private JLabel myFieldVisibilityCb; + private JLabel myMethodVisibilityCb; + private JLabel myMethodParameterVisibilityCb; public OptionsPanel() { myCheckLocalVariablesCheckBox.setSelected(LOCAL_VARIABLE); - myCheckGettersSettersCheckBox.setSelected(!isIgnoreAccessors()); - String[] visibilities = new String[] {"none", PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PACKAGE_LOCAL, PsiModifier.PRIVATE}; - myCheckClassesCheckBox.setModel(new DefaultComboBoxModel<>(visibilities)); - myCheckFieldsCheckBox.setModel(new DefaultComboBoxModel<>(visibilities)); - myCheckMethodsCheckBox.setModel(new DefaultComboBoxModel<>(visibilities)); - myCheckParametersCheckBox.setModel(new DefaultComboBoxModel<>(visibilities)); + myCheckClassesCheckBox.setSelected(CLASS); + myCheckFieldsCheckBox.setSelected(FIELD); + myCheckMethodsCheckBox.setSelected(METHOD); - final ListCellRendererWrapper renderer = new ListCellRendererWrapper() { - @Override - public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) { - if (value != null && !"none".equals(value)) { - setText(VisibilityUtil.toPresentableText(value)); - } - } - }; - myCheckClassesCheckBox.setRenderer(renderer); - myCheckMethodsCheckBox.setRenderer(renderer); - myCheckFieldsCheckBox.setRenderer(renderer); - myCheckParametersCheckBox.setRenderer(renderer); - - myCheckClassesCheckBox.setSelectedItem(getClassVisibility()); - myCheckFieldsCheckBox.setSelectedItem(getFieldVisibility()); - myCheckMethodsCheckBox.setSelectedItem(getMethodVisibility()); - myCheckParametersCheckBox.setSelectedItem(getParameterVisibility()); + myCheckParametersCheckBox.setSelected(PARAMETER); + myAccessors.setSelected(isIgnoreAccessors()); + myAccessors.setEnabled(PARAMETER); final ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { LOCAL_VARIABLE = myCheckLocalVariablesCheckBox.isSelected(); - setIgnoreAccessors(!myCheckGettersSettersCheckBox.isSelected()); - setClassVisibility((String)myCheckClassesCheckBox.getSelectedItem()); - setFieldVisibility((String)myCheckFieldsCheckBox.getSelectedItem()); - setMethodVisibility((String)myCheckMethodsCheckBox.getSelectedItem()); - setParameterVisibility((String)myCheckParametersCheckBox.getSelectedItem()); + CLASS = myCheckClassesCheckBox.isSelected(); + FIELD = myCheckFieldsCheckBox.isSelected(); + METHOD = myCheckMethodsCheckBox.isSelected(); + PARAMETER = myCheckParametersCheckBox.isSelected(); + + myAccessors.setEnabled(METHOD); + setIgnoreAccessors(!myAccessors.isSelected()); } }; myCheckLocalVariablesCheckBox.addActionListener(listener); @@ -90,12 +101,99 @@ public class UnusedSymbolLocalInspection extends UnusedSymbolLocalInspectionBase myCheckMethodsCheckBox.addActionListener(listener); myCheckClassesCheckBox.addActionListener(listener); myCheckParametersCheckBox.addActionListener(listener); - myCheckGettersSettersCheckBox.addActionListener(listener); + myAccessors.addActionListener(listener); + + ((MyLabel)myClassVisibilityCb).setupVisibilityLabel(() -> myClassVisibility, modifier -> setClassVisibility(modifier)); + ((MyLabel)myFieldVisibilityCb).setupVisibilityLabel( () -> myFieldVisibility, modifier -> setFieldVisibility(modifier)); + ((MyLabel)myMethodVisibilityCb).setupVisibilityLabel(() -> myMethodVisibility, modifier -> setMethodVisibility(modifier)); + ((MyLabel)myMethodParameterVisibilityCb).setupVisibilityLabel(() -> myParameterVisibility, modifier -> setParameterVisibility(modifier)); } public JComponent getPanel() { return myPanel; } + + private void createUIComponents() { + myClassVisibilityCb = new MyLabel(); + myFieldVisibilityCb = new MyLabel(); + myMethodVisibilityCb = new MyLabel(); + myMethodParameterVisibilityCb = new MyLabel(); + } + } + + private static class MyLabel extends JLabel implements UserActivityProviderComponent { + + @PsiModifier.ModifierConstant private static final String[] MODIFIERS = + new String[]{PsiModifier.PUBLIC, PsiModifier.PROTECTED, PsiModifier.PACKAGE_LOCAL, PsiModifier.PRIVATE}; + + private Set myListeners = new HashSet<>(); + + public MyLabel() { + setIcon(AllIcons.General.Combo2); + setHorizontalTextPosition(SwingConstants.LEFT); + } + + private void fireStateChanged() { + for (ChangeListener listener : myListeners) { + listener.stateChanged(new ChangeEvent(this)); + } + } + + private static String getPresentableText(String modifier) { + return StringUtil.capitalize(VisibilityUtil.toPresentableText(modifier)); + } + + private void setupVisibilityLabel(Producer visibilityProducer, Consumer setter) { + setText(getPresentableText(visibilityProducer.produce())); + new ClickListener() { + @Override + public boolean onClick(@NotNull MouseEvent e, int clickCount) { + @SuppressWarnings("UseOfObsoleteCollectionType") + Hashtable sliderLabels = new Hashtable<>(); + for (int i = 0; i < MODIFIERS.length; i++) { + sliderLabels.put(i + 1, new JLabel(getPresentableText(MODIFIERS[i]))); + } + + JSlider slider = new JSlider(SwingConstants.VERTICAL, 1, MODIFIERS.length, 1); + slider.setLabelTable(sliderLabels); + slider.putClientProperty(UIUtil.JSLIDER_ISFILLED, Boolean.TRUE); + slider.setPreferredSize(JBUI.size(150, 100)); + slider.setPaintLabels(true); + slider.setSnapToTicks(true); + slider.setValue(ArrayUtil.find(MODIFIERS, visibilityProducer.produce()) + 1); + final JBPopup popup = JBPopupFactory.getInstance() + .createComponentPopupBuilder(slider, null) + .setCancelOnClickOutside(true) + .createPopup(); + popup.addListener(new JBPopupAdapter() { + @Override + public void onClosed(LightweightWindowEvent event) { + final String modifier = MODIFIERS[slider.getValue() - 1]; + setter.consume(modifier); + setText(getPresentableText(modifier)); + fireStateChanged(); + } + }); + popup.show(new RelativePoint(MyLabel.this, new Point(getWidth(), 0))); + return true; + } + }.installOn(this); + } + + @Override + public void setForeground(Color fg) { + super.setForeground(isEnabled() ? UI.getColor("link.foreground") : fg); + } + + @Override + public void addChangeListener(ChangeListener changeListener) { + myListeners.add(changeListener); + } + + @Override + public void removeChangeListener(ChangeListener changeListener) { + myListeners.remove(changeListener); + } } @Override diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index d7b03a58a3c8..3af216a3db8a 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -314,12 +314,12 @@ inspection.javadoc.html.not.required.label.text=Additional Not Required Html Att inspection.javadoc.html.not.required.dialog.title=Edit Additional Not Required Html Attributes inspection.required.attributes.display.name=Missing required attribute -inspection.unused.symbol.check.localvars=Check &Local Variables -inspection.unused.symbol.check.fields=Check &Fields: -inspection.unused.symbol.check.methods=Check &Methods: -inspection.unused.symbol.check.accessors=Check &Getters/Setters: -inspection.unused.symbol.check.classes=Check &Classes: -inspection.unused.symbol.check.parameters=Check &Parameters in Methods: +inspection.unused.symbol.check.localvars=&Local variables (Editor only) +inspection.unused.symbol.check.fields=&Fields: +inspection.unused.symbol.check.methods=&Methods: +inspection.unused.symbol.check.accessors=&Getters/setters +inspection.unused.symbol.check.classes=&Classes: +inspection.unused.symbol.check.parameters=Method ¶meters: inspection.results.for.profile.toolwindow.title=''{0}'' Profile on {1} inspection.results.for.inspection.toolwindow.title=''{0}'' Inspection on {1}