From 60ef285dc1eec943de55cb5ff87c51f3bea2db7d Mon Sep 17 00:00:00 2001 From: "Kirill.Safonov" Date: Wed, 8 Sep 2010 22:16:13 +0400 Subject: [PATCH] Change Signature dialog refactored to use TableView and ColumnInfo-s and be more 'Flex'-ible --- .../ChangeMethodSignatureFromUsageFix.java | 5 +- .../JavaChangeSignatureDialog.java | 177 +++------ .../JavaParameterTableModel.java | 184 +++++++-- .../ChangeSignatureDialogBase.java | 122 ++---- .../ParameterTableModelBase.java | 357 ++++++++++-------- .../ParameterTableModelItemBase.java | 33 ++ .../src/messages/RefactoringBundle.properties | 6 +- .../com/intellij/util/ui/ListTableModel.java | 10 + 8 files changed, 488 insertions(+), 406 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelItemBase.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java index 6b939d4022d8..b45c7a264f6c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java @@ -156,7 +156,7 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction { return ++usagesFound[0] < myMinUsagesNumberToShowDialog; } }; - + handler.processElementUsages(method, processor, options); } }; @@ -190,7 +190,8 @@ public class ChangeMethodSignatureFromUsageFix implements IntentionAction { JavaChangeSignatureDialog dialog = new JavaChangeSignatureDialog(project, method, false, refExpr); dialog.setParameterInfos(parameterInfos); dialog.show(); - myNewParametersInfo = dialog.getParameters(); + List parameters = dialog.getParameters(); + myNewParametersInfo = parameters.toArray(new ParameterInfoImpl[parameters.size()]); } } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java index 98ee4a152830..af47d9aa0160 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureDialog.java @@ -15,11 +15,6 @@ */ package com.intellij.refactoring.changeSignature; -import com.intellij.codeInsight.completion.JavaCompletionUtil; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupManager; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.editor.Editor; import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; @@ -27,15 +22,19 @@ import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; -import com.intellij.psi.codeStyle.VariableKind; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.changeSignature.inCallers.JavaCallerChooser; -import com.intellij.refactoring.ui.*; +import com.intellij.refactoring.ui.CodeFragmentTableCellRenderer; +import com.intellij.refactoring.ui.JavaCodeFragmentTableCellEditor; +import com.intellij.refactoring.ui.JavaVisibilityPanel; +import com.intellij.refactoring.ui.VisibilityPanelBase; import com.intellij.refactoring.util.CanonicalTypes; import com.intellij.refactoring.util.RefactoringMessageUtil; import com.intellij.refactoring.util.RefactoringUtil; -import com.intellij.ui.EditorTextField; +import com.intellij.ui.EditableRowTable; +import com.intellij.ui.IdeBorderFactory; +import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.table.JBTable; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Consumer; @@ -45,20 +44,16 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.table.TableCellEditor; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.util.LinkedHashSet; import java.util.List; import java.util.Set; public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase { - private static final Logger LOG = Logger.getInstance(JavaChangeSignatureDialog.class.getName()); - private ExceptionsTableModel myExceptionsTableModel; protected Set myMethodsToPropagateExceptions; private JButton myPropagateExnChangesButton; @@ -132,8 +127,35 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase parameters = getParameters(); return new ChangeSignatureProcessor(myProject, myMethod.getMethod(), isGenerateDelegate(), getVisibility(), getMethodName(), getReturnType(), - getParameters(), getExceptions(), + parameters.toArray(new ParameterInfoImpl[parameters.size()]), getExceptions(), myMethodsToPropagateParameters, myMethodsToPropagateExceptions); } @@ -198,41 +221,6 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase codeFragments = myParametersTableModel.getCodeFragments(); - final List defaultValueFragments = myParametersTableModel.getDefaultValueFragments(); - ParameterInfoImpl[] parameterInfos = myParametersTableModel.getParameters(); - final int newParametersNumber = parameterInfos.length; - LOG.assertTrue(codeFragments.size() == newParametersNumber); + List> parameterInfos = myParametersTableModel.getItems(); + final int newParametersNumber = parameterInfos.size(); for (int i = 0; i < newParametersNumber; i++) { - ParameterInfoImpl info = parameterInfos[i]; - PsiTypeCodeFragment psiCodeFragment = (PsiTypeCodeFragment)codeFragments.get(i); - PsiCodeFragment defaultValueFragment = defaultValueFragments.get(i); + ParameterTableModelItemBase item = parameterInfos.get(i); - if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(info.getName())) { - return RefactoringMessageUtil.getIncorrectIdentifierMessage(info.getName()); + if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(item.parameter.getName())) { + return RefactoringMessageUtil.getIncorrectIdentifierMessage(item.parameter.getName()); } final PsiType type; try { - type = psiCodeFragment.getType(); + type = ((PsiTypeCodeFragment)parameterInfos.get(i).typeCodeFragment).getType(); } catch (PsiTypeCodeFragment.TypeSyntaxException e) { - return RefactoringBundle.message("changeSignature.wrong.type.for.parameter", psiCodeFragment.getText(), info.getName()); + return RefactoringBundle + .message("changeSignature.wrong.type.for.parameter", item.typeCodeFragment.getText(), item.parameter.getName()); } catch (PsiTypeCodeFragment.NoTypeException e) { - return RefactoringBundle.message("changeSignature.no.type.for.parameter", info.getName()); + return RefactoringBundle.message("changeSignature.no.type.for.parameter", item.parameter.getName()); } - info.setType(type); + item.parameter.setType(type); if (type instanceof PsiEllipsisType && i != newParametersNumber - 1) { return RefactoringBundle.message("changeSignature.vararg.not.last"); } - if (info.oldParameterIndex < 0) { - info.defaultValue = defaultValueFragment.getText(); - String def = info.defaultValue; + if (item.parameter.oldParameterIndex < 0) { + item.parameter.defaultValue = item.defaultValueCodeFragment.getText(); + String def = item.parameter.defaultValue; def = def.trim(); if (!(type instanceof PsiEllipsisType)) { if (def.length() == 0) { - return RefactoringBundle.message("changeSignature.no.default.value", info.getName()); + return RefactoringBundle.message("changeSignature.no.default.value", item.parameter.getName()); } try { - factory.createExpressionFromText(info.defaultValue, null); + factory.createExpressionFromText(def, null); } catch (IncorrectOperationException e) { return e.getMessage(); @@ -388,23 +372,20 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase codeFraments = myParametersTableModel.getCodeFragments(); - - final ParameterInfoImpl[] parameterInfos = myParametersTableModel.getParameters(); - LOG.assertTrue(codeFraments.size() == parameterInfos.length); final String indent = " "; - for (int i = 0; i < parameterInfos.length; i++) { - ParameterInfoImpl info = parameterInfos[i]; + List> items = myParametersTableModel.getItems(); + for (int i = 0; i < items.size(); i++) { + ParameterTableModelItemBase item = items.get(i); if (i > 0) { buffer.append(","); } buffer.append("\n"); buffer.append(indent); - buffer.append(codeFraments.get(i).getText()); + buffer.append(item.typeCodeFragment.getText()); buffer.append(" "); - buffer.append(info.getName()); + buffer.append(item.parameter.getName()); } - if (parameterInfos.length > 0) { + if (!items.isEmpty()) { buffer.append("\n"); } buffer.append(")"); @@ -425,40 +406,4 @@ public class JavaChangeSignatureDialog extends ChangeSignatureDialogBase set = new LinkedHashSet(); - JavaCompletionUtil.completeVariableNameForRefactoring(myProject, set, prefix, type, VariableKind.PARAMETER); - - LookupElement[] lookupItems = set.toArray(new LookupElement[set.size()]); - editor.getCaretModel().moveToOffset(prefix.length()); - editor.getSelectionModel().removeSelection(); - LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix); - } - - private class MyNameTableCellEditor extends StringTableCellEditor { - public MyNameTableCellEditor(Project project) { - super(project); - } - - public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { - final EditorTextField textField = (EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column); - textField.registerKeyboardAction(new ActionListener() { - public void actionPerformed(ActionEvent e) { - int column = myParametersTable.convertColumnIndexToModel(myParametersTable.getEditingColumn()); - if (column == 1) { - int row = myParametersTable.getEditingRow(); - PsiType type = ((JavaParameterTableModel)myParametersTableModel).getTypeByRow(row); - if (type != null) { - completeVariable(textField, type); - } - } - } - }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); - return textField; - } - } - } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterTableModel.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterTableModel.java index 351bc40281da..603a7974effa 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterTableModel.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterTableModel.java @@ -15,61 +15,175 @@ */ package com.intellij.refactoring.changeSignature; -import com.intellij.openapi.diagnostic.Logger; +import com.intellij.codeInsight.completion.JavaCompletionUtil; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.VariableKind; +import com.intellij.refactoring.ui.JavaCodeFragmentTableCellEditor; +import com.intellij.refactoring.ui.StringTableCellEditor; +import com.intellij.ui.EditorTextField; +import com.intellij.util.ui.ColumnInfo; import org.jetbrains.annotations.Nullable; -public class JavaParameterTableModel extends ParameterTableModelBase { - private static final Logger LOG = Logger.getInstance(JavaParameterTableModel.class.getName()); +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.util.LinkedHashSet; +import java.util.Set; +public class JavaParameterTableModel extends ParameterTableModelBase { private final Project myProject; - public JavaParameterTableModel(PsiElement typeContext, + public JavaParameterTableModel(final PsiElement typeContext, PsiElement defaultValueContext, - ChangeSignatureDialogBase dialog) { - super(typeContext, defaultValueContext, dialog, ParameterInfoImpl.class); + final ChangeSignatureDialogBase dialog) { + this(typeContext, defaultValueContext, + new JavaTypeColumn(typeContext.getProject()), + new JavaNameColumn(typeContext.getProject()), + new DefaultValueColumn(typeContext.getProject(), StdFileTypes.JAVA) { + @Override + public TableCellEditor doCreateEditor(ParameterTableModelItemBase item) { + return new EditorWithExpectedType(typeContext); + } + }, new AnyVarColumn() { + @Override + public boolean isCellEditable(ParameterTableModelItemBase item) { + return !dialog.isGenerateDelegate() && super.isCellEditable(item); + } + }); + } + + protected JavaParameterTableModel(PsiElement typeContext, PsiElement defaultValueContext, ColumnInfo... columns) { + super(typeContext, defaultValueContext, columns); myProject = typeContext.getProject(); } @Override - protected ParameterInfoImpl createParameterInfo() { - return new ParameterInfoImpl(-1); - } + protected ParameterTableModelItemBase createRowItem(@Nullable ParameterInfoImpl parameterInfo) { + if (parameterInfo == null) { + parameterInfo = new ParameterInfoImpl(-1); + } + PsiElementFactory f = JavaPsiFacade.getInstance(myProject).getElementFactory(); + final PsiTypeCodeFragment paramTypeCodeFragment = + f.createTypeCodeFragment(parameterInfo.getTypeText(), myTypeContext, false, true, true); + PsiExpressionCodeFragment defaultValueCodeFragment = + f.createExpressionCodeFragment(parameterInfo.getDefaultValue(), myDefaultValueContext, null, true); + defaultValueCodeFragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); - @Override - protected boolean isEllipsisType(int row) { - return getTypeByRow(row) instanceof PsiEllipsisType; - } - - @Override - protected PsiCodeFragment createDefaultValueCodeFragment(String expressionText) { - PsiExpressionCodeFragment codeFragment = JavaPsiFacade.getInstance(myProject).getElementFactory() - .createExpressionCodeFragment(expressionText, myDefaultValueContext, null, true); - codeFragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); - return codeFragment; - } - - @Override - protected PsiCodeFragment createParameterTypeCodeFragment(String typeText) { - return JavaPsiFacade.getInstance(myProject).getElementFactory().createTypeCodeFragment(typeText, myTypeContext, false, true, true); + return new ParameterTableModelItemBase(parameterInfo, paramTypeCodeFragment, defaultValueCodeFragment) { + @Override + public boolean isEllipsisType() { + try { + return paramTypeCodeFragment.getType() instanceof PsiEllipsisType; + } + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return false; + } + catch (PsiTypeCodeFragment.NoTypeException e) { + return false; + } + } + }; } @Nullable - public PsiType getTypeByRow(int row) { - Object typeValueAt = getValueAt(row, 0); - LOG.assertTrue(typeValueAt instanceof PsiTypeCodeFragment); - PsiType type; + private static PsiType getRowType(JTable table, int row) { try { - type = ((PsiTypeCodeFragment)typeValueAt).getType(); + return ((PsiTypeCodeFragment)((JavaParameterTableModel)table.getModel()).getItems().get(row).typeCodeFragment).getType(); } - catch (PsiTypeCodeFragment.TypeSyntaxException e1) { - type = null; + catch (PsiTypeCodeFragment.TypeSyntaxException e) { + return null; } - catch (PsiTypeCodeFragment.NoTypeException e1) { - type = null; + catch (PsiTypeCodeFragment.NoTypeException e) { + return null; } - return type; } + private static class VariableCompletionTableCellEditor extends StringTableCellEditor { + public VariableCompletionTableCellEditor(Project project) { + super(project); + } + + public Component getTableCellEditorComponent(final JTable table, + Object value, + boolean isSelected, + final int row, + int column) { + final EditorTextField textField = + (EditorTextField)super.getTableCellEditorComponent(table, value, isSelected, row, column); + textField.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + PsiType type = getRowType(table, row); + if (type != null) { + completeVariable(textField, type); + } + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); + return textField; + } + + private static void completeVariable(EditorTextField editorTextField, PsiType type) { + Editor editor = editorTextField.getEditor(); + String prefix = editorTextField.getText(); + if (prefix == null) prefix = ""; + Set set = new LinkedHashSet(); + JavaCompletionUtil.completeVariableNameForRefactoring(editorTextField.getProject(), set, prefix, type, VariableKind.PARAMETER); + + LookupElement[] lookupItems = set.toArray(new LookupElement[set.size()]); + editor.getCaretModel().moveToOffset(prefix.length()); + editor.getSelectionModel().removeSelection(); + LookupManager.getInstance(editorTextField.getProject()).showLookup(editor, lookupItems, prefix); + } + } + + private static class EditorWithExpectedType extends JavaCodeFragmentTableCellEditor { + public EditorWithExpectedType(PsiElement typeContext) { + super(typeContext.getProject()); + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + final Component editor = super.getTableCellEditorComponent(table, value, isSelected, row, column); + final PsiType type = getRowType(table, row); + if (type != null) { + ((PsiExpressionCodeFragment)myCodeFragment).setExpectedType(type); + } + return editor; + } + } + + public static class JavaTypeColumn extends TypeColumn { + private final Project myProject; + + public JavaTypeColumn(Project project) { + super(project, StdFileTypes.JAVA); + myProject = project; + } + + @Override + public TableCellEditor doCreateEditor(ParameterTableModelItemBase o) { + return new JavaCodeFragmentTableCellEditor(myProject); + } + } + + public static class JavaNameColumn extends NameColumn { + private final Project myProject; + + public JavaNameColumn(Project project) { + super(project); + myProject = project; + } + + @Override + public TableCellEditor doCreateEditor(ParameterTableModelItemBase o) { + return new VariableCompletionTableCellEditor(myProject); + } + } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java index 33f6464093e3..de9e2cc68bbe 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ChangeSignatureDialogBase.java @@ -17,7 +17,6 @@ package com.intellij.refactoring.changeSignature; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ModalityState; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.editor.event.DocumentListener; @@ -33,13 +32,12 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.ui.CodeFragmentTableCellRenderer; import com.intellij.refactoring.ui.DelegationPanel; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.ui.VisibilityPanelBase; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.ui.*; -import com.intellij.ui.table.JBTable; +import com.intellij.ui.table.TableView; import com.intellij.ui.treeStructure.Tree; import com.intellij.util.Alarm; import com.intellij.util.Consumer; @@ -50,23 +48,22 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableColumn; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.StringTokenizer; public abstract class ChangeSignatureDialogBase

> extends RefactoringDialog { - private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.ChangeSignatureDialogBase"); + protected final D myMethod; private final boolean myAllowDelegation; private EditorTextField myNameField; protected EditorTextField myReturnTypeField; - protected JTable myParametersTable; + protected TableView> myParametersTable; protected final ParameterTableModelBase

myParametersTableModel; private JTextArea mySignatureArea; private final Alarm myUpdateSignatureAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); @@ -92,12 +89,6 @@ public abstract class ChangeSignatureDialogBase

createCallerChooser(String title, Tree treeToReuse, Consumer> callback); - protected abstract TableCellEditor createTypeCellEditor(); - - protected abstract TableCellEditor createNameCellEditor(); - - protected abstract TableCellEditor createDefaultValueCellEditor(); - protected abstract String validateAndCommitData(); protected abstract boolean isResolvableType(P info, MethodDescriptor

method); @@ -144,8 +135,12 @@ public abstract class ChangeSignatureDialogBase

getParameters() { + List

result = new ArrayList

(myParametersTableModel.getRowCount()); + for (ParameterTableModelItemBase

item : myParametersTableModel.getItems()) { + result.add(item.parameter); + } + return result; } public boolean isGenerateDelegate() { @@ -225,7 +220,7 @@ public abstract class ChangeSignatureDialogBase

>(myParametersTableModel) { @Override public void editingStopped(ChangeEvent e) { super.editingStopped(e); @@ -291,23 +286,11 @@ public abstract class ChangeSignatureDialogBase

3) { - final TableColumn anyVarColumn = myParametersTable.getColumnModel().getColumn(3); - final int headerWidth = - myParametersTable.getFontMetrics(myParametersTable.getFont()).stringWidth(RefactoringBundle.message("column.name.any.var")) + 8; - anyVarColumn.setMaxWidth(Math.max(minWidth, headerWidth)); - } - configureParameterTableEditors(); - return createTablePanelImpl(myParametersTable, myParametersTableModel, RefactoringBundle.message("parameters.border.title"), true); - } - protected JPanel createTablePanelImpl(JTable table, RowEditableTableModel tableModel, String borderTitle, boolean addMnemonics) { JPanel panel = new JPanel(new BorderLayout()); - panel.setBorder(IdeBorderFactory.createTitledBorder(borderTitle)); + panel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("parameters.border.title"))); - JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(table); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myParametersTable); JPanel tablePanel = new JPanel(new BorderLayout()); tablePanel.add(scrollPane, BorderLayout.CENTER); @@ -315,16 +298,16 @@ public abstract class ChangeSignatureDialogBase

2) { - myParametersTable.getColumnModel().getColumn(2).setCellRenderer(new CodeFragmentTableCellRenderer(myProject, getFileType()) { - - public Component getTableCellRendererComponent(JTable table, - Object value, - boolean isSelected, - boolean hasFocus, - int row, - int column) { - Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) { - component.setBackground(myParametersTable.getBackground().darker()); - } - return component; - } - }); - } - if (myParametersTable.getColumnCount() > 3) { - myParametersTable.getColumnModel().getColumn(3).setCellRenderer(new BooleanTableCellRenderer() { - public Component getTableCellRendererComponent(JTable table, - Object value, - boolean isSelected, - boolean hasFocus, - int row, - int column) { - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - if (!myParametersTableModel.isCellEditable(row, myParametersTable.convertColumnIndexToModel(column))) { - setBackground(myParametersTable.getBackground().darker()); - } - return this; - } - }); - } - myParametersTable.getColumnModel().getColumn(0).setCellEditor(createTypeCellEditor()); - myParametersTable.getColumnModel().getColumn(1).setCellEditor(createNameCellEditor()); - if (myParametersTable.getColumnCount() > 2) { - myParametersTable.getColumnModel().getColumn(2).setCellEditor(createDefaultValueCellEditor()); - } - } - private JComponent createSignaturePanel() { JPanel panel = new JPanel(new BorderLayout()); panel.setBorder(BorderFactory.createCompoundBorder( @@ -428,10 +368,10 @@ public abstract class ChangeSignatureDialogBase

infos = getParameters(); + if (infos.size() <= myMethod.getParametersCount()) return false; for (int i = 0; i < myMethod.getParametersCount(); i++) { - if (infos[i].getOldIndex() != i) return false; + if (infos.get(i).getOldIndex() != i) return false; } return true; } @@ -460,9 +400,7 @@ public abstract class ChangeSignatureDialogBase

extends AbstractTableModel implements RowEditableTableModel { +public abstract class ParameterTableModelBase

extends ListTableModel> + implements RowEditableTableModel { - private List

myParameterInfos; - private List myTypeCodeFraments; - private List myDefaultValuesCodeFragments; protected final PsiElement myTypeContext; protected final PsiElement myDefaultValueContext; - private final ChangeSignatureDialogBase myDialog; - private final Class

myParameterInfoClass; - static final String ANY_VAR_COLUMN_NAME = RefactoringBundle.message("column.name.any.var"); public ParameterTableModelBase(PsiElement typeContext, PsiElement defaultValueContext, - ChangeSignatureDialogBase dialog, - Class

clazz) { + ColumnInfo... columnInfos) { + super(columnInfos); myTypeContext = typeContext; myDefaultValueContext = defaultValueContext; - myDialog = dialog; - myParameterInfoClass = clazz; } - public Class getColumnClass(int columnIndex) { - if (columnIndex == 3) return Boolean.class; - return super.getColumnClass(columnIndex); - } - - public List getCodeFragments() { - return Collections.unmodifiableList(myTypeCodeFraments); - } - - public List getDefaultValueFragments() { - return Collections.unmodifiableList(myDefaultValuesCodeFragments); - } - - public P[] getParameters() { - return ArrayUtil.toObjectArray(myParameterInfos, myParameterInfoClass); - } - - protected abstract P createParameterInfo(); - - protected abstract boolean isEllipsisType(int row); - - protected abstract PsiCodeFragment createDefaultValueCodeFragment(final String expressionText); - - protected abstract PsiCodeFragment createParameterTypeCodeFragment(final String typeText); + protected abstract ParameterTableModelItemBase

createRowItem(@Nullable P parameterInfo); public void addRow() { - P parameterInfo = createParameterInfo(); - myParameterInfos.add(parameterInfo); - myTypeCodeFraments.add(createParameterTypeCodeFragment("")); - myDefaultValuesCodeFragments.add(createDefaultValueCodeFragment(parameterInfo.getDefaultValue())); - fireTableRowsInserted(myParameterInfos.size() - 1, myParameterInfos.size() - 1); - } - - public void removeRow(int index) { - myParameterInfos.remove(index); - myTypeCodeFraments.remove(index); - myDefaultValuesCodeFragments.remove(index); - fireTableRowsDeleted(index, index); - } - - public void exchangeRows(int index1, int index2) { - Collections.swap(myParameterInfos, index1, index2); - Collections.swap(myTypeCodeFraments, index1, index2); - Collections.swap(myDefaultValuesCodeFragments, index1, index2); - if (index1 < index2) { - fireTableRowsUpdated(index1, index2); - } - else { - fireTableRowsUpdated(index2, index1); - } - } - - public int getRowCount() { - return myParameterInfos.size(); - } - - public int getColumnCount() { - return 4; - } - - public Object getValueAt(int rowIndex, int columnIndex) { - P info = myParameterInfos.get(rowIndex); - switch (columnIndex) { - case 0: - return myTypeCodeFraments.get(rowIndex); - case 1: - return info.getName(); - case 2: - return myDefaultValuesCodeFragments.get(rowIndex); - case 3: - return Boolean.valueOf(info.isUseAnySingleVariable()); - - default: - throw new IllegalArgumentException(); - } - } - - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - if (rowIndex < 0 || rowIndex >= myParameterInfos.size()) return; - String s = aValue instanceof String ? (String)aValue : ""; - s = s.trim(); - P info = myParameterInfos.get(rowIndex); - switch (columnIndex) { - case 0: - //info.setType(); - break; - - case 1: - info.setName(s); - break; - - case 2: - break; - - case 3: - info.setUseAnySingleVariable(((Boolean)aValue).booleanValue()); - break; - - default: - throw new IllegalArgumentException(); - } - fireTableCellUpdated(rowIndex, columnIndex); - } - - public String getColumnName(int column) { - switch (column) { - case 0: - return RefactoringBundle.message("column.name.type"); - case 1: - return RefactoringBundle.message("column.name.name"); - case 2: - return RefactoringBundle.message("column.name.default.value"); - case 3: - return ANY_VAR_COLUMN_NAME; - default: - throw new IllegalArgumentException(); - } - } - - public boolean isCellEditable(int rowIndex, int columnIndex) { - switch (columnIndex) { - case 0: - case 1: - return true; - - case 3: - if (myDialog.isGenerateDelegate()) return false; - // fallback - case 2: - return !isEllipsisType(rowIndex) && myParameterInfos.get(rowIndex).getOldIndex() < 0; - - default: - throw new IllegalArgumentException(); - } + addRow(createRowItem(null)); } public void setParameterInfos(List

parameterInfos) { - myParameterInfos = parameterInfos; - myTypeCodeFraments = new ArrayList(parameterInfos.size()); - myDefaultValuesCodeFragments = new ArrayList(parameterInfos.size()); + List> items = new ArrayList>(parameterInfos.size()); for (P parameterInfo : parameterInfos) { - myTypeCodeFraments.add(createParameterTypeCodeFragment(parameterInfo.getTypeText())); - myDefaultValuesCodeFragments.add(createDefaultValueCodeFragment(parameterInfo.getDefaultValue())); + items.add(createRowItem(parameterInfo)); + } + setItems(items); + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + super.setValueAt(aValue, rowIndex, columnIndex); + fireTableCellUpdated(rowIndex, columnIndex); // to update signature + } + + protected static abstract class ColumnInfoBase

+ extends ColumnInfo, Aspect> { + private TableCellRenderer myRenderer; + private TableCellEditor myEditor; + + public ColumnInfoBase(String name) { + super(name); + } + + @Override + public final TableCellEditor getEditor(ParameterTableModelItemBase

o) { + if (myEditor == null) { + myEditor = doCreateEditor(o); + } + return myEditor; + } + + @Override + public final TableCellRenderer getRenderer(ParameterTableModelItemBase

item) { + if (myRenderer == null) { + final TableCellRenderer original = doCreateRenderer(item); + myRenderer = new TableCellRenderer() { + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + Component component = original.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (!table.isCellEditable(row, table.convertColumnIndexToModel(column))) { + component.setBackground(table.getBackground().darker()); + } + return component; + } + }; + } + return myRenderer; + } + + protected abstract TableCellRenderer doCreateRenderer(ParameterTableModelItemBase

item); + + protected abstract TableCellEditor doCreateEditor(ParameterTableModelItemBase

item); + } + + protected static class TypeColumn

extends ColumnInfoBase { + private final Project myProject; + private final FileType myFileType; + + public TypeColumn(Project project, FileType fileType) { + super(RefactoringBundle.message("column.name.type")); + myProject = project; + myFileType = fileType; + } + + @Override + public PsiCodeFragment valueOf(ParameterTableModelItemBase

item) { + return item.typeCodeFragment; + } + + @Override + public boolean isCellEditable(ParameterTableModelItemBase

pParameterTableModelItemBase) { + return true; + } + + public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase

pParameterTableModelItemBase) { + return new CodeFragmentTableCellRenderer(myProject, myFileType); + } + + public TableCellEditor doCreateEditor(ParameterTableModelItemBase

o) { + return new CodeFragmentTableCellEditorBase(myProject, myFileType); + } + } + + protected static class NameColumn

extends ColumnInfoBase { + private final Project myProject; + + public NameColumn(Project project) { + super(RefactoringBundle.message("column.name.name")); + myProject = project; + } + + @Override + public String valueOf(ParameterTableModelItemBase

item) { + return item.parameter.getName(); + } + + @Override + public void setValue(ParameterTableModelItemBase

item, String value) { + item.parameter.setName(value); + } + + @Override + public boolean isCellEditable(ParameterTableModelItemBase

pParameterTableModelItemBase) { + return true; + } + + public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase

item) { + return new ColoredTableCellRenderer() { + public void customizeCellRenderer(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + if (value == null) return; + append((String)value, new SimpleTextAttributes(Font.PLAIN, null)); + } + }; + } + + public TableCellEditor doCreateEditor(ParameterTableModelItemBase

o) { + return new StringTableCellEditor(myProject); + } + } + + protected static class DefaultValueColumn

extends ColumnInfoBase { + private final Project myProject; + private final FileType myFileType; + + public DefaultValueColumn(Project project, FileType fileType) { + super(RefactoringBundle.message("column.name.default.value")); + myProject = project; + myFileType = fileType; + } + + @Override + public boolean isCellEditable(ParameterTableModelItemBase

item) { + return !item.isEllipsisType() && item.parameter.getOldIndex() == -1; + } + + @Override + public PsiCodeFragment valueOf(ParameterTableModelItemBase

item) { + return item.defaultValueCodeFragment; + } + + public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase

item) { + return new CodeFragmentTableCellRenderer(myProject, myFileType); + } + + public TableCellEditor doCreateEditor(ParameterTableModelItemBase

item) { + return new CodeFragmentTableCellEditorBase(myProject, myFileType); + } + } + + protected static class AnyVarColumn

extends ColumnInfoBase { + + public AnyVarColumn() { + super(RefactoringBundle.message("column.name.any.var")); + } + + @Override + public boolean isCellEditable(ParameterTableModelItemBase

item) { + return !item.isEllipsisType() && item.parameter.getOldIndex() == -1; + } + + @Override + public Boolean valueOf(ParameterTableModelItemBase

item) { + return item.parameter.isUseAnySingleVariable(); + } + + @Override + public void setValue(ParameterTableModelItemBase

item, Boolean value) { + item.parameter.setUseAnySingleVariable(value); + } + + public TableCellRenderer doCreateRenderer(ParameterTableModelItemBase

item) { + return new BooleanTableCellRenderer(); + } + + public TableCellEditor doCreateEditor(ParameterTableModelItemBase

item) { + return new BooleanTableCellEditor(false); + } + + @Override + public int getWidth(JTable table) { + final int headerWidth = table.getFontMetrics(table.getFont()).stringWidth(getName()) + 8; + return Math.max(new JCheckBox().getPreferredSize().width, headerWidth); } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelItemBase.java b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelItemBase.java new file mode 100644 index 000000000000..513b424b8e14 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/changeSignature/ParameterTableModelItemBase.java @@ -0,0 +1,33 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.refactoring.changeSignature; + +import com.intellij.psi.PsiCodeFragment; + +public abstract class ParameterTableModelItemBase

{ + public final P parameter; + public final PsiCodeFragment typeCodeFragment; + public final PsiCodeFragment defaultValueCodeFragment; + + public ParameterTableModelItemBase(P parameter, PsiCodeFragment typeCodeFragment, PsiCodeFragment defaultValueCodeFragment) { + this.parameter = parameter; + this.typeCodeFragment = typeCodeFragment; + this.defaultValueCodeFragment = defaultValueCodeFragment; + } + + public abstract boolean isEllipsisType(); + +} diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index 96a0f0aa9e6b..e9ad56e17820 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -33,7 +33,7 @@ error.not.supported.for.jsp={0} refactoring is not supported for JSP changeClassSignature.refactoring.name=Change Class Signature changeClassSignature.no.type.parameters=The class cannot have type parameters. changeClassSignature.parameters.panel.border.title=Parameters -changeClassSignature.bad.default.value=Wrong default value: ''{0}'' for parameter {1} +changeClassSignature.bad.default.value=Wrong default value: ''{0}'' for parameter ''{1}'' changeClassSignature.class.label.text=Change signature of {0} changeSignature.no.type.for.parameter=Specify a type for parameter ''{0}'' changeSignature.no.type.for.exception=Specify a type for exception @@ -53,10 +53,10 @@ changeSignature.parameters.wont.propagate=Recursive propagation of parameter cha changeSignature.exceptions.wont.propagate=Recursive propagation of exception changes won't be performed changeSignature.wrong.return.type=Wrong return type: ''{0}'' changeSignature.no.return.type=Specify return type -changeSignature.wrong.type.for.parameter=Wrong type: ''{0}'' for parameter {1} +changeSignature.wrong.type.for.parameter=Wrong type: ''{0}'' for parameter ''{1}'' changeSignature.wrong.type.for.exception=Wrong type: ''{0}'' for exception changeSignature.vararg.not.last=Vararg parameter should be the last in method signature -changeSignature.no.default.value=New parameter {0} has been added.\nSpecify a default value to be used in all existing calls of this method. +changeSignature.no.default.value=New parameter ''{0}'' has been added.\nSpecify a default value to be used in all existing calls of this method. changeSignature.not.throwable.type=Wrong type: ''{0}'' for exception, should extend java.lang.Throwable changeSignature.cannot.resolve.type=Type ''{0}'' cannot be resolved.\nContinue? search.in.comments.and.strings=Search in comments and &strings diff --git a/platform/util/src/com/intellij/util/ui/ListTableModel.java b/platform/util/src/com/intellij/util/ui/ListTableModel.java index 3a298fe9d71e..736f380dcea7 100644 --- a/platform/util/src/com/intellij/util/ui/ListTableModel.java +++ b/platform/util/src/com/intellij/util/ui/ListTableModel.java @@ -146,6 +146,16 @@ public class ListTableModel extends TableViewModel implements ItemRe fireTableRowsDeleted(idx, idx); } + public void exchangeRows(int idx1, int idx2) { + Collections.swap(myItems, idx1, idx2); + if (idx1 < idx2) { + fireTableRowsUpdated(idx1, idx2); + } + else { + fireTableRowsUpdated(idx2, idx1); + } + } + public void addRow(Item item) { myItems.add(item); fireTableRowsInserted(myItems.size() - 1, myItems.size() - 1);