4431cb52cebcd92325fb11c724944434d48a6298
[fedora-idea.git] / java / java-impl / src / com / intellij / refactoring / encapsulateFields / EncapsulateFieldsDialog.java
blob4431cb52cebcd92325fb11c724944434d48a6298
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.encapsulateFields;
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.openapi.util.IconLoader;
22 import com.intellij.openapi.util.Iconable;
23 import com.intellij.psi.*;
24 import com.intellij.psi.util.PropertyUtil;
25 import com.intellij.psi.util.PsiFormatUtil;
26 import com.intellij.refactoring.HelpID;
27 import com.intellij.refactoring.RefactoringBundle;
28 import com.intellij.refactoring.JavaRefactoringSettings;
29 import com.intellij.refactoring.ui.RefactoringDialog;
30 import com.intellij.refactoring.util.CommonRefactoringUtil;
31 import com.intellij.refactoring.util.RefactoringMessageUtil;
32 import com.intellij.ui.*;
33 import com.intellij.util.IconUtil;
34 import com.intellij.util.IncorrectOperationException;
35 import com.intellij.util.ui.EmptyIcon;
36 import com.intellij.util.ui.Table;
37 import com.intellij.util.ui.UIUtil;
38 import org.jetbrains.annotations.NonNls;
40 import javax.swing.*;
41 import javax.swing.border.Border;
42 import javax.swing.table.AbstractTableModel;
43 import javax.swing.table.DefaultTableCellRenderer;
44 import javax.swing.table.TableCellEditor;
45 import javax.swing.table.TableColumnModel;
46 import java.awt.*;
47 import java.awt.event.*;
48 import java.util.Set;
50 public class EncapsulateFieldsDialog extends RefactoringDialog implements EncapsulateFieldsDescriptor {
51 private static final Logger LOG = Logger.getInstance(
52 "#com.intellij.refactoring.encapsulateFields.EncapsulateFieldsDialog"
55 private static final int CHECKED_COLUMN = 0;
56 private static final int FIELD_COLUMN = 1;
57 private static final int GETTER_COLUMN = 2;
58 private static final int SETTER_COLUMN = 3;
60 private final Project myProject;
61 private final PsiClass myClass;
63 private final PsiField[] myFields;
64 private final boolean[] myCheckedMarks;
65 private final boolean[] myFinalMarks;
66 private final String[] myFieldNames;
67 private final String[] myGetterNames;
68 private final PsiMethod[] myGetterPrototypes;
69 private final String[] mySetterNames;
70 private final PsiMethod[] mySetterPrototypes;
72 private JTable myTable;
73 private MyTableModel myTableModel;
75 private final JCheckBox myCbEncapsulateGet = new JCheckBox();
76 private final JCheckBox myCbEncapsulateSet = new JCheckBox();
77 private final JCheckBox myCbUseAccessorsWhenAccessible = new JCheckBox();
78 private final JRadioButton myRbFieldPrivate = new JRadioButton();
79 private final JRadioButton myRbFieldProtected = new JRadioButton();
80 private final JRadioButton myRbFieldPackageLocal = new JRadioButton();
81 private final JRadioButton myRbFieldAsIs = new JRadioButton();
82 private final JRadioButton myRbAccessorPublic = new JRadioButton();
83 private final JRadioButton myRbAccessorProtected = new JRadioButton();
84 private final JRadioButton myRbAccessorPrivate = new JRadioButton();
85 private final JRadioButton myRbAccessorPackageLocal = new JRadioButton();
86 private static final String REFACTORING_NAME = RefactoringBundle.message("encapsulate.fields.title");
89 myCbEncapsulateGet.setFocusable(false);
90 myCbEncapsulateSet.setFocusable(false);
91 myCbUseAccessorsWhenAccessible.setFocusable(false);
93 myRbAccessorPackageLocal.setFocusable(false);
94 myRbAccessorPrivate.setFocusable(false);
95 myRbAccessorProtected.setFocusable(false);
96 myRbAccessorPublic.setFocusable(false);
98 myRbFieldAsIs.setFocusable(false);
99 myRbFieldPackageLocal.setFocusable(false);
100 myRbFieldPrivate.setFocusable(false);
101 myRbFieldProtected.setFocusable(false);
104 public EncapsulateFieldsDialog(Project project, PsiClass aClass, final Set preselectedFields) {
105 super(project, true);
106 myProject = project;
107 myClass = aClass;
109 String title = REFACTORING_NAME;
110 String qName = myClass.getQualifiedName();
111 if (qName != null) {
112 title += " - " + qName;
114 setTitle(title);
116 myFields = myClass.getFields();
117 myFieldNames = new String[myFields.length];
118 myCheckedMarks = new boolean[myFields.length];
119 myFinalMarks = new boolean[myFields.length];
120 myGetterNames = new String[myFields.length];
121 mySetterNames = new String[myFields.length];
122 myGetterPrototypes = new PsiMethod[myFields.length];
123 mySetterPrototypes = new PsiMethod[myFields.length];
124 for (int idx = 0; idx < myFields.length; idx++) {
125 PsiField field = myFields[idx];
126 myCheckedMarks[idx] = preselectedFields.contains(field);
127 myFinalMarks[idx] = field.hasModifierProperty(PsiModifier.FINAL);
128 myFieldNames[idx] =
129 PsiFormatUtil.formatVariable(field,
130 PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER,
131 PsiSubstitutor.EMPTY
133 myGetterNames[idx] = PropertyUtil.suggestGetterName(myProject, field);
134 mySetterNames[idx] = PropertyUtil.suggestSetterName(myProject, field);
135 myGetterPrototypes[idx] = generateMethodPrototype(field, myGetterNames[idx], true);
136 mySetterPrototypes[idx] = generateMethodPrototype(field, mySetterNames[idx], false);
139 init();
142 public PsiField[] getSelectedFields() {
143 int[] rows = getCheckedRows();
144 PsiField[] selectedFields = new PsiField[rows.length];
145 for (int idx = 0; idx < rows.length; idx++) {
146 selectedFields[idx] = myFields[rows[idx]];
148 return selectedFields;
151 public String[] getGetterNames() {
152 int[] rows = getCheckedRows();
153 String[] selectedGetters = new String[rows.length];
154 for (int idx = 0; idx < rows.length; idx++) {
155 selectedGetters[idx] = myGetterNames[rows[idx]];
157 return selectedGetters;
160 public String[] getSetterNames() {
161 int[] rows = getCheckedRows();
162 String[] selectedSetters = new String[rows.length];
163 for (int idx = 0; idx < rows.length; idx++) {
164 selectedSetters[idx] = mySetterNames[rows[idx]];
166 return selectedSetters;
169 public PsiMethod[] getGetterPrototypes() {
170 if (isToEncapsulateGet()) {
171 int[] rows = getCheckedRows();
172 PsiMethod[] selectedGetters = new PsiMethod[rows.length];
173 for (int idx = 0; idx < rows.length; idx++) {
174 selectedGetters[idx] = myGetterPrototypes[rows[idx]];
176 return selectedGetters;
177 } else {
178 return null;
182 public PsiMethod[] getSetterPrototypes() {
183 if (isToEncapsulateSet()) {
184 int[] rows = getCheckedRows();
185 PsiMethod[] selectedSetters = new PsiMethod[rows.length];
186 for (int idx = 0; idx < rows.length; idx++) {
187 selectedSetters[idx] = mySetterPrototypes[rows[idx]];
189 return selectedSetters;
190 } else {
191 return null;
195 public boolean isToEncapsulateGet() {
196 return myCbEncapsulateGet.isSelected();
199 public boolean isToEncapsulateSet() {
200 return myCbEncapsulateSet.isSelected();
203 public boolean isToUseAccessorsWhenAccessible() {
204 if (getFieldsVisibility() == null) {
205 // "as is"
206 return true;
208 return myCbUseAccessorsWhenAccessible.isSelected();
211 @Modifier
212 public String getFieldsVisibility() {
213 if (myRbFieldPrivate.isSelected()) {
214 return PsiModifier.PRIVATE;
215 } else if (myRbFieldPackageLocal.isSelected()) {
216 return PsiModifier.PACKAGE_LOCAL;
217 } else if (myRbFieldProtected.isSelected()) {
218 return PsiModifier.PROTECTED;
219 } else if (myRbFieldAsIs.isSelected()) {
220 return null;
221 } else {
222 LOG.assertTrue(false);
223 return null;
227 protected String getDimensionServiceKey() {
228 return "#com.intellij.refactoring.encapsulateFields.EncalpsulateFieldsDialog";
231 @Modifier
232 public String getAccessorsVisibility() {
233 if (myRbAccessorPublic.isSelected()) {
234 return PsiModifier.PUBLIC;
235 } else if (myRbAccessorProtected.isSelected()) {
236 return PsiModifier.PROTECTED;
237 } else if (myRbAccessorPackageLocal.isSelected()) {
238 return PsiModifier.PACKAGE_LOCAL;
239 } else if (myRbAccessorPrivate.isSelected()) {
240 return PsiModifier.PRIVATE;
241 } else {
242 LOG.assertTrue(false);
243 return null;
247 protected JComponent createCenterPanel() {
248 JPanel panel = new JPanel(new BorderLayout());
249 panel.add(createTable(), BorderLayout.CENTER);
251 myCbEncapsulateGet.setText(RefactoringBundle.message("encapsulate.fields.get.access.checkbox"));
252 myCbEncapsulateSet.setText(RefactoringBundle.message("encapsulate.fields.set.access.checkbox"));
253 myCbUseAccessorsWhenAccessible.setText(RefactoringBundle.message("encapsulate.fields.use.accessors.even.when.field.is.accessible.checkbox"));
254 myRbFieldPrivate.setText(RefactoringBundle.message("encapsulate.fields.private.radio"));
255 myRbFieldProtected.setText(RefactoringBundle.message("encapsulate.fields.protected.radio"));
256 myRbFieldPackageLocal.setText(RefactoringBundle.message("encapsulate.fields..package.local.radio"));
257 myRbFieldAsIs.setText(RefactoringBundle.getVisibilityAsIs());
258 myRbAccessorPublic.setText(RefactoringBundle.getVisibilityPublic());
259 myRbAccessorProtected.setText(RefactoringBundle.getVisibilityProtected());
260 myRbAccessorPrivate.setText(RefactoringBundle.getVisibilityPrivate());
261 myRbAccessorPackageLocal.setText(RefactoringBundle.getVisibilityPackageLocal());
263 ButtonGroup fieldGroup = new ButtonGroup();
264 fieldGroup.add(myRbFieldAsIs);
265 fieldGroup.add(myRbFieldPackageLocal);
266 fieldGroup.add(myRbFieldPrivate);
267 fieldGroup.add(myRbFieldProtected);
269 ButtonGroup methodGroup = new ButtonGroup();
270 methodGroup.add(myRbAccessorPackageLocal);
271 methodGroup.add(myRbAccessorPrivate);
272 methodGroup.add(myRbAccessorProtected);
273 methodGroup.add(myRbAccessorPublic);
275 myCbEncapsulateGet.setSelected(true);
276 myCbEncapsulateSet.setSelected(true);
277 ActionListener checkboxListener = new ActionListener() {
278 public void actionPerformed(ActionEvent e) {
279 if (myCbEncapsulateGet.equals(e.getSource())) {
280 if (!myCbEncapsulateGet.isSelected()) {
281 myCbEncapsulateSet.setSelected(true);
283 } else {
284 // myCbEncapsulateSet is the source
285 if (!myCbEncapsulateSet.isSelected()) {
286 myCbEncapsulateGet.setSelected(true);
289 int[] rows = myTable.getSelectedRows();
290 myTableModel.fireTableDataChanged();
291 TableUtil.selectRows(myTable, rows);
294 myCbEncapsulateGet.addActionListener(checkboxListener);
295 myCbEncapsulateSet.addActionListener(checkboxListener);
296 myRbFieldAsIs.addItemListener(new ItemListener() {
297 public void itemStateChanged(ItemEvent e) {
298 myCbUseAccessorsWhenAccessible.setEnabled(!myRbFieldAsIs.isSelected());
302 myCbUseAccessorsWhenAccessible.setSelected(
303 JavaRefactoringSettings.getInstance().ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE
306 myRbFieldPrivate.setSelected(true);
307 myRbAccessorPublic.setSelected(true);
309 Box leftBox = Box.createVerticalBox();
310 myCbEncapsulateGet.setPreferredSize(myCbUseAccessorsWhenAccessible.getPreferredSize());
311 leftBox.add(myCbEncapsulateGet);
312 leftBox.add(myCbEncapsulateSet);
313 JPanel leftPanel = new JPanel(new BorderLayout());
314 leftPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("encapsulate.fields.encapsulate.border.title")));
315 leftPanel.add(leftBox, BorderLayout.CENTER);
316 leftPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST);
318 Box rightBox = Box.createVerticalBox();
319 rightBox.add(myCbUseAccessorsWhenAccessible);
320 JPanel rightPanel = new JPanel(new BorderLayout());
321 rightPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("encapsulate.fields.options.border.title")));
322 rightPanel.add(rightBox, BorderLayout.CENTER);
323 rightPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST);
325 Box encapsulateBox = Box.createHorizontalBox();
326 encapsulateBox.add(leftPanel);
327 encapsulateBox.add(Box.createHorizontalStrut(5));
328 encapsulateBox.add(rightPanel);
330 Box fieldsBox = Box.createVerticalBox();
331 fieldsBox.add(myRbFieldPrivate);
332 fieldsBox.add(myRbFieldPackageLocal);
333 fieldsBox.add(myRbFieldProtected);
334 fieldsBox.add(myRbFieldAsIs);
335 JPanel fieldsVisibilityPanel = new JPanel(new BorderLayout());
336 fieldsVisibilityPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("encapsulate.fields..encapsulated.fields.visibility.border.title")));
337 fieldsVisibilityPanel.add(fieldsBox, BorderLayout.CENTER);
338 fieldsVisibilityPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST);
340 Box methodsBox = Box.createVerticalBox();
341 methodsBox.add(myRbAccessorPublic);
342 methodsBox.add(myRbAccessorProtected);
343 methodsBox.add(myRbAccessorPackageLocal);
344 methodsBox.add(myRbAccessorPrivate);
345 JPanel methodsVisibilityPanel = new JPanel(new BorderLayout());
346 methodsVisibilityPanel.setBorder(IdeBorderFactory.createTitledBorder(RefactoringBundle.message("encapsulate.fields.accessors.visibility.border.title")));
347 methodsVisibilityPanel.add(methodsBox, BorderLayout.CENTER);
348 methodsVisibilityPanel.add(Box.createHorizontalStrut(5), BorderLayout.WEST);
350 Box visibilityBox = Box.createHorizontalBox();
351 visibilityBox.add(fieldsVisibilityPanel);
352 visibilityBox.add(Box.createHorizontalStrut(5));
353 visibilityBox.add(methodsVisibilityPanel);
355 Box box = Box.createVerticalBox();
356 box.add(encapsulateBox);
357 box.add(Box.createVerticalStrut(5));
358 box.add(visibilityBox);
360 JPanel boxPanel = new JPanel(new BorderLayout());
361 boxPanel.add(box, BorderLayout.CENTER);
362 boxPanel.add(Box.createVerticalStrut(5), BorderLayout.NORTH);
363 panel.add(boxPanel, BorderLayout.SOUTH);
365 return panel;
368 private JComponent createTable() {
369 myTableModel = new MyTableModel();
370 myTable = new Table(myTableModel);
371 myTable.setSurrendersFocusOnKeystroke(true);
372 MyTableRenderer renderer = new MyTableRenderer();
373 TableColumnModel columnModel = myTable.getColumnModel();
374 columnModel.getColumn(CHECKED_COLUMN).setCellRenderer(new BooleanTableCellRenderer());
375 columnModel.getColumn(FIELD_COLUMN).setCellRenderer(renderer);
376 columnModel.getColumn(GETTER_COLUMN).setCellRenderer(renderer);
377 columnModel.getColumn(SETTER_COLUMN).setCellRenderer(renderer);
378 columnModel.getColumn(CHECKED_COLUMN).setMaxWidth(new JCheckBox().getPreferredSize().width);
380 myTable.setPreferredScrollableViewportSize(new Dimension(550, myTable.getRowHeight() * 12));
381 myTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
383 JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
384 // JLabel label = new JLabel("Fields to Encapsulate");
385 // CompTitledBorder titledBorder = new CompTitledBorder(label);
386 Border titledBorder = IdeBorderFactory.createTitledBorder(RefactoringBundle.message("encapsulate.fields.fields.to.encapsulate.border.title"));
387 Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5);
388 Border border = BorderFactory.createCompoundBorder(titledBorder, emptyBorder);
389 scrollPane.setBorder(border);
390 // make ESC and ENTER work when focus is in the table
391 myTable.registerKeyboardAction(new ActionListener() {
392 public void actionPerformed(ActionEvent e) {
393 TableCellEditor editor = myTable.getCellEditor();
394 if (editor != null) {
395 editor.cancelCellEditing();
396 } else {
397 doCancelAction();
400 }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
402 // make SPACE check/uncheck selected rows
403 @NonNls InputMap inputMap = myTable.getInputMap();
404 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable");
405 @NonNls ActionMap actionMap = myTable.getActionMap();
406 actionMap.put("enable_disable", new AbstractAction() {
407 public void actionPerformed(ActionEvent e) {
408 if (myTable.isEditing()) return;
409 int[] rows = myTable.getSelectedRows();
410 if (rows.length > 0) {
411 boolean valueToBeSet = false;
412 for (int row : rows) {
413 if (!myCheckedMarks[row]) {
414 valueToBeSet = true;
415 break;
418 for (int row : rows) {
419 myCheckedMarks[row] = valueToBeSet;
421 myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]);
422 TableUtil.selectRows(myTable, rows);
427 // make ENTER work when the table has focus
428 inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "invokeImpl");
429 actionMap.put("invokeImpl", new AbstractAction() {
430 public void actionPerformed(ActionEvent e) {
431 TableCellEditor editor = myTable.getCellEditor();
432 if (editor != null) {
433 editor.stopCellEditing();
434 } else {
435 clickDefaultButton();
440 return scrollPane;
443 public JComponent getPreferredFocusedComponent() {
444 return myTable;
447 protected void doAction() {
448 if (myTable.isEditing()) {
449 TableCellEditor editor = myTable.getCellEditor();
450 if (editor != null) {
451 editor.stopCellEditing();
454 String errorString = validateData();
455 if (errorString != null) { // were errors
456 CommonRefactoringUtil.showErrorMessage(REFACTORING_NAME, errorString, HelpID.ENCAPSULATE_FIELDS, myProject);
457 return;
460 if (getCheckedRows().length == 0) {
461 CommonRefactoringUtil.showErrorMessage(REFACTORING_NAME, "Nothing found to encapsulate", HelpID.ENCAPSULATE_FIELDS, myProject);
462 return;
465 invokeRefactoring(new EncapsulateFieldsProcessor(myProject, this));
466 JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance();
467 settings.ENCAPSULATE_FIELDS_USE_ACCESSORS_WHEN_ACCESSIBLE = myCbUseAccessorsWhenAccessible.isSelected();
471 * @return error string if errors were found, or null if everything is ok
473 private String validateData() {
474 PsiManager manager = PsiManager.getInstance(myProject);
475 for (int idx = 0; idx < myFields.length; idx++) {
476 if (myCheckedMarks[idx]) {
477 String name;
478 if (isToEncapsulateGet()) {
479 name = myGetterNames[idx];
480 if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
481 return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
484 if (!myFinalMarks[idx] && isToEncapsulateSet()) {
485 name = mySetterNames[idx];
486 if (!JavaPsiFacade.getInstance(manager.getProject()).getNameHelper().isIdentifier(name)) {
487 return RefactoringMessageUtil.getIncorrectIdentifierMessage(name);
492 return null;
495 @Override
496 protected boolean areButtonsValid() {
497 return getCheckedRows().length > 0;
500 private PsiMethod generateMethodPrototype(PsiField field, String methodName, boolean isGetter) {
501 PsiMethod prototype = isGetter
502 ? PropertyUtil.generateGetterPrototype(field)
503 : PropertyUtil.generateSetterPrototype(field);
504 try {
505 PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();
506 PsiIdentifier identifier = factory.createIdentifier(methodName);
507 prototype.getNameIdentifier().replace(identifier);
508 //prototype.getModifierList().setModifierProperty(getAccessorsVisibility(), true);
509 return prototype;
510 } catch (IncorrectOperationException e) {
511 return null;
515 private int[] getCheckedRows() {
516 int count = 0;
517 for (boolean checkedMark : myCheckedMarks) {
518 if (checkedMark) {
519 count++;
522 int[] rows = new int[count];
523 int currentRow = 0;
524 for (int idx = 0; idx < myCheckedMarks.length; idx++) {
525 if (myCheckedMarks[idx]) {
526 rows[currentRow++] = idx;
529 return rows;
532 protected void doHelpAction() {
533 HelpManager.getInstance().invokeHelp(HelpID.ENCAPSULATE_FIELDS);
536 private class MyTableModel extends AbstractTableModel {
537 public int getColumnCount() {
538 return 4;
541 public int getRowCount() {
542 return myFields.length;
545 public Class getColumnClass(int columnIndex) {
546 if (columnIndex == CHECKED_COLUMN) {
547 return Boolean.class;
549 return super.getColumnClass(columnIndex);
552 public Object getValueAt(int rowIndex, int columnIndex) {
553 switch (columnIndex) {
554 case CHECKED_COLUMN:
555 return myCheckedMarks[rowIndex] ? Boolean.TRUE : Boolean.FALSE;
556 case FIELD_COLUMN:
557 return myFieldNames[rowIndex];
558 case GETTER_COLUMN:
559 return myGetterNames[rowIndex];
560 case SETTER_COLUMN:
561 return mySetterNames[rowIndex];
562 default:
563 throw new RuntimeException("Incorrect column index");
567 public String getColumnName(int column) {
568 switch (column) {
569 case CHECKED_COLUMN:
570 return " ";
571 case FIELD_COLUMN:
572 return RefactoringBundle.message("encapsulate.fields.field.column.name");
573 case GETTER_COLUMN:
574 return RefactoringBundle.message("encapsulate.fields.getter.column.name");
575 case SETTER_COLUMN:
576 return RefactoringBundle.message("encapsulate.fields.setter.column.name");
577 default:
578 throw new RuntimeException("Incorrect column index");
582 public boolean isCellEditable(int rowIndex, int columnIndex) {
583 if (columnIndex == CHECKED_COLUMN) return true;
584 if (myCheckedMarks[rowIndex]) {
585 if (columnIndex == GETTER_COLUMN && myCbEncapsulateGet.isSelected()) return true;
586 if (columnIndex == SETTER_COLUMN) {
587 if (!myFinalMarks[rowIndex] && myCbEncapsulateSet.isSelected()) return true;
590 return false;
593 public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) {
594 if (columnIndex == CHECKED_COLUMN) {
595 myCheckedMarks[rowIndex] = ((Boolean) aValue).booleanValue();
596 fireTableRowsUpdated(rowIndex, rowIndex);
597 } else {
598 String name = (String) aValue;
599 PsiField field = myFields[rowIndex];
600 switch (columnIndex) {
601 case GETTER_COLUMN:
602 myGetterNames[rowIndex] = name;
603 myGetterPrototypes[rowIndex] = generateMethodPrototype(field, name, true);
604 break;
606 case SETTER_COLUMN:
607 mySetterNames[rowIndex] = name;
608 mySetterPrototypes[rowIndex] = generateMethodPrototype(field, name, false);
609 break;
611 default:
612 throw new RuntimeException("Incorrect column index");
618 private static final Icon OVERRIDING_METHOD_ICON = IconLoader.getIcon("/general/overridingMethod.png");
619 private static final Icon IMPLEMENTING_METHOD_ICON = IconLoader.getIcon("/general/implementingMethod.png");
620 private static final Icon EMPTY_OVERRIDE_ICON = new EmptyIcon(16, 16);
622 private class MyTableRenderer extends DefaultTableCellRenderer {
623 public Component getTableCellRendererComponent(JTable table, final Object value,
624 boolean isSelected, boolean hasFocus, final int row,
625 final int column) {
626 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
627 final int modelColumn = myTable.convertColumnIndexToModel(column);
629 this.setIconTextGap(0);
630 PsiField field = myFields[row];
631 switch (modelColumn) {
632 case FIELD_COLUMN:
634 Icon icon = field.getIcon(Iconable.ICON_FLAG_VISIBILITY);
635 MyTableRenderer.this.setIcon(icon);
636 MyTableRenderer.this.setDisabledIcon(icon);
637 configureColors(isSelected, table, hasFocus, row, column);
638 break;
641 case GETTER_COLUMN:
642 case SETTER_COLUMN:
644 Icon methodIcon = IconUtil.getEmptyIcon(true);
645 Icon overrideIcon = EMPTY_OVERRIDE_ICON;
647 PsiMethod prototype = modelColumn == GETTER_COLUMN ? myGetterPrototypes[row] : mySetterPrototypes[row];
648 if (prototype != null) {
649 // MyTableRenderer.this.setForeground(Color.black);
650 configureColors(isSelected, table, hasFocus, row, column);
652 PsiMethod existing = myClass.findMethodBySignature(prototype, false);
653 if (existing != null) {
654 methodIcon = existing.getIcon(Iconable.ICON_FLAG_VISIBILITY);
657 PsiMethod[] superMethods = prototype.findSuperMethods(myClass);
658 if (superMethods.length > 0) {
659 if (!superMethods[0].hasModifierProperty(PsiModifier.ABSTRACT)) {
660 overrideIcon = OVERRIDING_METHOD_ICON;
661 } else {
662 overrideIcon = IMPLEMENTING_METHOD_ICON;
665 } else {
666 MyTableRenderer.this.setForeground(Color.red);
669 RowIcon icon = new RowIcon(2);
670 icon.setIcon(methodIcon, 0);
671 icon.setIcon(overrideIcon, 1);
672 MyTableRenderer.this.setIcon(icon);
673 MyTableRenderer.this.setDisabledIcon(icon);
674 break;
677 default:
679 MyTableRenderer.this.setIcon(null);
680 MyTableRenderer.this.setDisabledIcon(null);
683 boolean enabled = myCheckedMarks[row];
684 if (enabled) {
685 if (modelColumn == GETTER_COLUMN) {
686 enabled = myCbEncapsulateGet.isSelected();
687 } else if (modelColumn == SETTER_COLUMN) {
688 enabled = !myFinalMarks[row] && myCbEncapsulateSet.isSelected();
691 this.setEnabled(enabled);
692 return this;
695 private void configureColors(boolean isSelected, JTable table, boolean hasFocus, final int row, final int column) {
696 if (isSelected) {
697 setForeground(table.getSelectionForeground());
698 } else {
699 setForeground(UIUtil.getTableForeground());
702 if (hasFocus) {
703 if (table.isCellEditable(row, column)) {
704 super.setForeground(UIUtil.getTableFocusCellForeground());
705 super.setBackground(UIUtil.getTableFocusCellBackground());