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
.compiler
.options
;
18 import com
.intellij
.openapi
.module
.Module
;
19 import com
.intellij
.openapi
.util
.io
.FileUtil
;
20 import com
.intellij
.ui
.ScrollPaneFactory
;
21 import com
.intellij
.ui
.SpeedSearchBase
;
22 import com
.intellij
.ui
.TableUtil
;
23 import com
.intellij
.util
.ui
.Table
;
24 import com
.intellij
.util
.ui
.UIUtil
;
25 import org
.jetbrains
.annotations
.Nullable
;
28 import javax
.swing
.table
.*;
30 import java
.awt
.event
.ActionEvent
;
31 import java
.awt
.event
.ActionListener
;
32 import java
.awt
.event
.KeyEvent
;
34 import java
.util
.List
;
36 public class ProcessedModulesChooser
extends JPanel
{
37 private Table myTable
= null;
38 private MyTableModel myTableModel
= null;
39 private boolean myColorUnmarkedElements
= true;
40 private final Map
<Module
, Boolean
> myDisabledMap
= new HashMap
<Module
, Boolean
>();
42 public ProcessedModulesChooser() {
43 super(new BorderLayout());
45 myTableModel
= new MyTableModel(true);
46 myTable
= new Table(myTableModel
);
47 myTable
.setShowGrid(false);
48 myTable
.setIntercellSpacing(new Dimension(0, 0));
49 myTable
.setTableHeader(null);
50 myTable
.setAutoResizeMode(JTable
.AUTO_RESIZE_LAST_COLUMN
);
51 myTable
.setColumnSelectionAllowed(false);
52 JScrollPane pane
= ScrollPaneFactory
.createScrollPane(myTable
);
53 pane
.setPreferredSize(new Dimension(100, 155));
54 int width
= new JCheckBox().getPreferredSize().width
;
55 TableColumnModel columnModel
= myTable
.getColumnModel();
57 TableColumn checkMarkColumn
= columnModel
.getColumn(myTableModel
.CHECK_MARK_COLUM_INDEX
);
58 checkMarkColumn
.setPreferredWidth(width
);
59 checkMarkColumn
.setMaxWidth(width
);
60 checkMarkColumn
.setCellRenderer(new CheckMarkColumnCellRenderer(myTable
.getDefaultRenderer(Boolean
.class)));
61 columnModel
.getColumn(myTableModel
.ELEMENT_COLUMN_INDEX
).setCellRenderer(new MyElementColumnCellRenderer());
63 add(pane
, BorderLayout
.CENTER
);
64 myTable
.registerKeyboardAction(
65 new ActionListener() {
66 public void actionPerformed(ActionEvent e
) {
67 final int[] selectedRows
= myTable
.getSelectedRows();
68 boolean currentlyMarked
= true;
69 for (int selectedRow
: selectedRows
) {
70 currentlyMarked
= myTableModel
.isElementMarked(selectedRow
);
71 if (!currentlyMarked
) {
75 myTableModel
.setMarked(selectedRows
, !currentlyMarked
);
78 KeyStroke
.getKeyStroke(KeyEvent
.VK_SPACE
, 0),
79 JComponent
.WHEN_FOCUSED
82 final SpeedSearchBase
<Table
> speedSearch
= new SpeedSearchBase
<Table
>(myTable
) {
83 public int getSelectedIndex() {
84 return myTable
.getSelectedRow();
87 public Object
[] getAllElements() {
88 final int count
= myTableModel
.getRowCount();
89 Object
[] elements
= new Object
[count
];
90 for (int idx
= 0; idx
< count
; idx
++) {
91 elements
[idx
] = myTableModel
.getElementAt(idx
);
96 public String
getElementText(Object element
) {
97 return ((Module
)element
).getName() + " (" + FileUtil
.toSystemDependentName(((Module
)element
).getModuleFilePath()) + ")";
100 public void selectElement(Object element
, String selectedText
) {
101 final int count
= myTableModel
.getRowCount();
102 for (int row
= 0; row
< count
; row
++) {
103 if (element
.equals(myTableModel
.getElementAt(row
))) {
104 myTable
.getSelectionModel().setSelectionInterval(row
, row
);
105 TableUtil
.scrollSelectionToVisible(myTable
);
111 speedSearch
.setComparator(new SpeedSearchBase
.SpeedSearchComparator(false));
114 public void refresh() {
115 myTableModel
.fireTableDataChanged();
118 public void refresh(Module element
) {
119 final int row
= myTableModel
.getElementRow(element
);
121 myTableModel
.fireTableRowsUpdated(row
, row
);
125 private int[] mySavedSelection
= null;
126 public void saveSelection() {
127 mySavedSelection
= myTable
.getSelectedRows();
130 public void restoreSelection() {
131 if (mySavedSelection
!= null) {
132 TableUtil
.selectRows(myTable
, mySavedSelection
);
133 mySavedSelection
= null;
137 public void addElement(Module element
, final boolean isMarked
) {
138 myTableModel
.addElement(element
, isMarked
);
139 selectRow(myTableModel
.getRowCount() - 1);
140 myTable
.requestFocus();
143 public boolean isElementMarked(Module element
) {
144 final int elementRow
= myTableModel
.getElementRow(element
);
145 return myTableModel
.isElementMarked(elementRow
);
148 public void setElementMarked(Module element
, boolean marked
) {
149 final int elementRow
= myTableModel
.getElementRow(element
);
150 myTableModel
.setMarked(elementRow
, marked
);
154 public void removeElement(Module element
) {
155 final int elementRow
= myTableModel
.getElementRow(element
);
156 if (elementRow
< 0) {
157 return; // no such element
159 final boolean wasSelected
= myTable
.getSelectionModel().isSelectedIndex(elementRow
);
161 myTableModel
.removeElement(element
);
164 final int rowCount
= myTableModel
.getRowCount();
166 selectRow(elementRow
% rowCount
);
169 myTable
.getSelectionModel().clearSelection();
172 myTable
.requestFocus();
175 public void removeAllElements() {
176 myTableModel
.removeAllElements();
177 myTable
.getSelectionModel().clearSelection();
180 private void selectRow(final int row
) {
181 myTable
.getSelectionModel().setSelectionInterval(row
, row
);
182 myTable
.scrollRectToVisible(myTable
.getCellRect(row
, 0, true));
186 public Module
getSelectedElement() {
187 final int selectedRow
= getSelectedElementRow();
188 return selectedRow
< 0?
null : myTableModel
.getElementAt(selectedRow
);
191 public int getSelectedElementRow() {
192 return myTable
.getSelectedRow();
195 public List
<Module
> getSelectedElements() {
196 final List
<Module
> elements
= new ArrayList
<Module
>();
197 final int[] selectedRows
= myTable
.getSelectedRows();
198 for (int selectedRow
: selectedRows
) {
199 if (selectedRow
< 0) {
202 elements
.add(myTableModel
.getElementAt(selectedRow
));
207 public void selectElements(Collection
<?
extends Module
> elements
) {
208 if (elements
.size() == 0) {
209 myTable
.clearSelection();
212 final int[] rows
= getElementsRows(elements
);
213 TableUtil
.selectRows(myTable
, rows
);
214 TableUtil
.scrollSelectionToVisible(myTable
);
215 myTable
.requestFocus();
218 private int[] getElementsRows(final Collection
<?
extends Module
> elements
) {
219 final int[] rows
= new int[elements
.size()];
221 for (final Module element
: elements
) {
222 rows
[index
++] = myTableModel
.getElementRow(element
);
227 public void markElements(Collection
<Module
> elements
) {
228 myTableModel
.setMarked(getElementsRows(elements
), true);
231 public List
<Module
> getMarkedElements() {
232 final int count
= myTableModel
.getRowCount();
233 List
<Module
> elements
= new ArrayList
<Module
>();
234 for (int idx
= 0; idx
< count
; idx
++) {
235 final Module element
= myTableModel
.getElementAt(idx
);
236 if (myTableModel
.isElementMarked(idx
)) {
237 elements
.add(element
);
243 public void sort(Comparator
<Module
> comparator
) {
244 myTableModel
.sort(comparator
);
247 public void setEnabled(boolean enabled
) {
248 super.setEnabled(enabled
);
249 myTable
.setRowSelectionAllowed(enabled
);
250 myTableModel
.fireTableDataChanged();
253 public void stopEditing() {
254 TableCellEditor editor
= myTable
.getCellEditor();
255 if (editor
!= null) {
256 editor
.stopCellEditing();
260 public JComponent
getComponent() {
264 public void clear() {
265 myTableModel
.clear();
268 public int getElementCount() {
269 return myTableModel
.getRowCount();
272 public Module
getElementAt(int row
) {
273 return myTableModel
.getElementAt(row
);
276 public void disableElement(Module element
) {
277 myDisabledMap
.put(element
, Boolean
.TRUE
);
280 private final class MyTableModel
extends AbstractTableModel
{
281 private final List
<Module
> myElements
= new ArrayList
<Module
>();
282 private final Map
<Module
, Boolean
> myMarkedMap
= new HashMap
<Module
, Boolean
>();
283 public final int CHECK_MARK_COLUM_INDEX
;
284 public final int ELEMENT_COLUMN_INDEX
;
285 private final boolean myElementsCanBeMarked
;
287 public MyTableModel(final boolean elementsCanBeMarked
) {
288 myElementsCanBeMarked
= elementsCanBeMarked
;
289 if (elementsCanBeMarked
) {
290 CHECK_MARK_COLUM_INDEX
= 0;
291 ELEMENT_COLUMN_INDEX
= 1;
294 CHECK_MARK_COLUM_INDEX
= -1;
295 ELEMENT_COLUMN_INDEX
= 0;
299 public void sort(Comparator
<Module
> comparator
) {
300 Collections
.sort(myElements
, comparator
);
301 fireTableDataChanged();
304 public Module
getElementAt(int index
) {
305 return myElements
.get(index
);
308 public boolean isElementMarked(int index
) {
309 final Module element
= myElements
.get(index
);
310 final Boolean isMarked
= myMarkedMap
.get(element
);
311 return isMarked
.booleanValue();
314 void addElement(Module element
, boolean isMarked
) {
315 myElements
.add(element
);
316 myMarkedMap
.put(element
, isMarked? Boolean
.TRUE
: Boolean
.FALSE
);
317 int row
= myElements
.size() - 1;
318 fireTableRowsInserted(row
, row
);
321 void addElements(List
<Module
> elements
, boolean isMarked
) {
322 if (elements
== null || elements
.size() == 0) {
325 for (final Module element
: elements
) {
326 myElements
.add(element
);
327 myMarkedMap
.put(element
, isMarked ? Boolean
.TRUE
: Boolean
.FALSE
);
329 fireTableRowsInserted(myElements
.size() - elements
.size(), myElements
.size() - 1);
332 public void removeElement(Module element
) {
333 final boolean reallyRemoved
= myElements
.remove(element
);
335 myMarkedMap
.remove(element
);
336 fireTableDataChanged();
340 public void changeElementRow(Module element
, int row
) {
341 final boolean reallyRemoved
= myElements
.remove(element
);
343 myElements
.add(row
, element
);
344 fireTableDataChanged();
348 public int getElementRow(Module element
) {
349 return myElements
.indexOf(element
);
352 public void removeAllElements() {
354 fireTableDataChanged();
357 public void removeRows(int[] rows
) {
358 final List
<Module
> toRemove
= new ArrayList
<Module
>();
359 for (int row
: rows
) {
360 final Module element
= myElements
.get(row
);
361 toRemove
.add(element
);
362 myMarkedMap
.remove(element
);
364 myElements
.removeAll(toRemove
);
365 fireTableDataChanged();
368 public int getRowCount() {
369 return myElements
.size();
372 public int getColumnCount() {
373 return myElementsCanBeMarked?
2 : 1;
377 public Object
getValueAt(int rowIndex
, int columnIndex
) {
378 Module element
= myElements
.get(rowIndex
);
379 if (columnIndex
== ELEMENT_COLUMN_INDEX
) {
382 if (columnIndex
== CHECK_MARK_COLUM_INDEX
) {
383 return myMarkedMap
.get(element
);
388 public void setValueAt(Object aValue
, int rowIndex
, int columnIndex
) {
389 if (columnIndex
== CHECK_MARK_COLUM_INDEX
) {
390 setMarked(rowIndex
, ((Boolean
)aValue
).booleanValue());
394 private void setMarked(int rowIndex
, final boolean marked
) {
395 final Module element
= myElements
.get(rowIndex
);
396 final Boolean newValue
= marked? Boolean
.TRUE
: Boolean
.FALSE
;
397 myMarkedMap
.put(element
, newValue
);
398 fireTableRowsUpdated(rowIndex
, rowIndex
);
401 private void setMarked(int[] rows
, final boolean marked
) {
402 if (rows
== null || rows
.length
== 0) {
405 int firstRow
= Integer
.MAX_VALUE
;
406 int lastRow
= Integer
.MIN_VALUE
;
407 final Boolean newValue
= marked? Boolean
.TRUE
: Boolean
.FALSE
;
408 for (final int row
: rows
) {
409 final Module element
= myElements
.get(row
);
410 myMarkedMap
.put(element
, newValue
);
411 firstRow
= Math
.min(firstRow
, row
);
412 lastRow
= Math
.max(lastRow
, row
);
414 fireTableRowsUpdated(firstRow
, lastRow
);
417 public Class
getColumnClass(int columnIndex
) {
418 if (columnIndex
== CHECK_MARK_COLUM_INDEX
) {
419 return Boolean
.class;
421 return super.getColumnClass(columnIndex
);
424 public boolean isCellEditable(int rowIndex
, int columnIndex
) {
425 if (!ProcessedModulesChooser
.this.isEnabled() || columnIndex
!= CHECK_MARK_COLUM_INDEX
) {
428 final Module o
= (Module
)getValueAt(rowIndex
, ELEMENT_COLUMN_INDEX
);
429 return myDisabledMap
.get(o
) == null;
432 public void clear() {
435 fireTableDataChanged();
439 private class MyElementColumnCellRenderer
extends DefaultTableCellRenderer
{
440 public Component
getTableCellRendererComponent(JTable table
, Object value
, boolean isSelected
, boolean hasFocus
, int row
, int column
) {
441 final Color color
= UIUtil
.getTableFocusCellBackground();
443 Module module
= (Module
)value
;
445 UIManager
.put(UIUtil
.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY
, table
.getSelectionBackground());
446 component
= super.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
, row
, column
);
447 setText(module
!= null ? module
.getName() + " (" + FileUtil
.toSystemDependentName(module
.getModuleFilePath()) + ")" : "");
448 if (component
instanceof JLabel
) {
449 ((JLabel
)component
).setBorder(noFocusBorder
);
453 UIManager
.put(UIUtil
.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY
, color
);
455 final MyTableModel model
= (MyTableModel
)table
.getModel();
456 component
.setEnabled(ProcessedModulesChooser
.this.isEnabled() && (myColorUnmarkedElements? model
.isElementMarked(row
) : true));
457 if (component
instanceof JLabel
) {
458 final Icon icon
= module
!= null ? module
.getModuleType().getNodeIcon(false) : null;
459 JLabel label
= (JLabel
)component
;
461 label
.setDisabledIcon(icon
);
463 component
.setForeground(isSelected ? table
.getSelectionForeground() : table
.getForeground());
468 private class CheckMarkColumnCellRenderer
implements TableCellRenderer
{
469 private final TableCellRenderer myDelegate
;
471 public CheckMarkColumnCellRenderer(TableCellRenderer delegate
) {
472 myDelegate
= delegate
;
475 public Component
getTableCellRendererComponent(JTable table
, Object value
, boolean isSelected
, boolean hasFocus
, int row
, int column
) {
476 Component component
= myDelegate
.getTableCellRendererComponent(table
, value
, isSelected
, hasFocus
, row
, column
);
477 component
.setEnabled(ProcessedModulesChooser
.this.isEnabled());
478 if (component
instanceof JComponent
) {
479 ((JComponent
)component
).setBorder(null);