diff --git a/platform/util/src/com/intellij/ui/CheckBoxList.java b/platform/util/src/com/intellij/ui/CheckBoxList.java new file mode 100644 index 000000000000..9570eb4abc13 --- /dev/null +++ b/platform/util/src/com/intellij/ui/CheckBoxList.java @@ -0,0 +1,91 @@ +package com.intellij.ui; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import javax.swing.plaf.basic.BasicRadioButtonUI; +import java.awt.*; +import java.awt.event.*; + +/** + * @author oleg + */ +public class CheckBoxList extends JList { + private static final Border noFocusBorder = new EmptyBorder(1, 1, 1, 1); + private static final int DEFAULT_CHECK_BOX_WIDTH = 20; + + public CheckBoxList(final ListModel dataModel, final CheckBoxListListener checkBoxListListener) { + super(dataModel); + setCellRenderer(new CellRenderer()); + setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + setBorder(BorderFactory.createEtchedBorder()); + addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + if (e.getKeyChar() == ' ') { + int index = CheckBoxList.this.getSelectedIndex(); + + if (index >= 0) { + JCheckBox checkbox = (JCheckBox)getModel().getElementAt(index); + setSelected(checkbox, index, checkBoxListListener); + } + } + } + }); + addMouseListener(new MouseAdapter() { + public void mouseClicked(MouseEvent e) { + if (isEnabled()) { + int index = locationToIndex(e.getPoint()); + + if (index != -1) { + JCheckBox checkbox = (JCheckBox)getModel().getElementAt(index); + int iconArea; + try { + iconArea = ((BasicRadioButtonUI)checkbox.getUI()).getDefaultIcon().getIconWidth(); + } + catch (ClassCastException c) { + iconArea = DEFAULT_CHECK_BOX_WIDTH; + } + if (e.getX() < iconArea) { + setSelected(checkbox, index, checkBoxListListener); + } + } + } + } + }); + } + + private void setSelected(JCheckBox checkbox, int index, CheckBoxListListener checkBoxListListener) { + boolean value = !checkbox.isSelected(); + checkbox.setSelected(value); + repaint(); + checkBoxListListener.checkBoxSelectionChanged(index, value); + } + + private class CellRenderer implements ListCellRenderer { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JCheckBox checkbox = (JCheckBox)value; + checkbox.setBackground(getBackgound(isSelected, checkbox)); + checkbox.setForeground(getForeGround(isSelected, checkbox)); + checkbox.setEnabled(isEnabled()); + checkbox.setFont(getFont(checkbox)); + checkbox.setFocusPainted(false); + checkbox.setBorderPainted(true); + checkbox.setBorder(isSelected ? UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder); + return checkbox; + } + } + + protected Font getFont(final JCheckBox checkbox) { + return getFont(); + } + + protected Color getBackgound(final boolean isSelected, final JCheckBox checkbox) { + return isSelected ? getSelectionBackground() : getBackground(); + } + + protected Color getForeGround(final boolean isSelected, final JCheckBox checkbox) { + return isSelected ? getSelectionForeground() : getForeground(); + } + +} diff --git a/platform/util/src/com/intellij/ui/CheckBoxListListener.java b/platform/util/src/com/intellij/ui/CheckBoxListListener.java new file mode 100644 index 000000000000..80e12a2566c3 --- /dev/null +++ b/platform/util/src/com/intellij/ui/CheckBoxListListener.java @@ -0,0 +1,8 @@ +package com.intellij.ui; + +/** + * @author oleg + */ +public interface CheckBoxListListener { + void checkBoxSelectionChanged(int index, boolean value); +} diff --git a/platform/util/src/com/intellij/ui/OptionalChooserComponent.form b/platform/util/src/com/intellij/ui/OptionalChooserComponent.form new file mode 100644 index 000000000000..8bebb6b2da4d --- /dev/null +++ b/platform/util/src/com/intellij/ui/OptionalChooserComponent.form @@ -0,0 +1,28 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/util/src/com/intellij/ui/OptionalChooserComponent.java b/platform/util/src/com/intellij/ui/OptionalChooserComponent.java new file mode 100644 index 000000000000..67e294ed1503 --- /dev/null +++ b/platform/util/src/com/intellij/ui/OptionalChooserComponent.java @@ -0,0 +1,69 @@ +package com.intellij.ui; + +import com.intellij.openapi.util.Pair; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.List; + +/** + * @author oleg + * This component represents a list of checkboxes. + */ +public abstract class OptionalChooserComponent implements CheckBoxListListener { + private JPanel myContentPane; + private CheckBoxList myList; + private DefaultListModel myListModel; + private List> myInitialList; + private ArrayList> myWorkingList; + + public OptionalChooserComponent(@NotNull final List> list) { + myInitialList = list; + myWorkingList = new ArrayList>(myInitialList); + + // fill list + reset(); + } + + public JPanel getContentPane() { + return myContentPane; + } + + public void checkBoxSelectionChanged(int index, boolean value) { + final Pair pair = myWorkingList.remove(index); + myWorkingList.add(index, Pair.create(pair.first, value)); + } + + private void createUIComponents() { + myListModel = new DefaultListModel(); + myList = new CheckBoxList(myListModel, this); + } + + public void reset() { + myWorkingList = new ArrayList>(myInitialList); + update(); + } + + public abstract JCheckBox createCheckBox(final String path, final boolean checked); + + public boolean isModified() { + return !myWorkingList.equals(myInitialList); + } + + public ArrayList> getValue() { + return myWorkingList; + } + + public void apply() { + myInitialList.clear(); + myInitialList.addAll(myWorkingList); + } + + public void update() { + myListModel.clear(); + for (Pair pair : myWorkingList) { + myListModel.addElement(createCheckBox(pair.first, pair.second)); + } + } +} diff --git a/platform/util/src/com/intellij/ui/PathsChooserComponent.form b/platform/util/src/com/intellij/ui/PathsChooserComponent.form new file mode 100644 index 000000000000..24a5f47f4b65 --- /dev/null +++ b/platform/util/src/com/intellij/ui/PathsChooserComponent.form @@ -0,0 +1,49 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/platform/util/src/com/intellij/ui/PathsChooserComponent.java b/platform/util/src/com/intellij/ui/PathsChooserComponent.java new file mode 100644 index 000000000000..d74b34e3c035 --- /dev/null +++ b/platform/util/src/com/intellij/ui/PathsChooserComponent.java @@ -0,0 +1,101 @@ +package com.intellij.ui; + +import com.intellij.openapi.fileChooser.FileChooserDescriptor; +import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory; +import com.intellij.openapi.fileChooser.FileChooserDialog; +import com.intellij.openapi.fileChooser.FileChooserFactory; +import com.intellij.openapi.vfs.VirtualFile; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; + +/** + * @author oleg + * This component is used to configure list of folders with add/remove buttons. + */ +public class PathsChooserComponent { + private JPanel myContentPane; + private JList myList; + private JButton myAddButton; + private JButton myRemoveButton; + private DefaultListModel myListModel; + + private List myWorkingCollection; + private List myInitialCollection; + + public PathsChooserComponent(@NotNull final List collection, @NotNull final PathProcessor processor) { + myInitialCollection = collection; + myWorkingCollection = new ArrayList(myInitialCollection); + myListModel = new DefaultListModel(); + myList.setModel(myListModel); + + // fill list + reset(); + + // listeners + myAddButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + final FileChooserDescriptor dirChooser = FileChooserDescriptorFactory.createSingleFolderDescriptor(); + dirChooser.setShowFileSystemRoots(true); + dirChooser.setHideIgnored(true); + dirChooser.setTitle(UIBundle.message("file.chooser.default.title")); + FileChooserDialog chooser = FileChooserFactory.getInstance().createFileChooser(dirChooser, myContentPane); + VirtualFile[] files = chooser.choose(null, null); + for (VirtualFile file : files) { + // adding to the end + final String path = file.getPath(); + if (processor.addPath(myWorkingCollection, path)){ + myListModel.addElement(path); + } + } + } + }); + + myRemoveButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int selected = myList.getSelectedIndex(); + if (selected != -1) { + // removing index + final String path = (String) myListModel.get(selected); + if (processor.removePath(myWorkingCollection, path)){ + myListModel.remove(selected); + } + } + } + }); + } + + public JPanel getContentPane() { + return myContentPane; + } + + public List getValues(){ + return myWorkingCollection; + } + + public void reset() { + myListModel.clear(); + myWorkingCollection = new ArrayList(myInitialCollection); + for (String path : myWorkingCollection) { + myListModel.addElement(path); + } + } + + public boolean isModified() { + return !myWorkingCollection.equals(myInitialCollection); + } + + public void apply() { + myInitialCollection.clear(); + myInitialCollection.addAll(myWorkingCollection); + } + + public interface PathProcessor { + boolean addPath(List paths, String path); + boolean removePath(List paths, String path); + } +} diff --git a/platform/util/util.iml b/platform/util/util.iml index 315d1bbcb801..619f920cf77c 100644 --- a/platform/util/util.iml +++ b/platform/util/util.iml @@ -16,6 +16,7 @@ +