PageRenderTime 42ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/jEdit/tags/jedit-4-5-pre1/org/gjt/sp/jedit/gui/PingPongList.java

#
Java | 342 lines | 274 code | 41 blank | 27 comment | 25 complexity | 08e78d2e59ba62a142a96974fb65ad5e MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, Apache-2.0, LGPL-2.0, LGPL-3.0, GPL-2.0, CC-BY-SA-3.0, LGPL-2.1, GPL-3.0, MPL-2.0-no-copyleft-exception, IPL-1.0
  1. /*
  2. * EncodingsOptionPane.java - Encodings options panel
  3. * :tabSize=8:indentSize=8:noTabs=false:
  4. * :folding=explicit:collapseFolds=1:
  5. *
  6. * Copyright (C) 2010 Matthieu Casanova
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU General Public License
  10. * as published by the Free Software Foundation; either version 2
  11. * of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21. */
  22. package org.gjt.sp.jedit.gui;
  23. import org.gjt.sp.util.Log;
  24. import javax.swing.*;
  25. import java.awt.*;
  26. import java.awt.datatransfer.DataFlavor;
  27. import java.awt.datatransfer.Transferable;
  28. import java.awt.datatransfer.UnsupportedFlavorException;
  29. import java.io.IOException;
  30. import java.util.Collection;
  31. import java.util.Iterator;
  32. import java.util.List;
  33. /**
  34. * @author Matthieu Casanova
  35. * @since jEdit 4.4pre1
  36. */
  37. public class PingPongList<E> extends JSplitPane
  38. {
  39. private final MyListModel<E> leftModel;
  40. private final MyListModel<E> rightModel;
  41. private JList left;
  42. private JList right;
  43. private JLabel leftLabel;
  44. private JLabel rightLabel;
  45. private JPanel leftPanel;
  46. private JPanel rightPanel;
  47. public PingPongList(List<E> leftData, List<E> rightData)
  48. {
  49. this(JSplitPane.HORIZONTAL_SPLIT, leftData, rightData);
  50. }
  51. public PingPongList(int newOrientation, List<E> leftData, List<E> rightData)
  52. {
  53. super(newOrientation);
  54. leftModel = new MyListModel<E>(leftData);
  55. left = new JList(leftModel);
  56. rightModel = new MyListModel<E>(rightData);
  57. right = new JList(rightModel);
  58. leftPanel = new JPanel(new BorderLayout());
  59. rightPanel = new JPanel(new BorderLayout());
  60. JScrollPane leftScroll = new JScrollPane(left);
  61. JScrollPane rightScroll = new JScrollPane(right);
  62. leftPanel.add(leftScroll);
  63. rightPanel.add(rightScroll);
  64. setLeftComponent(leftPanel);
  65. setRightComponent(rightPanel);
  66. left.setDragEnabled(true);
  67. right.setDragEnabled(true);
  68. MyTransferHandler myTransferHandler = new MyTransferHandler();
  69. left.setTransferHandler(myTransferHandler);
  70. right.setTransferHandler(myTransferHandler);
  71. setDividerLocation(0.5);
  72. }
  73. public void setLeftTooltip(String leftTooltip)
  74. {
  75. left.setToolTipText(leftTooltip);
  76. }
  77. public void setRightTooltip(String rightTooltip)
  78. {
  79. right.setToolTipText(rightTooltip);
  80. }
  81. public void setLeftTitle(String leftTitle)
  82. {
  83. if (leftTitle == null)
  84. {
  85. removeLeftTitle();
  86. return;
  87. }
  88. if (leftLabel == null)
  89. {
  90. leftLabel = new JLabel();
  91. }
  92. leftLabel.setText(leftTitle);
  93. leftPanel.add(leftLabel, BorderLayout.NORTH);
  94. }
  95. public void setRightTitle(String rightTitle)
  96. {
  97. if (rightTitle == null)
  98. {
  99. removeRightTitle();
  100. return;
  101. }
  102. if (rightLabel == null)
  103. {
  104. rightLabel = new JLabel();
  105. }
  106. rightLabel.setText(rightTitle);
  107. rightPanel.add(rightLabel, BorderLayout.NORTH);
  108. }
  109. public void removeLeftTitle()
  110. {
  111. if (leftLabel != null)
  112. {
  113. leftPanel.remove(leftLabel);
  114. leftLabel = null;
  115. }
  116. }
  117. public void removeRightTitle()
  118. {
  119. if (rightLabel != null)
  120. {
  121. rightPanel.remove(rightLabel);
  122. rightLabel = null;
  123. }
  124. }
  125. public int getLeftSize()
  126. {
  127. return leftModel.getSize();
  128. }
  129. public int getRightSize()
  130. {
  131. return rightModel.getSize();
  132. }
  133. public Iterator<E> getLeftDataIterator()
  134. {
  135. return leftModel.iterator();
  136. }
  137. public Iterator<E> getRightDataIterator()
  138. {
  139. return rightModel.iterator();
  140. }
  141. public void moveAllToLeft()
  142. {
  143. leftModel.addAll(rightModel.data);
  144. rightModel.clear();
  145. }
  146. public void moveAllToRight()
  147. {
  148. rightModel.addAll(leftModel.data);
  149. leftModel.clear();
  150. }
  151. private static class MyListModel<E> extends AbstractListModel implements Iterable<E>
  152. {
  153. private List<E> data;
  154. private MyListModel(List<E> data)
  155. {
  156. this.data = data;
  157. }
  158. public int getSize()
  159. {
  160. return data.size();
  161. }
  162. public Object getElementAt(int index)
  163. {
  164. return data.get(index);
  165. }
  166. public Iterator<E> iterator()
  167. {
  168. return data.iterator();
  169. }
  170. public void clear()
  171. {
  172. if (data.isEmpty())
  173. return;
  174. int i = data.size();
  175. data.clear();
  176. fireIntervalRemoved(this, 0, i - 1);
  177. }
  178. public void addAll(Collection<E> newData)
  179. {
  180. int i = data.size();
  181. data.addAll(newData);
  182. fireIntervalAdded(this, i, i + newData.size() - 1);
  183. }
  184. public void remove(int index)
  185. {
  186. data.remove(index);
  187. fireContentsChanged(this, index, index);
  188. }
  189. public void add(int pos, E[] addedDatas)
  190. {
  191. for (int i = addedDatas.length - 1; i >= 0; i--)
  192. data.add(pos, addedDatas[i]);
  193. fireContentsChanged(this, pos, pos + addedDatas.length - 1);
  194. }
  195. }
  196. private class MyTransferHandler extends TransferHandler
  197. {
  198. private JList sourceList;
  199. private int[]indices;
  200. @Override
  201. public int getSourceActions(JComponent c)
  202. {
  203. return MOVE;
  204. }
  205. @Override
  206. public boolean importData(JComponent comp, Transferable t)
  207. {
  208. try
  209. {
  210. @SuppressWarnings({"unchecked"})
  211. E[] transferData = (E[]) t.getTransferData(MyTransferable.javaListFlavor);
  212. JList targetList = (JList) comp;
  213. @SuppressWarnings({"unchecked"})
  214. MyListModel<E> targetModel = (MyListModel<E>) targetList.getModel();
  215. @SuppressWarnings({"unchecked"})
  216. MyListModel<E> sourceModel = (MyListModel<E>) sourceList.getModel();
  217. int dropLocation = targetList.getSelectedIndex();
  218. if(dropLocation == -1)dropLocation=0;
  219. targetModel.add(dropLocation, transferData);
  220. int dropStart = dropLocation;
  221. if (targetList == sourceList)
  222. {
  223. // we are moving inside the same list
  224. for (int i = indices.length - 1; i >= 0; i--)
  225. {
  226. int index = indices[i];
  227. if (indices[i] >= dropLocation)
  228. {
  229. index += transferData.length;
  230. }
  231. else
  232. {
  233. dropStart--;
  234. }
  235. sourceModel.remove(index);
  236. }
  237. for (int i = indices.length - 1; i >= 0; i--)
  238. {
  239. indices[i] = dropStart + i;
  240. }
  241. }
  242. else
  243. {
  244. // we are moving to another list
  245. sourceList.clearSelection();
  246. for (int i = indices.length - 1; i >= 0; i--)
  247. {
  248. sourceModel.remove(indices[i]);
  249. indices[i] = dropLocation + i;
  250. }
  251. }
  252. targetList.setSelectedIndices(indices);
  253. return true;
  254. }
  255. catch (UnsupportedFlavorException e)
  256. {
  257. Log.log(Log.ERROR, this, e);
  258. }
  259. catch (IOException e)
  260. {
  261. Log.log(Log.ERROR, this, e);
  262. }
  263. return false;
  264. }
  265. @Override
  266. protected Transferable createTransferable(JComponent c)
  267. {
  268. sourceList = (JList) c;
  269. indices = sourceList.getSelectedIndices();
  270. @SuppressWarnings({"unchecked"})
  271. E[] objects = (E[]) sourceList.getSelectedValues();
  272. return new MyTransferable<E>(objects);
  273. }
  274. @Override
  275. public boolean canImport(JComponent comp, DataFlavor[] transferFlavors)
  276. {
  277. return comp == left || comp == right;
  278. }
  279. }
  280. private static class MyTransferable<E> implements Transferable
  281. {
  282. public static final DataFlavor javaListFlavor = new DataFlavor(Collection.class, "java.util.Collection");
  283. private final E[] data;
  284. private MyTransferable(E[] data)
  285. {
  286. this.data = data;
  287. }
  288. public DataFlavor[] getTransferDataFlavors()
  289. {
  290. return new DataFlavor[]{javaListFlavor};
  291. }
  292. public boolean isDataFlavorSupported(DataFlavor flavor)
  293. {
  294. return flavor.equals(javaListFlavor);
  295. }
  296. public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
  297. {
  298. return data;
  299. }
  300. }
  301. }