update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / changeClassSignature / ChangeClassSignatureDialog.java
blob4120fd3832609e9f89d026aef9c48bf52cc17d53
1 /*
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;
34 import javax.swing.*;
35 import javax.swing.table.AbstractTableModel;
36 import javax.swing.table.TableColumn;
37 import java.awt.*;
38 import java.util.ArrayList;
39 import java.util.List;
41 /**
42 * @author dsl
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);
61 myClass = aClass;
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();
71 init();
74 private PsiTypeCodeFragment createValueCodeFragment() {
75 return JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory().createTypeCodeFragment(
76 "",
77 myClass.getLBrace(),
78 false, true, false
82 protected JComponent createNorthPanel() {
83 Box box = Box.createHorizontalBox();
84 JLabel label = new JLabel(RefactoringBundle.message("changeClassSignature.class.label.text", UsageViewUtil.getDescriptiveName(myClass)));
85 box.add(label);
86 box.add(Box.createHorizontalGlue());
87 return box;
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);
118 return panel;
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());
126 return;
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;
145 PsiType type;
146 try {
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);
157 return null;
160 private class MyTableModel extends AbstractTableModel implements RowEditableTableModel {
161 public int getColumnCount() {
162 return 2;
165 public int getRowCount() {
166 return myTypeParameterInfos.size();
169 public Class getColumnClass(int columnIndex) {
170 switch(columnIndex) {
171 case NAME_COLUMN:
172 return String.class;
174 default:
175 return null;
179 public Object getValueAt(int rowIndex, int columnIndex) {
180 switch(columnIndex) {
181 case NAME_COLUMN:
182 TypeParameterInfo info = myTypeParameterInfos.get(rowIndex);
183 if (info.isForExistingParameter()) {
184 return myOriginalParameters[info.getOldParameterIndex()].getName();
186 else {
187 return info.getNewName();
189 case VALUE_COLUMN:
190 return myTypeCodeFragments.get(rowIndex);
192 LOG.assertTrue(false);
193 return null;
196 public boolean isCellEditable(int rowIndex, int columnIndex) {
197 return !myTypeParameterInfos.get(rowIndex).isForExistingParameter();
200 public String getColumnName(int column) {
201 switch(column) {
202 case NAME_COLUMN:
203 return RefactoringBundle.message("column.name.name");
204 case VALUE_COLUMN:
205 return RefactoringBundle.message("changeSignature.default.value.column");
206 default:
207 LOG.assertTrue(false);
208 return null;
212 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
213 switch(columnIndex) {
214 case NAME_COLUMN:
215 myTypeParameterInfos.get(rowIndex).setNewName((String) aValue);
216 break;
217 case VALUE_COLUMN:
218 break;
219 default:
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() {
259 super(getProject());
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());
268 return component;