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.
18 * Class ClassFilterEditor
21 package com
.intellij
.ui
.classFilter
;
23 import com
.intellij
.ide
.util
.TreeClassChooser
;
24 import com
.intellij
.ide
.util
.TreeClassChooserFactory
;
25 import com
.intellij
.openapi
.project
.Project
;
26 import com
.intellij
.psi
.PsiClass
;
27 import com
.intellij
.psi
.search
.GlobalSearchScope
;
28 import com
.intellij
.psi
.util
.PsiTreeUtil
;
29 import com
.intellij
.ui
.ScrollPaneFactory
;
30 import com
.intellij
.ui
.TableUtil
;
31 import com
.intellij
.ui
.UIBundle
;
32 import com
.intellij
.util
.ui
.ItemRemovable
;
33 import com
.intellij
.util
.ui
.Table
;
34 import com
.intellij
.util
.ui
.UIUtil
;
35 import org
.jetbrains
.annotations
.NotNull
;
36 import org
.jetbrains
.annotations
.Nullable
;
39 import javax
.swing
.event
.ListSelectionEvent
;
40 import javax
.swing
.event
.ListSelectionListener
;
41 import javax
.swing
.table
.*;
43 import java
.awt
.event
.ActionEvent
;
44 import java
.awt
.event
.ActionListener
;
45 import java
.awt
.event
.KeyEvent
;
46 import java
.util
.Arrays
;
47 import java
.util
.Iterator
;
48 import java
.util
.LinkedList
;
49 import java
.util
.List
;
51 public class ClassFilterEditor
extends JPanel
{
52 protected JTable myTable
= null;
53 protected FilterTableModel myTableModel
= null;
54 private JButton myAddClassButton
;
55 protected JButton myAddPatternButton
;
56 private JButton myRemoveButton
;
57 protected Project myProject
;
58 private TreeClassChooser
.ClassFilter myChooserFilter
;
60 public ClassFilterEditor(Project project
) {
64 public ClassFilterEditor(Project project
, TreeClassChooser
.ClassFilter classFilter
) {
65 super(new GridBagLayout());
66 myAddClassButton
= new JButton(getAddButtonText());
67 myAddPatternButton
= new JButton(getAddPatternButtonText());
68 myRemoveButton
= new JButton(UIBundle
.message("button.remove"));
69 myTable
= new Table();
70 JScrollPane scrollPane
= ScrollPaneFactory
.createScrollPane(myTable
);
72 add(scrollPane
, new GridBagConstraints(0, GridBagConstraints
.RELATIVE
, 1, 3, 1.0, 1.0, GridBagConstraints
.CENTER
, GridBagConstraints
.BOTH
, new Insets(4, 4, 4, 6), 0, 0));
73 add(myAddClassButton
, new GridBagConstraints(1, GridBagConstraints
.RELATIVE
, 1, 1, 0.0, 0.0, GridBagConstraints
.NORTHWEST
, GridBagConstraints
.HORIZONTAL
, new Insets(4, 0, 0, 4), 0, 0));
74 add(myAddPatternButton
, new GridBagConstraints(1, GridBagConstraints
.RELATIVE
, 1, 1, 0.0, 0.0, GridBagConstraints
.NORTHWEST
, GridBagConstraints
.HORIZONTAL
, new Insets(4, 0, 0, 4), 0, 0));
75 add(myRemoveButton
, new GridBagConstraints(1, GridBagConstraints
.RELATIVE
, 1, 1, 0.0, 1.0, GridBagConstraints
.NORTHWEST
, GridBagConstraints
.HORIZONTAL
, new Insets(4, 0, 0, 4), 0, 0));
77 myChooserFilter
= classFilter
;
79 myAddClassButton
.setDefaultCapable(false);
80 myAddPatternButton
.setDefaultCapable(false);
81 myRemoveButton
.setDefaultCapable(false);
83 myTableModel
= new FilterTableModel();
84 myTable
.setModel(myTableModel
);
85 myTable
.setShowGrid(false);
86 myTable
.setIntercellSpacing(new Dimension(0, 0));
87 myTable
.setTableHeader(null);
88 myTable
.setAutoResizeMode(JTable
.AUTO_RESIZE_LAST_COLUMN
);
89 myTable
.setColumnSelectionAllowed(false);
90 myTable
.setPreferredScrollableViewportSize(new Dimension(200, 100));
92 TableColumnModel columnModel
= myTable
.getColumnModel();
93 TableColumn column
= columnModel
.getColumn(FilterTableModel
.CHECK_MARK
);
94 int width
= new JCheckBox().getPreferredSize().width
;
95 column
.setPreferredWidth(width
);
96 column
.setMaxWidth(width
);
97 column
.setCellRenderer(new EnabledCellRenderer(myTable
.getDefaultRenderer(Boolean
.class)));
98 columnModel
.getColumn(FilterTableModel
.FILTER
).setCellRenderer(new FilterCellRenderer());
100 myTable
.registerKeyboardAction(
101 new ActionListener() {
102 public void actionPerformed(ActionEvent e
) {
103 myAddClassButton
.doClick();
106 KeyStroke
.getKeyStroke(KeyEvent
.VK_INSERT
, 0),
107 JComponent
.WHEN_FOCUSED
109 myTable
.registerKeyboardAction(
110 new ActionListener() {
111 public void actionPerformed(ActionEvent e
) {
112 myRemoveButton
.doClick();
115 KeyStroke
.getKeyStroke(KeyEvent
.VK_DELETE
, 0),
116 JComponent
.WHEN_FOCUSED
118 myTable
.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
119 public void valueChanged(ListSelectionEvent e
) {
120 myRemoveButton
.setEnabled(myTable
.getSelectedRow() > -1);
124 myAddPatternButton
.addActionListener(new ActionListener() {
125 public void actionPerformed(ActionEvent e
) {
129 myAddClassButton
.addActionListener(new ActionListener() {
130 public void actionPerformed(ActionEvent e
) {
135 myRemoveButton
.addActionListener(new RemoveAction());
136 myRemoveButton
.setEnabled(false);
139 protected String
getAddButtonText() {
140 return UIBundle
.message("button.add.class");
143 protected String
getAddPatternButtonText() {
144 return UIBundle
.message("button.add.pattern");
147 public void setFilters(ClassFilter
[] filters
) {
148 myTableModel
.setFilters(filters
);
151 public ClassFilter
[] getFilters() {
152 return myTableModel
.getFilters();
155 public void setEnabled(boolean enabled
) {
156 super.setEnabled(enabled
);
158 myAddPatternButton
.setEnabled(enabled
);
159 myAddClassButton
.setEnabled(enabled
);
160 myRemoveButton
.setEnabled((myTable
.getSelectedRow() > -1) && enabled
);
161 myTable
.setRowSelectionAllowed(enabled
);
162 myTableModel
.fireTableDataChanged();
165 public void stopEditing() {
166 TableCellEditor editor
= myTable
.getCellEditor();
167 if (editor
!= null) {
168 editor
.stopCellEditing();
172 protected final class FilterTableModel
extends AbstractTableModel
implements ItemRemovable
{
173 private final List
<ClassFilter
> myFilters
= new LinkedList
<ClassFilter
>();
174 public static final int CHECK_MARK
= 0;
175 public static final int FILTER
= 1;
177 public final void setFilters(ClassFilter
[] filters
) {
179 if (filters
!= null) {
180 myFilters
.addAll(Arrays
.asList(filters
));
182 fireTableDataChanged();
185 public ClassFilter
[] getFilters() {
186 for (Iterator
<ClassFilter
> it
= myFilters
.iterator(); it
.hasNext();) {
187 ClassFilter filter
= it
.next();
188 String pattern
= filter
.getPattern();
189 if (pattern
== null || "".equals(pattern
)) {
193 return myFilters
.toArray(new ClassFilter
[myFilters
.size()]);
196 public ClassFilter
getFilterAt(int index
) {
197 return myFilters
.get(index
);
200 public int getFilterIndex(ClassFilter filter
) {
201 return myFilters
.indexOf(filter
);
204 public void addRow(ClassFilter filter
) {
205 myFilters
.add(filter
);
206 int row
= myFilters
.size() - 1;
207 fireTableRowsInserted(row
, row
);
210 public int getRowCount() {
211 return myFilters
.size();
214 public int getColumnCount() {
218 public Object
getValueAt(int rowIndex
, int columnIndex
) {
219 ClassFilter filter
= myFilters
.get(rowIndex
);
220 if (columnIndex
== FILTER
) {
223 if (columnIndex
== CHECK_MARK
) {
224 return filter
.isEnabled()? Boolean
.TRUE
: Boolean
.FALSE
;
229 public void setValueAt(Object aValue
, int rowIndex
, int columnIndex
) {
230 ClassFilter filter
= myFilters
.get(rowIndex
);
231 if (columnIndex
== FILTER
) {
232 filter
.setPattern(aValue
!= null? aValue
.toString() : "");
234 else if (columnIndex
== CHECK_MARK
) {
235 filter
.setEnabled(aValue
== null || ((Boolean
)aValue
).booleanValue());
237 // fireTableCellUpdated(rowIndex, columnIndex);
238 fireTableRowsUpdated(rowIndex
, rowIndex
);
241 public Class
getColumnClass(int columnIndex
) {
242 if (columnIndex
== CHECK_MARK
) {
243 return Boolean
.class;
245 return super.getColumnClass(columnIndex
);
248 public boolean isCellEditable(int rowIndex
, int columnIndex
) {
249 return isEnabled() && (columnIndex
== CHECK_MARK
);
252 public void removeRow(final int idx
) {
253 myFilters
.remove(idx
);
254 fireTableDataChanged();
258 private class FilterCellRenderer
extends DefaultTableCellRenderer
{
259 public Component
getTableCellRendererComponent(JTable table
, Object value
,
260 boolean isSelected
, boolean hasFocus
, int row
, int column
) {
261 Color color
= UIUtil
.getTableFocusCellBackground();
262 UIManager
.put(UIUtil
.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY
, table
.getSelectionBackground());
263 Component component
= super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
, row
, column
);
264 if (component
instanceof JLabel
) {
265 ((JLabel
)component
).setBorder(noFocusBorder
);
267 UIManager
.put(UIUtil
.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY
, color
);
268 ClassFilter filter
= (ClassFilter
)table
.getValueAt(row
, FilterTableModel
.FILTER
);
269 component
.setEnabled(ClassFilterEditor
.this.isEnabled() && filter
.isEnabled());
274 private class EnabledCellRenderer
extends DefaultTableCellRenderer
{
275 private final TableCellRenderer myDelegate
;
277 public EnabledCellRenderer(TableCellRenderer delegate
) {
278 myDelegate
= delegate
;
281 public Component
getTableCellRendererComponent(JTable table
, Object value
,
282 boolean isSelected
, boolean hasFocus
, int row
, int column
) {
283 Component component
= myDelegate
.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
, row
, column
);
284 component
.setEnabled(ClassFilterEditor
.this.isEnabled());
290 protected ClassFilter
createFilter(String pattern
){
291 return new ClassFilter(pattern
);
294 protected void addPatternFilter() {
295 ClassFilterEditorAddDialog dialog
= new ClassFilterEditorAddDialog(myProject
);
298 String pattern
= dialog
.getPattern();
299 if (pattern
!= null) {
300 ClassFilter filter
= createFilter(pattern
);
301 myTableModel
.addRow(filter
);
302 int row
= myTableModel
.getRowCount() - 1;
303 myTable
.getSelectionModel().setSelectionInterval(row
, row
);
304 myTable
.scrollRectToVisible(myTable
.getCellRect(row
, 0, true));
306 myTable
.requestFocus();
311 protected void addClassFilter() {
312 TreeClassChooser chooser
= TreeClassChooserFactory
.getInstance(myProject
).createNoInnerClassesScopeChooser(
313 UIBundle
.message("class.filter.editor.choose.class.title"), GlobalSearchScope
.allScope(myProject
), myChooserFilter
, null);
314 chooser
.showDialog();
315 PsiClass selectedClass
= chooser
.getSelectedClass();
316 if (selectedClass
!= null) {
317 ClassFilter filter
= createFilter(getJvmClassName(selectedClass
));
318 myTableModel
.addRow(filter
);
319 int row
= myTableModel
.getRowCount() - 1;
320 myTable
.getSelectionModel().setSelectionInterval(row
, row
);
321 myTable
.scrollRectToVisible(myTable
.getCellRect(row
, 0, true));
323 myTable
.requestFocus();
328 private static String
getJvmClassName(PsiClass aClass
) {
329 PsiClass parentClass
= PsiTreeUtil
.getParentOfType(aClass
, PsiClass
.class, true);
330 if(parentClass
!= null) {
331 final String parentName
= getJvmClassName(parentClass
);
332 if (parentName
== null) {
335 return parentName
+ "$" + aClass
.getName();
337 return aClass
.getQualifiedName();
340 public void addPattern(String pattern
) {
341 ClassFilter filter
= createFilter(pattern
);
342 myTableModel
.addRow(filter
);
345 private final class RemoveAction
implements ActionListener
{
346 public void actionPerformed(ActionEvent e
) {
347 TableUtil
.removeSelectedItems(myTable
);