28491c21fc2dd63d9f13cd30e3487b511d529aac
[idea/community.git] / platform / lang-api / src / com / intellij / execution / util / ListTableWithButtons.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.execution.util;
17
18 import com.intellij.openapi.actionSystem.AnActionEvent;
19 import com.intellij.ui.AnActionButton;
20 import com.intellij.ui.AnActionButtonRunnable;
21 import com.intellij.ui.AnActionButtonUpdater;
22 import com.intellij.ui.ToolbarDecorator;
23 import com.intellij.ui.table.TableView;
24 import com.intellij.util.containers.ContainerUtil;
25 import com.intellij.util.ui.ColumnInfo;
26 import com.intellij.util.ui.ListTableModel;
27 import org.jetbrains.annotations.Nullable;
28
29 import javax.swing.*;
30 import javax.swing.table.DefaultTableCellRenderer;
31 import javax.swing.table.TableCellRenderer;
32 import java.util.List;
33 import java.util.Observable;
34
35 /**
36  * @author traff
37  */
38 public abstract class ListTableWithButtons<T> extends Observable {
39   private final List<T> myElements = ContainerUtil.newArrayList();
40   private final JPanel myPanel;
41   private final TableView myTableView;
42   private boolean myIsEnabled = true;
43
44   protected ListTableWithButtons() {
45     myTableView = new TableView(createListModel());
46     myTableView.setRowHeight(new JTextField().getPreferredSize().height);
47     myTableView.getTableViewModel().setSortable(false);
48     myPanel = ToolbarDecorator.createDecorator(myTableView)
49       .setAddAction(new AnActionButtonRunnable() {
50         @Override
51         public void run(AnActionButton button) {
52           myTableView.stopEditing();
53           setModified();
54           SwingUtilities.invokeLater(new Runnable() {
55             @Override
56             public void run() {
57               myElements.add(createElement());
58               myTableView.getTableViewModel().setItems(myElements);
59               myTableView.getComponent().editCellAt(myElements.size() - 1, 0);
60             }
61           });
62         }
63       }).setRemoveAction(new AnActionButtonRunnable() {
64         @Override
65         public void run(AnActionButton button) {
66           myTableView.stopEditing();
67           setModified();
68           Object selected = getSelection();
69           if (selected != null) {
70             int selectedIndex = myElements.indexOf(selected);
71             myElements.remove(selected);
72             myTableView.getTableViewModel().setItems(myElements);
73
74             int prev = selectedIndex - 1;
75             if (prev >= 0) {
76               myTableView.getComponent().getSelectionModel().setSelectionInterval(prev, prev);
77             }
78             else if (selectedIndex < myElements.size()) {
79               myTableView.getComponent().getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex);
80             }
81           }
82         }
83       }).disableUpDownActions().createPanel();
84
85     ToolbarDecorator.findRemoveButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() {
86       @Override
87       public boolean isEnabled(AnActionEvent e) {
88         T selection = getSelection();
89         return selection != null && myIsEnabled && canDeleteElement(selection);
90       }
91     });
92     ToolbarDecorator.findAddButton(myPanel).addCustomUpdater(new AnActionButtonUpdater() {
93       @Override
94       public boolean isEnabled(AnActionEvent e) {
95         return myIsEnabled;
96       }
97     });
98
99
100     myTableView.getComponent().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
101   }
102
103   protected abstract ListTableModel createListModel();
104
105   protected void setModified() {
106     setChanged();
107     notifyObservers();
108   }
109
110   protected List<T> getElements() {
111     return myElements;
112   }
113
114   public JComponent getComponent() {
115     return myPanel;
116   }
117
118   public void setEnabled() {
119     myTableView.getComponent().setEnabled(true);
120     myIsEnabled = true;
121   }
122
123   public void setDisabled() {
124     myTableView.getComponent().setEnabled(false);
125     myIsEnabled = false;
126   }
127
128   public void stopEditing() {
129     myTableView.stopEditing();
130   }
131
132   public void refreshValues() {
133     myTableView.getComponent().repaint();
134   }
135
136   protected abstract T createElement();
137
138
139   protected T getSelection() {
140     int selIndex = myTableView.getComponent().getSelectionModel().getMinSelectionIndex();
141     if (selIndex < 0) {
142       return null;
143     }
144     else {
145       return myElements.get(selIndex);
146     }
147   }
148
149   public void setValues(List<T> envVariables) {
150     myElements.clear();
151     for (T envVariable : envVariables) {
152       myElements.add(cloneElement(envVariable));
153     }
154     myTableView.getTableViewModel().setItems(myElements);
155   }
156
157   protected abstract T cloneElement(T variable);
158
159   protected abstract boolean canDeleteElement(T selection);
160
161   protected static abstract class ElementsColumnInfoBase<T> extends ColumnInfo<T, String> {
162     private DefaultTableCellRenderer myRenderer;
163
164     protected ElementsColumnInfoBase(String name) {
165       super(name);
166     }
167
168     @Override
169     public TableCellRenderer getRenderer(T element) {
170       if (myRenderer == null) {
171         myRenderer = new DefaultTableCellRenderer();
172       }
173       if (element != null) {
174         myRenderer.setText(valueOf(element));
175         myRenderer.setToolTipText(getDescription(element));
176       }
177       return myRenderer;
178     }
179
180     @Nullable
181     protected abstract String getDescription(T element);
182   }
183 }