2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.refactoring
.inheritanceToDelegation
;
18 import com
.intellij
.openapi
.help
.HelpManager
;
19 import com
.intellij
.openapi
.options
.ConfigurationException
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.openapi
.util
.text
.StringUtil
;
22 import com
.intellij
.psi
.*;
23 import com
.intellij
.psi
.codeStyle
.JavaCodeStyleManager
;
24 import com
.intellij
.psi
.codeStyle
.SuggestedNameInfo
;
25 import com
.intellij
.psi
.codeStyle
.VariableKind
;
26 import com
.intellij
.refactoring
.HelpID
;
27 import com
.intellij
.refactoring
.JavaRefactoringSettings
;
28 import com
.intellij
.refactoring
.RefactoringBundle
;
29 import com
.intellij
.refactoring
.classMembers
.MemberInfoChange
;
30 import com
.intellij
.refactoring
.classMembers
.MemberInfoModel
;
31 import com
.intellij
.refactoring
.ui
.ClassCellRenderer
;
32 import com
.intellij
.refactoring
.ui
.MemberSelectionPanel
;
33 import com
.intellij
.refactoring
.ui
.NameSuggestionsField
;
34 import com
.intellij
.refactoring
.ui
.RefactoringDialog
;
35 import com
.intellij
.refactoring
.util
.classMembers
.InterfaceMemberDependencyGraph
;
36 import com
.intellij
.refactoring
.util
.classMembers
.MemberInfo
;
37 import com
.intellij
.util
.containers
.HashMap
;
38 import org
.jetbrains
.annotations
.NonNls
;
39 import org
.jetbrains
.annotations
.NotNull
;
43 import java
.awt
.event
.ItemEvent
;
44 import java
.awt
.event
.ItemListener
;
45 import java
.util
.ArrayList
;
46 import java
.util
.Collection
;
47 import java
.util
.Collections
;
49 public class InheritanceToDelegationDialog
extends RefactoringDialog
{
50 private final PsiClass
[] mySuperClasses
;
52 private final PsiClass myClass
;
53 private final HashMap
<PsiClass
, Collection
<MemberInfo
>> myBasesToMemberInfos
;
55 private NameSuggestionsField myFieldNameField
;
56 private NameSuggestionsField myInnerClassNameField
;
57 private JCheckBox myCbGenerateGetter
;
58 private MemberSelectionPanel myMemberSelectionPanel
;
59 private JComboBox myClassCombo
;
60 private final Project myProject
;
61 private MyClassComboItemListener myClassComboItemListener
;
62 private NameSuggestionsField
.DataChanged myDataChangedListener
;
64 public InheritanceToDelegationDialog(Project project
,
66 PsiClass
[] superClasses
,
67 HashMap
<PsiClass
,Collection
<MemberInfo
>> basesToMemberInfos
) {
71 mySuperClasses
= superClasses
;
72 myBasesToMemberInfos
= basesToMemberInfos
;
74 setTitle(InheritanceToDelegationHandler
.REFACTORING_NAME
);
79 public JComponent
getPreferredFocusedComponent() {
80 return myFieldNameField
;
83 protected void dispose() {
84 myInnerClassNameField
.removeDataChangedListener(myDataChangedListener
);
85 myFieldNameField
.removeDataChangedListener(myDataChangedListener
);
86 myClassCombo
.removeItemListener(myClassComboItemListener
);
91 public String
getFieldName() {
92 return myFieldNameField
.getEnteredName();
95 public String
getInnerClassName() {
96 if (myInnerClassNameField
!= null) {
97 return myInnerClassNameField
.getEnteredName();
104 public boolean isGenerateGetter() {
105 return myCbGenerateGetter
.isSelected();
109 protected void canRun() throws ConfigurationException
{
110 final String fieldName
= getFieldName();
111 final PsiNameHelper helper
= JavaPsiFacade
.getInstance(myProject
).getNameHelper();
112 if (!helper
.isIdentifier(fieldName
)){
113 throw new ConfigurationException("\'" + StringUtil
.first(fieldName
, 10, true) + "\' is invalid field name for delegation");
115 if (myInnerClassNameField
!= null) {
116 final String className
= myInnerClassNameField
.getEnteredName();
117 if (!helper
.isIdentifier(className
)) {
118 throw new ConfigurationException("\'" + StringUtil
.first(className
, 10, true) + "\' is invalid inner class name");
123 public Collection
<MemberInfo
> getSelectedMemberInfos() {
124 return myMemberSelectionPanel
.getTable().getSelectedMemberInfos();
127 public PsiClass
getSelectedTargetClass() {
128 return (PsiClass
)myClassCombo
.getSelectedItem();
132 protected void doHelpAction() {
133 HelpManager
.getInstance().invokeHelp(HelpID
.INHERITANCE_TO_DELEGATION
);
136 protected void doAction() {
137 JavaRefactoringSettings
.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER
= myCbGenerateGetter
.isSelected();
139 final Collection
<MemberInfo
> selectedMemberInfos
= getSelectedMemberInfos();
140 final ArrayList
<PsiClass
> implementedInterfaces
= new ArrayList
<PsiClass
>();
141 final ArrayList
<PsiMethod
> delegatedMethods
= new ArrayList
<PsiMethod
>();
143 for (MemberInfo memberInfo
: selectedMemberInfos
) {
144 final PsiElement member
= memberInfo
.getMember();
145 if (member
instanceof PsiClass
&& Boolean
.FALSE
.equals(memberInfo
.getOverrides())) {
146 implementedInterfaces
.add((PsiClass
)member
);
148 else if (member
instanceof PsiMethod
) {
149 delegatedMethods
.add((PsiMethod
)member
);
152 invokeRefactoring(new InheritanceToDelegationProcessor(myProject
, myClass
,
153 getSelectedTargetClass(), getFieldName(),
155 implementedInterfaces
.toArray(new PsiClass
[implementedInterfaces
.size()]),
156 delegatedMethods
.toArray(new PsiMethod
[delegatedMethods
.size()]),
157 isGenerateGetter(), isGenerateGetter()));
160 protected JComponent
createNorthPanel() {
161 JPanel panel
= new JPanel(new GridBagLayout());
162 GridBagConstraints gbc
= new GridBagConstraints();
164 gbc
.fill
= GridBagConstraints
.BOTH
;
165 gbc
.anchor
= GridBagConstraints
.WEST
;
170 gbc
.insets
= new Insets(4, 8, 0, 8);
171 myClassCombo
= new JComboBox(mySuperClasses
);
172 myClassCombo
.setRenderer(new ClassCellRenderer());
174 final JLabel classComboLabel
= new JLabel();
175 panel
.add(classComboLabel
, gbc
);
177 panel
.add(myClassCombo
, gbc
);
178 classComboLabel
.setText(RefactoringBundle
.message("replace.inheritance.from"));
180 myClassComboItemListener
= new MyClassComboItemListener();
181 myClassCombo
.addItemListener(myClassComboItemListener
);
185 gbc
.insets
= new Insets(4, 8, 4, 0);
186 final JLabel fieldNameLabel
= new JLabel();
187 panel
.add(fieldNameLabel
, gbc
);
189 myFieldNameField
= new NameSuggestionsField(myProject
);
191 gbc
.gridwidth
= GridBagConstraints
.REMAINDER
;
192 gbc
.insets
= new Insets(4, 4, 4, 8);
194 panel
.add(myFieldNameField
.getComponent(), gbc
);
195 fieldNameLabel
.setText(RefactoringBundle
.message("field.name"));
197 // if(InheritanceToDelegationUtil.isInnerClassNeeded(myClass, mySuperClass)) {
201 gbc
.insets
= new Insets(4, 8, 4, 0);
203 final JLabel innerClassNameLabel
= new JLabel();
204 panel
.add(innerClassNameLabel
, gbc
);
206 /*String[] suggestions = new String[mySuperClasses.length];
207 for (int i = 0; i < suggestions.length; i++) {
208 suggestions[i] = "My" + mySuperClasses[i].getName();
210 myInnerClassNameField
= new NameSuggestionsField(myProject
);
212 gbc
.gridwidth
= GridBagConstraints
.REMAINDER
;
213 gbc
.insets
= new Insets(4, 4, 4, 8);
215 panel
.add(myInnerClassNameField
.getComponent(), gbc
);
216 innerClassNameLabel
.setText(RefactoringBundle
.message("inner.class.name"));
222 protected JComponent
createCenterPanel() {
223 JPanel panel
= new JPanel(new GridBagLayout());
224 GridBagConstraints gbc
= new GridBagConstraints();
226 gbc
.fill
= GridBagConstraints
.BOTH
;
227 gbc
.anchor
= GridBagConstraints
.WEST
;
234 gbc
.insets
= new Insets(4, 8, 4, 4);
236 myMemberSelectionPanel
= new MemberSelectionPanel(RefactoringBundle
.message("delegate.members"), Collections
.<MemberInfo
>emptyList(), null);
237 panel
.add(myMemberSelectionPanel
, gbc
);
238 MyMemberInfoModel memberInfoModel
= new InheritanceToDelegationDialog
.MyMemberInfoModel();
239 myMemberSelectionPanel
.getTable().setMemberInfoModel(memberInfoModel
);
240 myMemberSelectionPanel
.getTable().addMemberInfoChangeListener(memberInfoModel
);
244 gbc
.insets
= new Insets(4, 8, 0, 8);
246 myCbGenerateGetter
= new JCheckBox(RefactoringBundle
.message("generate.getter.for.delegated.component"));
247 myCbGenerateGetter
.setFocusable(false);
248 panel
.add(myCbGenerateGetter
, gbc
);
249 myCbGenerateGetter
.setSelected(JavaRefactoringSettings
.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER
);
255 private void updateTargetClass() {
256 final PsiClass targetClass
= getSelectedTargetClass();
257 PsiManager psiManager
= myClass
.getManager();
258 PsiType superType
= JavaPsiFacade
.getInstance(psiManager
.getProject()).getElementFactory().createType(targetClass
);
259 SuggestedNameInfo suggestedNameInfo
=
260 JavaCodeStyleManager
.getInstance(psiManager
.getProject()).suggestVariableName(VariableKind
.FIELD
, null, null, superType
);
261 myFieldNameField
.setSuggestions(suggestedNameInfo
.names
);
262 myInnerClassNameField
.getComponent().setEnabled(InheritanceToDelegationUtil
.isInnerClassNeeded(myClass
, targetClass
));
263 @NonNls final String suggestion
= "My" + targetClass
.getName();
264 myInnerClassNameField
.setSuggestions(new String
[]{suggestion
});
266 myDataChangedListener
= new NameSuggestionsField
.DataChanged() {
267 public void dataChanged() {
271 myInnerClassNameField
.addDataChangedListener(myDataChangedListener
);
272 myFieldNameField
.addDataChangedListener(myDataChangedListener
);
274 myMemberSelectionPanel
.getTable().setMemberInfos(myBasesToMemberInfos
.get(targetClass
));
275 myMemberSelectionPanel
.getTable().fireExternalDataChange();
278 private class MyMemberInfoModel
implements MemberInfoModel
<PsiMember
, MemberInfo
> {
279 final HashMap
<PsiClass
,InterfaceMemberDependencyGraph
> myGraphs
;
281 public MyMemberInfoModel() {
282 myGraphs
= new HashMap
<PsiClass
, InterfaceMemberDependencyGraph
>();
283 for (PsiClass superClass
: mySuperClasses
) {
284 myGraphs
.put(superClass
, new InterfaceMemberDependencyGraph(superClass
));
288 public boolean isMemberEnabled(MemberInfo memberInfo
) {
289 if (getGraph().getDependent().contains(memberInfo
.getMember())) {
297 public boolean isCheckedWhenDisabled(MemberInfo member
) {
301 public boolean isAbstractEnabled(MemberInfo member
) {
305 public boolean isAbstractWhenDisabled(MemberInfo member
) {
309 public Boolean
isFixedAbstract(MemberInfo member
) {
313 public int checkForProblems(@NotNull MemberInfo member
) {
317 public String
getTooltipText(MemberInfo member
) {
321 public void memberInfoChanged(MemberInfoChange
<PsiMember
, MemberInfo
> event
) {
322 final Collection
<MemberInfo
> changedMembers
= event
.getChangedMembers();
324 for (MemberInfo changedMember
: changedMembers
) {
325 getGraph().memberChanged(changedMember
);
329 private InterfaceMemberDependencyGraph
getGraph() {
330 return myGraphs
.get(getSelectedTargetClass());
334 private class MyClassComboItemListener
implements ItemListener
{
335 public void itemStateChanged(ItemEvent e
) {
336 if (e
.getStateChange() == ItemEvent
.SELECTED
) {