extract CheckBoxListModelEditor, consolidate copy action button placement (file watchers vs external tools)

This commit is contained in:
Vladimir Krivosheev
2014-01-09 15:02:09 +01:00
parent c77d473122
commit 07c3b8cfcb
7 changed files with 234 additions and 42 deletions
@@ -76,7 +76,6 @@ public abstract class BaseToolsPanel<T extends Tool> extends JPanel {
private boolean myIsModified = false;
protected BaseToolsPanel() {
myTree = new CheckboxTree(
new CheckboxTree.CheckboxTreeCellRenderer() {
@Override
@@ -181,8 +180,7 @@ public abstract class BaseToolsPanel<T extends Tool> extends JPanel {
myTree.requestFocus();
}
}
}).setButtonComparator("Add", "Copy", "Edit", "Remove", "Up", "Down")
.createPanel(), BorderLayout.CENTER);
}).createPanel(), BorderLayout.CENTER);
myAddButton = ToolbarDecorator.findAddButton(this);
myEditButton = ToolbarDecorator.findEditButton(this);
@@ -4,6 +4,7 @@ import com.intellij.ui.components.JBList;
import com.intellij.util.Function;
import com.intellij.util.containers.BidirectionalMap;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -23,7 +24,7 @@ import java.util.Map;
public class CheckBoxList<T> extends JBList {
private static final int DEFAULT_CHECK_BOX_WIDTH = 20;
private CheckBoxListListener checkBoxListListener;
private final BidirectionalMap<Object, JCheckBox> myItemMap = new BidirectionalMap<Object, JCheckBox>();
private final BidirectionalMap<T, JCheckBox> myItemMap = new BidirectionalMap<T, JCheckBox>();
public CheckBoxList(final CheckBoxListListener checkBoxListListener) {
this(new DefaultListModel(), checkBoxListListener);
@@ -39,6 +40,7 @@ public class CheckBoxList<T> extends JBList {
public CheckBoxList(final DefaultListModel dataModel) {
super();
//noinspection unchecked
setModel(dataModel);
setCellRenderer(new CellRenderer());
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
@@ -87,7 +89,8 @@ public class CheckBoxList<T> extends JBList {
public void setStringItems(final Map<String, Boolean> items) {
clear();
for (Map.Entry<String, Boolean> entry : items.entrySet()) {
addItem(entry.getKey(), entry.getKey(), entry.getValue());
//noinspection unchecked
addItem((T)entry.getKey(), entry.getKey(), entry.getValue());
}
}
@@ -99,19 +102,26 @@ public class CheckBoxList<T> extends JBList {
}
}
private void addItem(Object item, String text, boolean selected) {
public void addItem(T item, String text, boolean selected) {
JCheckBox checkBox = new JCheckBox(text, selected);
myItemMap.put(item, checkBox);
//noinspection unchecked
((DefaultListModel) getModel()).addElement(checkBox);
}
public Object getItemAt(int index) {
public void updateItem(@NotNull T oldItem, @NotNull T newItem) {
JCheckBox checkBox = myItemMap.remove(oldItem);
myItemMap.put(newItem, checkBox);
}
@Nullable
public T getItemAt(int index) {
JCheckBox checkBox = (JCheckBox)getModel().getElementAt(index);
List<Object> value = myItemMap.getKeysByValue(checkBox);
List<T> value = myItemMap.getKeysByValue(checkBox);
return value == null || value.isEmpty() ? null : value.get(0);
}
private void clear() {
public void clear() {
((DefaultListModel) getModel()).clear();
myItemMap.clear();
}
@@ -120,12 +130,12 @@ public class CheckBoxList<T> extends JBList {
return ((JCheckBox)getModel().getElementAt(index)).isSelected();
}
public boolean isItemSelected(Object item) {
public boolean isItemSelected(T item) {
JCheckBox checkBox = myItemMap.get(item);
return checkBox != null && checkBox.isSelected();
}
public void setItemSelected(Object item, boolean selected) {
public void setItemSelected(T item, boolean selected) {
JCheckBox checkBox = myItemMap.get(item);
if (checkBox != null) {
checkBox.setSelected(selected);
@@ -140,6 +150,7 @@ public class CheckBoxList<T> extends JBList {
// fire change notification in case if we've already initialized model
final ListModel model = getModel();
if (model instanceof DefaultListModel) {
//noinspection unchecked
((DefaultListModel)model).setElementAt(getModel().getElementAt(index), index);
}
@@ -83,31 +83,34 @@ class ListToolbarDecorator extends ToolbarDecorator {
protected void updateButtons() {
final CommonActionsPanel p = getActionsPanel();
if (p != null) {
boolean someElementSelected;
if (myList.isEnabled()) {
final int index = myList.getSelectedIndex();
if (0 <= index && index < myList.getModel().getSize()) {
someElementSelected = 0 <= index && index < myList.getModel().getSize();
if (someElementSelected) {
final boolean downEnable = myList.getMaxSelectionIndex() < myList.getModel().getSize() - 1;
final boolean upEnable = myList.getMinSelectionIndex() > 0;
final boolean editEnabled = myList.getSelectedIndices().length == 1;
p.setEnabled(CommonActionsPanel.Buttons.EDIT, editEnabled);
p.setEnabled(CommonActionsPanel.Buttons.REMOVE, true);
p.setEnabled(CommonActionsPanel.Buttons.UP, upEnable);
p.setEnabled(CommonActionsPanel.Buttons.DOWN, downEnable);
}
else {
p.setEnabled(CommonActionsPanel.Buttons.EDIT, false);
p.setEnabled(CommonActionsPanel.Buttons.REMOVE, false);
p.setEnabled(CommonActionsPanel.Buttons.UP, false);
p.setEnabled(CommonActionsPanel.Buttons.DOWN, false);
}
p.setEnabled(CommonActionsPanel.Buttons.ADD, true);
}
else {
someElementSelected = false;
p.setEnabled(CommonActionsPanel.Buttons.ADD, false);
p.setEnabled(CommonActionsPanel.Buttons.REMOVE, false);
p.setEnabled(CommonActionsPanel.Buttons.UP, false);
p.setEnabled(CommonActionsPanel.Buttons.DOWN, false);
}
p.setEnabled(CommonActionsPanel.Buttons.REMOVE, someElementSelected);
updateExtraElementActions(someElementSelected);
}
}
@@ -0,0 +1,181 @@
/*
* Copyright 2000-2014 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.util.ui;
import com.intellij.ide.IdeBundle;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.AnActionButton;
import com.intellij.ui.AnActionButtonRunnable;
import com.intellij.ui.CheckBoxList;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.util.Consumer;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.Function;
import com.intellij.util.PlatformIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
public class CheckBoxListModelEditor<T> {
private final CheckBoxList<T> list;
private final ToolbarDecorator toolbarDecorator;
private final Function<T, String> toNameConverter;
public CheckBoxListModelEditor(@NotNull Function<T, String> toNameConverter, @NotNull String emptyText) {
this.toNameConverter = toNameConverter;
list = new CheckBoxList<T>();
list.setEmptyText(emptyText);
// toolbar decorator is responsible for border
list.setBorder(null);
toolbarDecorator = ToolbarDecorator.createDecorator(list);
}
@NotNull
public CheckBoxListModelEditor<T> editAction(final @NotNull Function<T, T> consumer) {
final Runnable action = new Runnable() {
@Override
public void run() {
T item = getSelectedItem();
if (item != null) {
T newItem = consumer.fun(item);
if (newItem != null) {
list.updateItem(item, newItem);
}
list.repaint();
list.requestFocus();
}
}
};
toolbarDecorator.setEditAction(new AnActionButtonRunnable() {
@Override
public void run(AnActionButton button) {
action.run();
}
});
EditSourceOnDoubleClickHandler.install(list, action);
return this;
}
@NotNull
public CheckBoxListModelEditor<T> copyAction(final @NotNull Consumer<T> consumer) {
toolbarDecorator.addExtraAction(new ToolbarDecorator.ElementActionButton(IdeBundle.message("button.copy"), PlatformIcons.COPY_ICON) {
@Override
public void actionPerformed(AnActionEvent e) {
int[] indices = list.getSelectedIndices();
if (indices == null || indices.length == 0) {
return;
}
for (int index : indices) {
T item = list.getItemAt(index);
if (item != null) {
consumer.consume(item);
}
}
}
});
return this;
}
public ToolbarDecorator getToolbar() {
return toolbarDecorator;
}
@NotNull
public JComponent createComponent() {
return toolbarDecorator.createPanel();
}
@NotNull
public DefaultListModel getModel() {
return ((DefaultListModel)list.getModel());
}
public void selectItemByName(@NotNull String name) {
for (int i = 0; i < list.getItemsCount(); i++) {
T item = list.getItemAt(i);
if (item != null && name.equalsIgnoreCase(toNameConverter.fun(item))) {
list.setSelectedIndex(i);
}
}
}
@Nullable
private T getSelectedItem() {
int index = list.getSelectedIndex();
return index == -1 ? null : list.getItemAt(index);
}
public CheckBoxList<T> getList() {
return list;
}
public void reset(@NotNull List<Pair<T, Boolean>> items) {
list.clear();
for (Pair<T, Boolean> item : items) {
list.addItem(item.first, toNameConverter.fun(item.first), item.second);
}
}
public boolean isModified(@NotNull List<Pair<T, Boolean>> oldItems) {
if (oldItems.size() != list.getItemsCount()) {
return true;
}
for (int i = 0; i < list.getItemsCount(); i++) {
T item = list.getItemAt(i);
if (item == null) {
return true;
}
Pair<T, Boolean> oldItem = oldItems.get(i);
if (oldItem.second != list.isItemSelected(i) || !oldItem.first.equals(item)) {
return true;
}
}
return false;
}
@NotNull
public List<T> getItems() {
int count = list.getItemsCount();
List<T> result = new ArrayList<T>(count);
for (int i = 0; i < count; i++) {
T item = list.getItemAt(i);
if (item != null) {
result.add(item);
}
}
return result;
}
@NotNull
public List<Pair<T, Boolean>> apply() {
int count = list.getItemsCount();
List<Pair<T, Boolean>> result = new ArrayList<Pair<T, Boolean>>(count);
for (int i = 0; i < count; i++) {
T item = list.getItemAt(i);
if (item != null) {
result.add(Pair.create(item, list.isItemSelected(i)));
}
}
return result;
}
}
@@ -37,12 +37,11 @@ import java.util.*;
*/
public class ContainedInBranchesConfigDialog extends DialogWrapper {
private JPanel myPanel;
private CheckBoxList myLocalBranches;
private CheckBoxList myRemoteBranches;
private CheckBoxList<String> myLocalBranches;
private CheckBoxList<String> myRemoteBranches;
private final Project myProject;
private boolean myChanged;
private JRadioButton myHighlight;
private JRadioButton myFilter;
public ContainedInBranchesConfigDialog(final Project project, final Collection<String> localBranches,
Collection<String> remoteBranches, final String currentLocal, final String currentRemote) {
@@ -74,15 +73,15 @@ public class ContainedInBranchesConfigDialog extends DialogWrapper {
final ButtonGroup bg = new ButtonGroup();
myHighlight = new JRadioButton("Highlight them");
myFilter = new JRadioButton("Filter others out");
JRadioButton filter = new JRadioButton("Filter others out");
bg.add(myHighlight);
bg.add(myFilter);
bg.add(filter);
gb.gridwidth = 1;
gb.gridx = 0;
++ gb.gridy;
myPanel.add(myHighlight, gb);
++ gb.gridy;
myPanel.add(myFilter, gb);
myPanel.add(filter, gb);
gb.insets.top = 10;
gb.gridwidth = 1;
@@ -108,7 +107,7 @@ public class ContainedInBranchesConfigDialog extends DialogWrapper {
setItems(remoteBranches, gitLogSettings.getRemoteBranchesCopy(), myRemoteBranches);
myHighlight.setSelected(gitLogSettings.isHighlight());
myFilter.setSelected(! gitLogSettings.isHighlight());
filter.setSelected(!gitLogSettings.isHighlight());
new ListSpeedSearch(myLocalBranches);
new ListSpeedSearch(myRemoteBranches);
@@ -134,7 +133,7 @@ public class ContainedInBranchesConfigDialog extends DialogWrapper {
return myChanged;
}
private static void setItems(Collection<String> localBranches, Set<String> localBranchesCopy, final CheckBoxList list) {
private static void setItems(Collection<String> localBranches, Set<String> localBranchesCopy, final CheckBoxList<String> list) {
// order
final Map<String, Boolean> localBranchesState = new TreeMap<String, Boolean>();
for (String localBranch : localBranches) {
@@ -163,9 +162,9 @@ public class ContainedInBranchesConfigDialog extends DialogWrapper {
final GitLogSettings gitLogSettings = GitLogSettings.getInstance(myProject);
final ArrayList<String> local = gatherSelected((DefaultListModel)myLocalBranches.getModel());
final ArrayList<String> remote = gatherSelected((DefaultListModel)myRemoteBranches.getModel());
boolean hightlightChanged = gitLogSettings.isHighlight() != myHighlight.isSelected();
boolean highlightChanged = gitLogSettings.isHighlight() != myHighlight.isSelected();
gitLogSettings.setHighlight(myHighlight.isSelected());
if (gitLogSettings.setIfChanged(local, remote) || hightlightChanged) {
if (gitLogSettings.setIfChanged(local, remote) || highlightChanged) {
myChanged = true;
}
super.doOKAction();
@@ -183,7 +182,7 @@ public class ContainedInBranchesConfigDialog extends DialogWrapper {
return selected;
}
private static class MyCheckBoxList extends CheckBoxList {
private static class MyCheckBoxList extends CheckBoxList<String> {
private final String myBold;
private final static Border FOCUSED_BORDER = UIManager.getBorder("List.focusCellHighlightBorder");
private final EmptyBorder myEmptyBorder;
@@ -117,7 +117,7 @@ public class GitLogUI implements Disposable {
private boolean myStarted;
private String myPreviousFilter;
private final CommentSearchContext myCommentSearchContext;
private List<String> myUsersSearchContext;
private final List<String> myUsersSearchContext;
private String mySelectedBranch;
private BranchSelectorAction myBranchSelectorAction;
private final DescriptionRenderer myDescriptionRenderer;
@@ -159,7 +159,7 @@ public class GitLogUI implements Disposable {
private JScrollPane myTableScrollPane;
private GitLogUI.MyTextFieldAction myTextFieldAction;
private DatesFilterI myDatesFilter;
private GitLogSettings mySettings;
private final GitLogSettings mySettings;
public GitLogUI(Project project, final Mediator mediator) {
myProject = project;
@@ -481,7 +481,7 @@ public class GitLogUI implements Disposable {
});
myBranchesLoaderImpl = new Consumer<CommitI>() {
private Processor<AbstractHash> myRecheck;
private final Processor<AbstractHash> myRecheck;
{
myRecheck = new Processor<AbstractHash>() {
@@ -1043,7 +1043,7 @@ public class GitLogUI implements Disposable {
private class DataProviderPanel extends JPanel implements TypeSafeDataProvider {
private GitCommitDetailsProvider myCommitDetailsProvider;
private final GitCommitDetailsProvider myCommitDetailsProvider;
private DataProviderPanel(LayoutManager layout) {
super(layout);
@@ -1989,7 +1989,7 @@ public class GitLogUI implements Disposable {
private final DumbAwareAction myMultiColorAction;
private final DumbAwareAction myCalmAction;
private final Icon myIcon;
private JLabel myLabel;
private final JLabel myLabel;
private final GitLogUI.MySelectRootsForTreeAction myRootsForTreeAction;
private final DumbAwareAction myDateOrder;
private final DumbAwareAction myTopoOrder;
@@ -2102,7 +2102,7 @@ public class GitLogUI implements Disposable {
@Override
public void actionPerformed(AnActionEvent e) {
final CheckBoxList checkBoxList = new CheckBoxList();
final CheckBoxList<String> checkBoxList = new CheckBoxList<String>();
final List<VirtualFile> order = myTableModel.getOrder();
final Set<VirtualFile> activeRoots = myTableModel.getActiveRoots();
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class BrowserSettings implements SearchableConfigurable, Configurable.NoScroll {
private BrowserSettingsPanel mySettingsPanel;
private BrowserSettingsPanel myPanel;
@Override
@NotNull
@@ -52,33 +52,33 @@ public class BrowserSettings implements SearchableConfigurable, Configurable.NoS
@Override
public JComponent createComponent() {
if (mySettingsPanel == null) {
mySettingsPanel = new BrowserSettingsPanel();
if (myPanel == null) {
myPanel = new BrowserSettingsPanel();
}
return mySettingsPanel.getComponent();
return myPanel.getComponent();
}
@Override
public boolean isModified() {
return mySettingsPanel != null && mySettingsPanel.isModified();
return myPanel != null && myPanel.isModified();
}
@Override
public void apply() throws ConfigurationException {
if (mySettingsPanel != null) {
mySettingsPanel.apply();
if (myPanel != null) {
myPanel.apply();
}
}
@Override
public void reset() {
if (mySettingsPanel != null) {
mySettingsPanel.reset();
if (myPanel != null) {
myPanel.reset();
}
}
@Override
public void disposeUIResources() {
mySettingsPanel = null;
myPanel = null;
}
}