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
.changeClassSignature
;
18 import com
.intellij
.openapi
.diagnostic
.Logger
;
19 import com
.intellij
.openapi
.help
.HelpManager
;
20 import com
.intellij
.openapi
.project
.Project
;
21 import com
.intellij
.psi
.*;
22 import com
.intellij
.refactoring
.HelpID
;
23 import com
.intellij
.refactoring
.RefactoringBundle
;
24 import com
.intellij
.refactoring
.ui
.CodeFragmentTableCellEditor
;
25 import com
.intellij
.refactoring
.ui
.CodeFragmentTableCellRenderer
;
26 import com
.intellij
.refactoring
.ui
.RefactoringDialog
;
27 import com
.intellij
.refactoring
.ui
.StringTableCellEditor
;
28 import com
.intellij
.refactoring
.util
.CommonRefactoringUtil
;
29 import com
.intellij
.ui
.*;
30 import com
.intellij
.usageView
.UsageViewUtil
;
31 import com
.intellij
.util
.containers
.ContainerUtil
;
32 import com
.intellij
.util
.ui
.Table
;
35 import javax
.swing
.table
.AbstractTableModel
;
36 import javax
.swing
.table
.TableColumn
;
38 import java
.util
.ArrayList
;
39 import java
.util
.List
;
44 public class ChangeClassSignatureDialog
extends RefactoringDialog
{
45 private static final Logger LOG
= Logger
.getInstance("#com.intellij.refactoring.changeClassSignature.ChangeClassSignatureDialog");
46 private static final int NAME_COLUMN
= 0;
47 private static final int VALUE_COLUMN
= 1;
49 private final List
<TypeParameterInfo
> myTypeParameterInfos
;
50 private final List
<PsiTypeCodeFragment
> myTypeCodeFragments
;
51 private final PsiClass myClass
;
52 private final PsiTypeParameter
[] myOriginalParameters
;
53 private final PsiManager myManager
;
54 private final MyTableModel myTableModel
;
55 private Table myTable
;
56 static final String REFACTORING_NAME
= RefactoringBundle
.message("changeClassSignature.refactoring.name");
58 public ChangeClassSignatureDialog(PsiClass aClass
) {
59 super(aClass
.getProject(), true);
60 setTitle(REFACTORING_NAME
);
62 myManager
= myClass
.getManager();
63 myTypeParameterInfos
= new ArrayList
<TypeParameterInfo
>();
64 myTypeCodeFragments
= new ArrayList
<PsiTypeCodeFragment
>();
65 myOriginalParameters
= myClass
.getTypeParameters();
66 for (int i
= 0; i
< myOriginalParameters
.length
; i
++) {
67 myTypeParameterInfos
.add(new TypeParameterInfo(i
));
68 myTypeCodeFragments
.add(null);
70 myTableModel
= new MyTableModel();
74 private PsiTypeCodeFragment
createValueCodeFragment() {
75 return JavaPsiFacade
.getInstance(myManager
.getProject()).getElementFactory().createTypeCodeFragment(
82 protected JComponent
createNorthPanel() {
83 Box box
= Box
.createHorizontalBox();
84 JLabel label
= new JLabel(RefactoringBundle
.message("changeClassSignature.class.label.text", UsageViewUtil
.getDescriptiveName(myClass
)));
86 box
.add(Box
.createHorizontalGlue());
90 protected void doHelpAction() {
91 HelpManager
.getInstance().invokeHelp(HelpID
.CHANGE_CLASS_SIGNATURE
);
94 protected JComponent
createCenterPanel() {
95 myTable
= new Table(myTableModel
);
96 TableColumn nameColumn
= myTable
.getColumnModel().getColumn(NAME_COLUMN
);
97 TableColumn valueColumn
= myTable
.getColumnModel().getColumn(VALUE_COLUMN
);
98 Project project
= myClass
.getProject();
99 nameColumn
.setCellRenderer(new MyCellRenderer());
100 nameColumn
.setCellEditor(new StringTableCellEditor(project
));
101 valueColumn
.setCellRenderer(new MyCodeFragmentTableCellRenderer());
102 valueColumn
.setCellEditor(new CodeFragmentTableCellEditor(project
));
104 myTable
.setPreferredScrollableViewportSize(new Dimension(210, myTable
.getRowHeight() * 4));
105 myTable
.getSelectionModel().setSelectionMode(ListSelectionModel
.SINGLE_SELECTION
);
106 myTable
.getSelectionModel().setSelectionInterval(0, 0);
107 myTable
.setSurrendersFocusOnKeystroke(true);
108 myTable
.setFocusCycleRoot(true);
111 JPanel panel
= new JPanel(new BorderLayout());
112 panel
.setBorder(IdeBorderFactory
.createTitledBorder(RefactoringBundle
.message("changeClassSignature.parameters.panel.border.title")));
113 JScrollPane scrollPane
= ScrollPaneFactory
.createScrollPane(myTable
);
115 panel
.add(scrollPane
, BorderLayout
.CENTER
);
116 final JPanel buttonsTable
= EditableRowTable
.createButtonsTable(myTable
, myTableModel
, true);
117 panel
.add(buttonsTable
, BorderLayout
.EAST
);
121 protected void doAction() {
122 TableUtil
.stopEditing(myTable
);
123 String message
= validateAndCommitData();
124 if (message
!= null) {
125 CommonRefactoringUtil
.showErrorMessage(RefactoringBundle
.message("error.incorrect.data"), message
, HelpID
.CHANGE_SIGNATURE
, myClass
.getProject());
128 ChangeClassSignatureProcessor processor
=
129 new ChangeClassSignatureProcessor(myClass
.getProject(), myClass
,
130 myTypeParameterInfos
.toArray(new TypeParameterInfo
[myTypeParameterInfos
.size()]));
131 invokeRefactoring(processor
);
134 private String
validateAndCommitData() {
135 for (final TypeParameterInfo info
: myTypeParameterInfos
) {
136 if (!info
.isForExistingParameter() && !JavaPsiFacade
.getInstance(myClass
.getProject()).getNameHelper().isIdentifier(info
.getNewName())) {
137 return RefactoringBundle
.message("error.wrong.name.input", info
.getNewName());
140 LOG
.assertTrue(myTypeCodeFragments
.size() == myTypeParameterInfos
.size());
141 for (int i
= 0; i
< myTypeCodeFragments
.size(); i
++) {
142 final PsiTypeCodeFragment codeFragment
= myTypeCodeFragments
.get(i
);
143 TypeParameterInfo info
= myTypeParameterInfos
.get(i
);
144 if (info
.getOldParameterIndex() >= 0) continue;
147 type
= codeFragment
.getType();
149 catch (PsiTypeCodeFragment
.TypeSyntaxException e
) {
150 return RefactoringBundle
.message("changeClassSignature.bad.default.value", codeFragment
.getText(), info
.getNewName());
152 catch (PsiTypeCodeFragment
.NoTypeException e
) {
153 return RefactoringBundle
.message("changeSignature.no.type.for.parameter", info
.getNewName());
155 info
.setDefaultValue(type
);
160 private class MyTableModel
extends AbstractTableModel
implements RowEditableTableModel
{
161 public int getColumnCount() {
165 public int getRowCount() {
166 return myTypeParameterInfos
.size();
169 public Class
getColumnClass(int columnIndex
) {
170 switch(columnIndex
) {
179 public Object
getValueAt(int rowIndex
, int columnIndex
) {
180 switch(columnIndex
) {
182 TypeParameterInfo info
= myTypeParameterInfos
.get(rowIndex
);
183 if (info
.isForExistingParameter()) {
184 return myOriginalParameters
[info
.getOldParameterIndex()].getName();
187 return info
.getNewName();
190 return myTypeCodeFragments
.get(rowIndex
);
192 LOG
.assertTrue(false);
196 public boolean isCellEditable(int rowIndex
, int columnIndex
) {
197 return !myTypeParameterInfos
.get(rowIndex
).isForExistingParameter();
200 public String
getColumnName(int column
) {
203 return RefactoringBundle
.message("column.name.name");
205 return RefactoringBundle
.message("changeSignature.default.value.column");
207 LOG
.assertTrue(false);
212 public void setValueAt(Object aValue
, int rowIndex
, int columnIndex
) {
213 switch(columnIndex
) {
215 myTypeParameterInfos
.get(rowIndex
).setNewName((String
) aValue
);
220 LOG
.assertTrue(false);
224 public void addRow() {
225 TableUtil
.stopEditing(myTable
);
226 myTypeParameterInfos
.add(new TypeParameterInfo("", null));
227 myTypeCodeFragments
.add(createValueCodeFragment());
228 fireTableDataChanged();
231 public void removeRow(int index
) {
232 myTypeParameterInfos
.remove(index
);
233 myTypeCodeFragments
.remove(index
);
234 fireTableDataChanged();
237 public void exchangeRows(int index1
, int index2
) {
238 ContainerUtil
.swapElements(myTypeParameterInfos
, index1
, index2
);
239 ContainerUtil
.swapElements(myTypeCodeFragments
, index1
, index2
);
240 fireTableDataChanged();
241 //fireTableRowsUpdated(Math.min(index1, index2), Math.max(index1, index2));
245 private class MyCellRenderer
extends ColoredTableCellRenderer
{
247 public void customizeCellRenderer(JTable table
, Object value
,
248 boolean isSelected
, boolean hasFocus
, int row
, int column
) {
249 if (!myTableModel
.isCellEditable(row
, column
)) {
250 setBackground(getBackground().darker());
252 append((String
)value
, new SimpleTextAttributes(Font
.PLAIN
, null));
256 private class MyCodeFragmentTableCellRenderer
extends CodeFragmentTableCellRenderer
{
258 public MyCodeFragmentTableCellRenderer() {
262 public Component
getTableCellRendererComponent(JTable table
, Object value
, boolean isSelected
, boolean hasFocus
, int row
, int column
) {
263 final Component component
= super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
, row
, column
);
264 if (!myTableModel
.isCellEditable(row
, column
)) {
265 component
.setBackground(component
.getBackground().darker());