class members refactoring refactoring
[fedora-idea.git] / refactoring / impl / com / intellij / refactoring / inheritanceToDelegation / InheritanceToDelegationDialog.java
blob0ee76d7083b8c11236889c54902b0e8e8bcb7488
1 package com.intellij.refactoring.inheritanceToDelegation;
3 import com.intellij.openapi.help.HelpManager;
4 import com.intellij.openapi.options.ConfigurationException;
5 import com.intellij.openapi.project.Project;
6 import com.intellij.openapi.util.text.StringUtil;
7 import com.intellij.psi.*;
8 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
9 import com.intellij.psi.codeStyle.SuggestedNameInfo;
10 import com.intellij.psi.codeStyle.VariableKind;
11 import com.intellij.refactoring.HelpID;
12 import com.intellij.refactoring.JavaRefactoringSettings;
13 import com.intellij.refactoring.RefactoringBundle;
14 import com.intellij.refactoring.classMembers.MemberInfoChange;
15 import com.intellij.refactoring.classMembers.MemberInfoModel;
16 import com.intellij.refactoring.ui.ClassCellRenderer;
17 import com.intellij.refactoring.ui.MemberSelectionPanel;
18 import com.intellij.refactoring.ui.NameSuggestionsField;
19 import com.intellij.refactoring.ui.RefactoringDialog;
20 import com.intellij.refactoring.util.classMembers.InterfaceMemberDependencyGraph;
21 import com.intellij.refactoring.util.classMembers.MemberInfo;
22 import com.intellij.util.containers.HashMap;
23 import org.jetbrains.annotations.NonNls;
24 import org.jetbrains.annotations.NotNull;
26 import javax.swing.*;
27 import java.awt.*;
28 import java.awt.event.ItemEvent;
29 import java.awt.event.ItemListener;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.Collections;
34 public class InheritanceToDelegationDialog extends RefactoringDialog {
35 private final PsiClass[] mySuperClasses;
37 private final PsiClass myClass;
38 private final HashMap<PsiClass, Collection<MemberInfo>> myBasesToMemberInfos;
40 private NameSuggestionsField myFieldNameField;
41 private NameSuggestionsField myInnerClassNameField;
42 private JCheckBox myCbGenerateGetter;
43 private MemberSelectionPanel myMemberSelectionPanel;
44 private JComboBox myClassCombo;
45 private final Project myProject;
46 private MyClassComboItemListener myClassComboItemListener;
47 private NameSuggestionsField.DataChanged myDataChangedListener;
49 public InheritanceToDelegationDialog(Project project,
50 PsiClass aClass,
51 PsiClass[] superClasses,
52 HashMap<PsiClass,Collection<MemberInfo>> basesToMemberInfos) {
53 super(project, true);
54 myProject = project;
55 myClass = aClass;
56 mySuperClasses = superClasses;
57 myBasesToMemberInfos = basesToMemberInfos;
59 setTitle(InheritanceToDelegationHandler.REFACTORING_NAME);
60 init();
63 @Override
64 public JComponent getPreferredFocusedComponent() {
65 return myFieldNameField;
68 protected void dispose() {
69 myInnerClassNameField.removeDataChangedListener(myDataChangedListener);
70 myFieldNameField.removeDataChangedListener(myDataChangedListener);
71 myClassCombo.removeItemListener(myClassComboItemListener);
72 super.dispose();
75 @NotNull
76 public String getFieldName() {
77 return myFieldNameField.getEnteredName();
80 public String getInnerClassName() {
81 if (myInnerClassNameField != null) {
82 return myInnerClassNameField.getEnteredName();
84 else {
85 return null;
89 public boolean isGenerateGetter() {
90 return myCbGenerateGetter.isSelected();
93 @Override
94 protected void canRun() throws ConfigurationException {
95 final String fieldName = getFieldName();
96 final PsiNameHelper helper = JavaPsiFacade.getInstance(myProject).getNameHelper();
97 if (!helper.isIdentifier(fieldName)){
98 throw new ConfigurationException("\'" + StringUtil.first(fieldName, 10, true) + "\' is invalid field name for delegation");
100 if (myInnerClassNameField != null) {
101 final String className = myInnerClassNameField.getEnteredName();
102 if (!helper.isIdentifier(className)) {
103 throw new ConfigurationException("\'" + StringUtil.first(className, 10, true) + "\' is invalid inner class name");
108 public Collection<MemberInfo> getSelectedMemberInfos() {
109 return myMemberSelectionPanel.getTable().getSelectedMemberInfos();
112 public PsiClass getSelectedTargetClass() {
113 return (PsiClass)myClassCombo.getSelectedItem();
117 protected void doHelpAction() {
118 HelpManager.getInstance().invokeHelp(HelpID.INHERITANCE_TO_DELEGATION);
121 protected void doAction() {
122 JavaRefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER = myCbGenerateGetter.isSelected();
124 final Collection<MemberInfo> selectedMemberInfos = getSelectedMemberInfos();
125 final ArrayList<PsiClass> implementedInterfaces = new ArrayList<PsiClass>();
126 final ArrayList<PsiMethod> delegatedMethods = new ArrayList<PsiMethod>();
128 for (MemberInfo memberInfo : selectedMemberInfos) {
129 final PsiElement member = memberInfo.getMember();
130 if (member instanceof PsiClass && Boolean.FALSE.equals(memberInfo.getOverrides())) {
131 implementedInterfaces.add((PsiClass)member);
133 else if (member instanceof PsiMethod) {
134 delegatedMethods.add((PsiMethod)member);
137 invokeRefactoring(new InheritanceToDelegationProcessor(myProject, myClass,
138 getSelectedTargetClass(), getFieldName(),
139 getInnerClassName(),
140 implementedInterfaces.toArray(new PsiClass[implementedInterfaces.size()]),
141 delegatedMethods.toArray(new PsiMethod[delegatedMethods.size()]),
142 isGenerateGetter(), isGenerateGetter()));
145 protected JComponent createNorthPanel() {
146 JPanel panel = new JPanel(new GridBagLayout());
147 GridBagConstraints gbc = new GridBagConstraints();
149 gbc.fill = GridBagConstraints.BOTH;
150 gbc.anchor = GridBagConstraints.WEST;
151 gbc.gridy = 0;
152 gbc.gridx = 0;
155 gbc.insets = new Insets(4, 8, 0, 8);
156 myClassCombo = new JComboBox(mySuperClasses);
157 myClassCombo.setRenderer(new ClassCellRenderer());
158 gbc.gridwidth = 2;
159 final JLabel classComboLabel = new JLabel();
160 panel.add(classComboLabel, gbc);
161 gbc.gridy++;
162 panel.add(myClassCombo, gbc);
163 classComboLabel.setText(RefactoringBundle.message("replace.inheritance.from"));
165 myClassComboItemListener = new MyClassComboItemListener();
166 myClassCombo.addItemListener(myClassComboItemListener);
168 gbc.gridy++;
169 gbc.gridwidth = 1;
170 gbc.insets = new Insets(4, 8, 4, 0);
171 final JLabel fieldNameLabel = new JLabel();
172 panel.add(fieldNameLabel, gbc);
174 myFieldNameField = new NameSuggestionsField(myProject);
175 gbc.gridx++;
176 gbc.gridwidth = GridBagConstraints.REMAINDER;
177 gbc.insets = new Insets(4, 4, 4, 8);
178 gbc.weightx = 1.0;
179 panel.add(myFieldNameField.getComponent(), gbc);
180 fieldNameLabel.setText(RefactoringBundle.message("field.name"));
182 // if(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, mySuperClass)) {
183 gbc.gridx = 0;
184 gbc.gridy++;
185 gbc.gridwidth = 1;
186 gbc.insets = new Insets(4, 8, 4, 0);
187 gbc.weightx = 0.0;
188 final JLabel innerClassNameLabel = new JLabel();
189 panel.add(innerClassNameLabel, gbc);
191 /*String[] suggestions = new String[mySuperClasses.length];
192 for (int i = 0; i < suggestions.length; i++) {
193 suggestions[i] = "My" + mySuperClasses[i].getName();
195 myInnerClassNameField = new NameSuggestionsField(myProject);
196 gbc.gridx++;
197 gbc.gridwidth = GridBagConstraints.REMAINDER;
198 gbc.insets = new Insets(4, 4, 4, 8);
199 gbc.weightx = 1.0;
200 panel.add(myInnerClassNameField.getComponent(), gbc);
201 innerClassNameLabel.setText(RefactoringBundle.message("inner.class.name"));
203 return panel;
207 protected JComponent createCenterPanel() {
208 JPanel panel = new JPanel(new GridBagLayout());
209 GridBagConstraints gbc = new GridBagConstraints();
211 gbc.fill = GridBagConstraints.BOTH;
212 gbc.anchor = GridBagConstraints.WEST;
213 gbc.gridy = 0;
214 gbc.gridx = 0;
215 gbc.weightx = 1.0;
217 gbc.weighty = 1.0;
218 gbc.gridwidth = 1;
219 gbc.insets = new Insets(4, 8, 4, 4);
221 myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("delegate.members"), Collections.<MemberInfo>emptyList(), null);
222 panel.add(myMemberSelectionPanel, gbc);
223 MyMemberInfoModel memberInfoModel = new InheritanceToDelegationDialog.MyMemberInfoModel();
224 myMemberSelectionPanel.getTable().setMemberInfoModel(memberInfoModel);
225 myMemberSelectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel);
228 gbc.gridy++;
229 gbc.insets = new Insets(4, 8, 0, 8);
230 gbc.weighty = 0.0;
231 myCbGenerateGetter = new JCheckBox(RefactoringBundle.message("generate.getter.for.delegated.component"));
232 myCbGenerateGetter.setFocusable(false);
233 panel.add(myCbGenerateGetter, gbc);
234 myCbGenerateGetter.setSelected(JavaRefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER);
235 updateTargetClass();
237 return panel;
240 private void updateTargetClass() {
241 final PsiClass targetClass = getSelectedTargetClass();
242 PsiManager psiManager = myClass.getManager();
243 PsiType superType = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory().createType(targetClass);
244 SuggestedNameInfo suggestedNameInfo =
245 JavaCodeStyleManager.getInstance(psiManager.getProject()).suggestVariableName(VariableKind.FIELD, null, null, superType);
246 myFieldNameField.setSuggestions(suggestedNameInfo.names);
247 myInnerClassNameField.getComponent().setEnabled(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, targetClass));
248 @NonNls final String suggestion = "My" + targetClass.getName();
249 myInnerClassNameField.setSuggestions(new String[]{suggestion});
251 myDataChangedListener = new NameSuggestionsField.DataChanged() {
252 public void dataChanged() {
253 validateButtons();
256 myInnerClassNameField.addDataChangedListener(myDataChangedListener);
257 myFieldNameField.addDataChangedListener(myDataChangedListener);
259 myMemberSelectionPanel.getTable().setMemberInfos(myBasesToMemberInfos.get(targetClass));
260 myMemberSelectionPanel.getTable().fireExternalDataChange();
263 private class MyMemberInfoModel implements MemberInfoModel<PsiMember, MemberInfo> {
264 final HashMap<PsiClass,InterfaceMemberDependencyGraph> myGraphs;
266 public MyMemberInfoModel() {
267 myGraphs = new HashMap<PsiClass, InterfaceMemberDependencyGraph>();
268 for (PsiClass superClass : mySuperClasses) {
269 myGraphs.put(superClass, new InterfaceMemberDependencyGraph(superClass));
273 public boolean isMemberEnabled(MemberInfo memberInfo) {
274 if (getGraph().getDependent().contains(memberInfo.getMember())) {
275 return false;
277 else {
278 return true;
282 public boolean isCheckedWhenDisabled(MemberInfo member) {
283 return true;
286 public boolean isAbstractEnabled(MemberInfo member) {
287 return false;
290 public boolean isAbstractWhenDisabled(MemberInfo member) {
291 return false;
294 public Boolean isFixedAbstract(MemberInfo member) {
295 return null;
298 public int checkForProblems(@NotNull MemberInfo member) {
299 return OK;
302 public String getTooltipText(MemberInfo member) {
303 return null;
306 public void memberInfoChanged(MemberInfoChange<PsiMember, MemberInfo> event) {
307 final Collection<MemberInfo> changedMembers = event.getChangedMembers();
309 for (MemberInfo changedMember : changedMembers) {
310 getGraph().memberChanged(changedMember);
314 private InterfaceMemberDependencyGraph getGraph() {
315 return myGraphs.get(getSelectedTargetClass());
319 private class MyClassComboItemListener implements ItemListener {
320 public void itemStateChanged(ItemEvent e) {
321 if (e.getStateChange() == ItemEvent.SELECTED) {
322 updateTargetClass();