PageRenderTime 62ms CodeModel.GetById 33ms app.highlight 25ms RepoModel.GetById 1ms 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
  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 */
 22package org.gjt.sp.jedit.gui;
 23
 24import org.gjt.sp.util.Log;
 25
 26import javax.swing.*;
 27import java.awt.*;
 28import java.awt.datatransfer.DataFlavor;
 29import java.awt.datatransfer.Transferable;
 30import java.awt.datatransfer.UnsupportedFlavorException;
 31import java.io.IOException;
 32import java.util.Collection;
 33import java.util.Iterator;
 34import java.util.List;
 35
 36/**
 37 * @author Matthieu Casanova
 38 * @since jEdit 4.4pre1
 39 */
 40public class PingPongList<E> extends JSplitPane
 41{
 42	private final MyListModel<E> leftModel;
 43	private final MyListModel<E> rightModel;
 44	private JList left;
 45	private JList right;
 46	private JLabel leftLabel;
 47	private JLabel rightLabel;
 48	private JPanel leftPanel;
 49	private JPanel rightPanel;
 50
 51	public PingPongList(List<E> leftData, List<E> rightData)
 52	{
 53		this(JSplitPane.HORIZONTAL_SPLIT, leftData, rightData);
 54	}
 55
 56	public PingPongList(int newOrientation, List<E> leftData, List<E> rightData)
 57	{
 58		super(newOrientation);
 59		leftModel = new MyListModel<E>(leftData);
 60		left = new JList(leftModel);
 61		rightModel = new MyListModel<E>(rightData);
 62		right = new JList(rightModel);
 63		leftPanel = new JPanel(new BorderLayout());
 64		rightPanel = new JPanel(new BorderLayout());
 65		JScrollPane leftScroll = new JScrollPane(left);
 66		JScrollPane rightScroll = new JScrollPane(right);
 67		leftPanel.add(leftScroll);
 68		rightPanel.add(rightScroll);
 69		setLeftComponent(leftPanel);
 70		setRightComponent(rightPanel);
 71		left.setDragEnabled(true);
 72		right.setDragEnabled(true);
 73
 74		MyTransferHandler myTransferHandler = new MyTransferHandler();
 75		left.setTransferHandler(myTransferHandler);
 76		right.setTransferHandler(myTransferHandler);
 77		setDividerLocation(0.5);
 78	}
 79
 80	public void setLeftTooltip(String leftTooltip)
 81	{
 82		left.setToolTipText(leftTooltip);
 83	}
 84
 85	public void setRightTooltip(String rightTooltip)
 86	{
 87		right.setToolTipText(rightTooltip);
 88	}
 89
 90	public void setLeftTitle(String leftTitle)
 91	{
 92		if (leftTitle == null)
 93		{
 94			removeLeftTitle();
 95			return;
 96		}
 97		if (leftLabel == null)
 98		{
 99			leftLabel = new JLabel();
100		}
101		leftLabel.setText(leftTitle);
102		leftPanel.add(leftLabel, BorderLayout.NORTH);
103	}
104
105	public void setRightTitle(String rightTitle)
106	{
107		if (rightTitle == null)
108		{
109			removeRightTitle();
110			return;
111		}
112		if (rightLabel == null)
113		{
114			rightLabel = new JLabel();
115		}
116		rightLabel.setText(rightTitle);
117		rightPanel.add(rightLabel, BorderLayout.NORTH);
118	}
119
120	public void removeLeftTitle()
121	{
122		if (leftLabel != null)
123		{
124			leftPanel.remove(leftLabel);
125			leftLabel = null;
126		}
127	}
128
129	public void removeRightTitle()
130	{
131		if (rightLabel != null)
132		{
133			rightPanel.remove(rightLabel);
134			rightLabel = null;
135		}
136	}
137
138	public int getLeftSize()
139	{
140		return leftModel.getSize();
141	}
142
143	public int getRightSize()
144	{
145		return rightModel.getSize();
146	}
147
148	public Iterator<E> getLeftDataIterator()
149	{
150		return leftModel.iterator();
151	}
152
153	public Iterator<E> getRightDataIterator()
154	{
155		return rightModel.iterator();
156	}
157
158	public void moveAllToLeft()
159	{
160		leftModel.addAll(rightModel.data);
161		rightModel.clear();
162	}
163
164	public void moveAllToRight()
165	{
166		rightModel.addAll(leftModel.data);
167		leftModel.clear();
168	}
169
170	private static class MyListModel<E> extends AbstractListModel implements Iterable<E>
171	{
172		private List<E> data;
173
174		private MyListModel(List<E> data)
175		{
176			this.data = data;
177		}
178
179		public int getSize()
180		{
181			return data.size();
182		}
183
184		public Object getElementAt(int index)
185		{
186			return data.get(index);
187		}
188
189		public Iterator<E> iterator()
190		{
191			return data.iterator();
192		}
193
194		public void clear()
195		{
196			if (data.isEmpty())
197				return;
198			int i = data.size();
199			data.clear();
200			fireIntervalRemoved(this, 0, i - 1);
201		}
202
203		public void addAll(Collection<E> newData)
204		{
205			int i = data.size();
206			data.addAll(newData);
207			fireIntervalAdded(this, i, i + newData.size() - 1);
208		}
209
210		public void remove(int index)
211		{
212			data.remove(index);
213
214			fireContentsChanged(this, index, index);
215		}
216
217		public void add(int pos, E[] addedDatas)
218		{
219			for (int i = addedDatas.length - 1; i >= 0; i--)
220				data.add(pos, addedDatas[i]);
221
222			fireContentsChanged(this, pos, pos + addedDatas.length - 1);
223		}
224	}
225
226	private class MyTransferHandler extends TransferHandler
227	{
228		private JList sourceList;
229		private int[]indices;
230
231		@Override
232		public int getSourceActions(JComponent c)
233		{
234			return MOVE;
235		}
236
237		@Override
238		public boolean importData(JComponent comp, Transferable t)
239		{
240			try
241			{
242				@SuppressWarnings({"unchecked"})
243				E[] transferData = (E[]) t.getTransferData(MyTransferable.javaListFlavor);
244				JList targetList = (JList) comp;
245				@SuppressWarnings({"unchecked"})
246				MyListModel<E> targetModel = (MyListModel<E>) targetList.getModel();
247				@SuppressWarnings({"unchecked"})
248				MyListModel<E> sourceModel = (MyListModel<E>) sourceList.getModel();
249				int dropLocation = targetList.getSelectedIndex();
250				if(dropLocation == -1)dropLocation=0;
251				targetModel.add(dropLocation, transferData);
252				int dropStart = dropLocation;
253				if (targetList == sourceList)
254				{
255					// we are moving inside the same list
256					for (int i = indices.length - 1; i >= 0; i--)
257					{
258						int index = indices[i];
259						if (indices[i] >= dropLocation)
260						{
261							index += transferData.length;
262						}
263						else
264						{
265							dropStart--;
266						}
267						sourceModel.remove(index);
268					}
269					for (int i = indices.length - 1; i >= 0; i--)
270					{
271						indices[i] = dropStart + i;
272					}
273				}
274				else
275				{
276					// we are moving to another list
277					sourceList.clearSelection();
278					for (int i = indices.length - 1; i >= 0; i--)
279					{
280						sourceModel.remove(indices[i]);
281						indices[i] = dropLocation + i;
282					}
283				}
284				targetList.setSelectedIndices(indices);
285				return true;
286			}
287			catch (UnsupportedFlavorException e)
288			{
289				Log.log(Log.ERROR, this, e);
290			}
291			catch (IOException e)
292			{
293				Log.log(Log.ERROR, this, e);
294			}
295			return false;
296		}
297
298		@Override
299		protected Transferable createTransferable(JComponent c)
300		{
301			sourceList = (JList) c;
302			indices = sourceList.getSelectedIndices();
303
304			@SuppressWarnings({"unchecked"})
305			E[] objects = (E[]) sourceList.getSelectedValues();
306			return new MyTransferable<E>(objects);
307		}
308
309		@Override
310		public boolean canImport(JComponent comp, DataFlavor[] transferFlavors)
311		{
312			return comp == left || comp == right;
313		}
314	}
315
316	private static class MyTransferable<E> implements Transferable
317	{
318		public static final DataFlavor javaListFlavor = new DataFlavor(Collection.class, "java.util.Collection");
319
320		private final E[] data;
321
322		private MyTransferable(E[] data)
323		{
324			this.data = data;
325		}
326
327		public DataFlavor[] getTransferDataFlavors()
328		{
329			return new DataFlavor[]{javaListFlavor};
330		}
331
332		public boolean isDataFlavorSupported(DataFlavor flavor)
333		{
334			return flavor.equals(javaListFlavor);
335		}
336
337		public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
338		{
339			return data;
340		}
341	}
342}