/src/main/java/org/sylfra/idea/plugins/revu/ui/multichooser/MultiChooserPanel.java

https://github.com/syllant/idea-plugin-revu · Java · 227 lines · 190 code · 31 blank · 6 comment · 13 complexity · fd6318d8694481b03e5b487a9569fcdf MD5 · raw file

  1. package org.sylfra.idea.plugins.revu.ui.multichooser;
  2. import com.intellij.openapi.actionSystem.*;
  3. import com.intellij.openapi.project.Project;
  4. import com.intellij.util.containers.SortedList;
  5. import com.intellij.util.ui.UIUtil;
  6. import org.jetbrains.annotations.NotNull;
  7. import org.jetbrains.annotations.Nullable;
  8. import org.sylfra.idea.plugins.revu.RevuBundle;
  9. import org.sylfra.idea.plugins.revu.RevuIconProvider;
  10. import org.sylfra.idea.plugins.revu.RevuPlugin;
  11. import org.sylfra.idea.plugins.revu.ui.DashedBorder;
  12. import javax.swing.*;
  13. import java.awt.*;
  14. import java.awt.event.ActionEvent;
  15. import java.awt.event.KeyEvent;
  16. import java.util.ArrayList;
  17. import java.util.Collections;
  18. import java.util.Comparator;
  19. import java.util.List;
  20. /**
  21. * @author <a href="mailto:syllant@gmail.com">Sylvain FRANCOIS</a>
  22. * @version $Id$
  23. */
  24. public abstract class MultiChooserPanel<NestedData, Item extends IMultiChooserItem<NestedData>> extends JPanel
  25. {
  26. protected final Project project;
  27. private MultiChooserPopup<Item> popup;
  28. private final SortedList<Item> selectedItems;
  29. private AnAction editAction;
  30. private JComponent toolbar;
  31. private final JLabel label;
  32. private final String popupTitle;
  33. private final String dimensionKeySuffix;
  34. private final RevuIconProvider.IconRef iconRef;
  35. public MultiChooserPanel(@NotNull Project project, @NotNull JLabel label, @NotNull String popupTitle,
  36. @Nullable String dimensionKeySuffix, @Nullable RevuIconProvider.IconRef iconRef)
  37. {
  38. this.project = project;
  39. this.label = label;
  40. this.popupTitle = popupTitle;
  41. this.dimensionKeySuffix = dimensionKeySuffix;
  42. this.iconRef = iconRef;
  43. selectedItems = new SortedList<Item>(new Comparator<Item>()
  44. {
  45. public int compare(Item o1, Item o2)
  46. {
  47. return o1.getName().compareTo(o2.getName());
  48. }
  49. });
  50. configureUI();
  51. }
  52. private void configureUI()
  53. {
  54. setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
  55. editAction = new AnAction(RevuBundle.message("multiChooser.edit.tip"), null,
  56. RevuIconProvider.getIcon(RevuIconProvider.IconRef.EDIT_MULTI_CHOOSER))
  57. {
  58. @Override
  59. public void actionPerformed(AnActionEvent e)
  60. {
  61. List<NestedData> datas = retrieveAllAvailableElements();
  62. showEditPopup(toItemsList(datas));
  63. }
  64. @Override
  65. public void update(AnActionEvent e)
  66. {
  67. e.getPresentation().setEnabled(getTemplatePresentation().isEnabled());
  68. }
  69. };
  70. // Should use #registerCustomShortcutSet ?
  71. getActionMap().put(editAction, new AbstractAction()
  72. {
  73. public void actionPerformed(ActionEvent e)
  74. {
  75. if (editAction.getTemplatePresentation().isEnabled())
  76. {
  77. editAction.actionPerformed(null);
  78. }
  79. }
  80. });
  81. getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
  82. KeyStroke.getKeyStroke(label.getDisplayedMnemonic(), KeyEvent.ALT_MASK), editAction);
  83. DefaultActionGroup actionGroup = new DefaultActionGroup();
  84. actionGroup.add(editAction);
  85. toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actionGroup, true).getComponent();
  86. if (toolbar.getComponentCount() > 0)
  87. {
  88. label.setLabelFor(toolbar.getComponent(0));
  89. }
  90. add(toolbar);
  91. popup = new MultiChooserPopup<Item>(project, popupTitle,
  92. (dimensionKeySuffix == null) ? null : RevuPlugin.PLUGIN_NAME + "." + dimensionKeySuffix,
  93. new MultiChooserPopup.IPopupListener<Item>()
  94. {
  95. public void apply(@NotNull List<Item> markedElements)
  96. {
  97. setSelectedItems(markedElements);
  98. }
  99. },
  100. new MultiChooserPopup.IItemRenderer<Item>()
  101. {
  102. public String getText(Item issue)
  103. {
  104. return issue.getName();
  105. }
  106. });
  107. }
  108. private List<Item> toItemsList(@Nullable List<NestedData> datas)
  109. {
  110. if (datas == null)
  111. {
  112. return Collections.emptyList();
  113. }
  114. List<Item> items = new ArrayList<Item>(datas.size());
  115. for (NestedData data : datas)
  116. {
  117. items.add(createMultiChooserItem(data));
  118. }
  119. return items;
  120. }
  121. @SuppressWarnings({"unchecked"})
  122. @NotNull
  123. public List<NestedData> getSelectedItemDatas()
  124. {
  125. // First component is the edit button
  126. int count = getComponentCount();
  127. List<NestedData> result = new ArrayList<NestedData>(count - 1);
  128. for (int i = 1; i < count; i++)
  129. {
  130. result.add(((ItemPanel) getComponent(i)).item.getNestedData());
  131. }
  132. return result;
  133. }
  134. public void setSelectedItemDatas(@Nullable List<NestedData> nestedDataList)
  135. {
  136. setSelectedItems(toItemsList(nestedDataList));
  137. }
  138. protected void setSelectedItems(@Nullable List<Item> items)
  139. {
  140. int componentCount = getComponentCount();
  141. for (int i = componentCount - 1; i > 0; i--)
  142. {
  143. remove(i);
  144. }
  145. selectedItems.clear();
  146. selectedItems.addAll(items);
  147. if (items != null)
  148. {
  149. for (Item tag : items)
  150. {
  151. add(new ItemPanel(tag));
  152. }
  153. }
  154. revalidate();
  155. repaint();
  156. }
  157. public void setEnabled(boolean enabled)
  158. {
  159. editAction.getTemplatePresentation().setEnabled(enabled);
  160. }
  161. public void showEditPopup(@NotNull List<Item> allTags)
  162. {
  163. List<Item> allSortedTags = new ArrayList<Item>(allTags);
  164. Collections.sort(allSortedTags);
  165. popup.show(toolbar, false, allSortedTags, selectedItems);
  166. }
  167. @Override
  168. public Dimension getPreferredSize()
  169. {
  170. return super.getPreferredSize();
  171. }
  172. protected abstract Item createMultiChooserItem(@NotNull NestedData data);
  173. protected abstract List<NestedData> retrieveAllAvailableElements();
  174. private class ItemPanel extends JLabel
  175. {
  176. private final Item item;
  177. public ItemPanel(Item item)
  178. {
  179. super(item.getName());
  180. this.item = item;
  181. if (iconRef != null)
  182. {
  183. setIcon(RevuIconProvider.getIcon(iconRef));
  184. setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 0, 8),
  185. BorderFactory.createCompoundBorder(BorderFactory.createEtchedBorder(),
  186. BorderFactory.createEmptyBorder(1, 1, 1, 3))));
  187. }
  188. else
  189. {
  190. setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0, 0, 0, 3),
  191. new DashedBorder(UIUtil.getBoundsColor())));
  192. }
  193. setHorizontalAlignment(SwingConstants.CENTER);
  194. }
  195. }
  196. }