📄 intro.html
字号:
<li> Drop it onto the table. It is removed from the list and the commas are removed, replaced by column separators.<li> Type some text into the text area; for example: How, Now, Brown, Cow. Select the line of text and drop it into the table.<li> Select an item in the list. Hold down the Control key while dragging the item to the text area and drop. The text has been copied to the new location.</ol><hr></blockquote><p>The code for the example's main class isin <a href=examples/ExtendedDnDDemo.java><code>ExtendedDnDDemo.java</code></a>.An abstract subclass of <code>TransferHandler</code>,<code>StringTransferHandler</code>, definesthree abstract methods for importing and exportingstrings: <code>exportString</code>, <code>importString</code>,and <code>cleanup</code>. <code>StringTransferHandler</code>also overrides the standard <code>TransferHandler</code> methods:<code>importData</code> and <code>canImport</code>are required to import data;<code>getSourceActions</code>,<code>createTransferable</code>, and<code>exportDone</code> are for export.(Note that <code>exportDone</code> may not be necessary if you onlyimplement Copy and, therefore, do not need to remove data from thesource as you would for a Move.)The abstract methods <code>importString</code>, <code>exportString</code>,and <code>cleanup</code> are called by the <code>importData</code>,<code>createTransferable</code>, and <code>exportDone</code> methods,respectively. Here is the code for<a href=examples/StringTransferHandler.java><code>StringTransferHander.java</code></a>:<blockquote><pre>public abstract class StringTransferHandler extends TransferHandler { protected abstract String exportString(JComponent c); protected abstract void importString(JComponent c, String str); protected abstract void cleanup(JComponent c, boolean remove); protected Transferable createTransferable(JComponent c) { return new StringSelection(exportString(c)); } public int getSourceActions(JComponent c) { return COPY_OR_MOVE; } public boolean importData(JComponent c, Transferable t) { if (canImport(c, t.getTransferDataFlavors())) { try { String str = (String)t.getTransferData(DataFlavor.stringFlavor); importString(c, str); return true; } catch (UnsupportedFlavorException ufe) { } catch (IOException ioe) { } } return false; } protected void exportDone(JComponent c, Transferable data, int action) { cleanup(c, action == MOVE); } public boolean canImport(JComponent c, DataFlavor[] flavors) { for (int i = 0; i < flavors.length; i++) { if (DataFlavor.stringFlavor.equals(flavors[i])) { return true; } } return false; } }</pre></blockquote><p>The<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/datatransfer/StringSelection.html"><code>StringSelection</code></a> class implements the <code>Transferable</code> interface and handles the details of bundling up the data for transport.<p>Two subclasses of <code>StringTransferHandler</code>,<a href=examples/ListTransferHandler.java><code>ListTransferHandler</code></a> and<a href=examples/TableTransferHandler.java><code>TableTransferHandler</code></a>, implement theabstract <code>importString</code>, <code>exportString</code>, and <code>cleanup</code>methods and deal with the specifics of a list and a table,respectively. Here is the code for<code>ListTransferHandler</code>:<blockquote><pre>public class ListTransferHandler extends StringTransferHandler { private int[] indices = null; private int addIndex = -1; //Location where items were added private int addCount = 0; //Number of items added. //Bundle up the selected items in the list //as a single string, for export. protected String exportString(JComponent c) { JList list = (JList)c; indices = list.getSelectedIndices(); Object[] values = list.getSelectedValues(); StringBuffer buff = new StringBuffer(); for (int i = 0; i < values.length; i++) { Object val = values[i]; buff.append(val == null ? "" : val.toString()); if (i != values.length - 1) { buff.append("\n"); } } return buff.toString(); } //Take the incoming string and wherever there is a //newline, break it into a separate item in the list. protected void importString(JComponent c, String str) { JList target = (JList)c; DefaultListModel listModel = (DefaultListModel)target.getModel(); int index = target.getSelectedIndex(); //Prevent the user from dropping data back on itself. //For example, if the user is moving items #4,#5,#6 and #7 and //attempts to insert the items after item #5, this would //be problematic when removing the original items. //So this is not allowed. if (indices != null && index >= indices[0] - 1 && index <= indices[indices.length - 1]) { indices = null; return; } int max = listModel.getSize(); if (index < 0) { index = max; } else { index++; if (index > max) { index = max; } } addIndex = index; String[] values = str.split("\n"); addCount = values.length; for (int i = 0; i < values.length; i++) { listModel.add(index++, values[i]); } } //If the remove argument is true, the drop has been //successful and it's time to remove the selected items //from the list. If the remove argument is false, it //was a Copy operation and the original list is left //intact. protected void cleanup(JComponent c, boolean remove) { if (remove && indices != null) { JList source = (JList)c; DefaultListModel model = (DefaultListModel)source.getModel(); //If we are moving items around in the same list, we //need to adjust the indices accordingly, since those //after the insertion point have moved. if (addCount > 0) { for (int i = 0; i < indices.length; i++) { if (indices[i] > addIndex) { indices[i] += addCount; } } } for (int i = indices.length - 1; i >= 0; i--) { model.remove(indices[i]); } } indices = null; addCount = 0; addIndex = -1; }}</pre></blockquote><p>Note that <code>importString</code> uses the<code>split</code> utility method of <code>String</code>to divide the incoming text so that wherever a newline occurs,a new list item is created.To support the moving of text from a list, <code>exportDone</code>calls <code>cleanup</code>, which takes care of removing thedragged items from the original list. The <code>cleanup</code>method has special handling for the case when moving itemswithin the same list and the data is moved to a higherposition in the list (with a smaller index). The <code>cleanup</code>method is called <em>after</em> the data has been inserted intothe list which changes the indices of the items to be deleted.When the indices of the original items to be moved havechanged, they must be adjusted accordingly, before they canbe deleted.<p>The table transfer handler,<a href=examples/TableTransferHandler.java><code>TableTransferHandler</code></a>, is implemented in a similarmanner, though it is slightly more complex because it hassupport for text that is newline- and comma-delimited.</blockquote><a name=dataFormat><h2>Specifying the Data Format</h2></a><blockquote><p>Creating a <code>TransferHandler</code> can be as simple as using the constructor. For example, in the <code>LabelDnD</code> demo, the label supports both importing and exporting <code>String</code>s to and from its <code>text</code> property with the following line of code:<blockquote><pre>label.setTransferHandler(new TransferHandler("text"));</pre></blockquote><p>When using the property name form of the constructor,there must be a <code>get<i>Property</i></code> method in thecomponent's API to export data and a <code>set<i>Property</i></code>method to import data. The label's transfer handler works because<code>JLabel</code> has a <code>getText</code> method.This works with any property, for example,if you had instead created the label's transfer handler like this:<blockquote><pre>label.setTransferHandler(new TransferHandler("foreground"));</pre></blockquote><p>You would then be able to drag a color from the colorchooser, drop it on the label, and the label's text colorwould change, because label has a <code>setForeground</code>method that requires a <code>java.awt.Color</code> object.We have provided another version of LabelDnD, called <a href=examples/index.html#LabelDnD2>LabelDnD2</a>,which demonstrates using the <code>TransferHandler</code>constructor, this time for the label's foreground property:<p><center><IMG SRC="../../figures/uiswing/dnd/LabelDnD2.png" WIDTH="447" HEIGHT="428" ALIGN="BOTTOM" ALT="The LabelDnD2 example"></center></p><blockquote><hr><strong>Try this:</strong> <ol><li> <a href="http://java.sun.com/docs/books/tutorialJWS/uiswing/misc/examples/LabelDnD2.jnlp">Run LabelDnD2</a> using <a href=http://java.sun.com/products/javawebstart> Java Web Start</a>. Or, to compile and run the example yourself, consult the <a href="examples/index.html#LabelDnD">example index</a>.<li> Select a color from the palette. The selected color appears in the Preview panel.<li> Press and hold the mouse button while the cursor is over the Preview panel and begin to drag.<li> Drop the color onto the label and see the text change color.<li> Select another color from the palette so the Preview panel now shows a new color.<li> Press on the label and begin to drag. Drop the color anywhere on the color chooser — in the palette or the preview panel. The Preview panel now shows the color of the label.</ol><hr></blockquote><p>If you cannot use the property name form of the<code>TransferHandler</code> constructor, the<a class="APILink" target="_blank" href="http://java.sun.com/javase/6/docs/api/java/awt/datatransfer/DataFlavor.html"><code>DataFlavor</code></a> class allows you to specify the content-type of your datafor both your <code>TransferHandler</code> and, if necessary,your <code>Transferable</code>. Three flavor types are predefined for you:<ul><li> <code>imageFlavor</code> represents data in the <code>java.awt.Image</code> format<li> <code>stringFlavor</code> represents data in the most basic form of text — <code>java.lang.String</code><li> <code>javaFileListFlavor</code> represents <code>java.io.File</code> objects in a <code>java.util.List</code> format</ul><p>For example, a <code>TransferHandler</code> imports<code>String</code> data with this line of code:<blockquote><pre>String str = (String)t.getTransferData(DataFlavor.stringFlavor);</pre></blockquote><p>Or it imports a <code>java.awt.Image</code> using <code>imageFlavor</code> with this line of code:<blockquote><pre>Image image = (Image)t.getTransferData(DataFlavor.imageFlavor);</pre></blockquote><p>If you require a flavor other than thesepredefined types, you need to create your own.The format for specifying a data flavor is this:<blockquote><pre>DataFlavor(Class representationClass, String humanPresentableName);</pre></blockquote>For example, to create a data flavor for the<code>java.util.ArrayList</code> class:<blockquote><pre>new DataFlavor(ArrayList.class, "ArrayList");</pre></blockquote><p>To create a data flavor for an integer array:<blockquote><pre>new DataFlavor(int[].class, "Integer Array");</pre></blockquote><p>Transferring the data in this manner uses <code>Object</code>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -