aboutsummaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2009-07-04 06:58:59 +0000
committerYana Stamcheva <yana@jitsi.org>2009-07-04 06:58:59 +0000
commit26c28dfbda79ad47d9b774c119ef442b8e947faf (patch)
tree3f54a9bd9caa5789f2e37b5c13a1888896062191 /src/net
parent0cadd759954fc55a221db77f256a64322a7792c2 (diff)
downloadjitsi-26c28dfbda79ad47d9b774c119ef442b8e947faf.zip
jitsi-26c28dfbda79ad47d9b774c119ef442b8e947faf.tar.gz
jitsi-26c28dfbda79ad47d9b774c119ef442b8e947faf.tar.bz2
- Issue #690 (Add drag and drop of files in the contact list).
- Show an error message when file transfer is not supported by the selected account.
Diffstat (limited to 'src/net')
-rwxr-xr-xsrc/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java4
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatMessage.java40
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java102
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatTransferHandler.java163
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java118
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/DefaultContactList.java1
-rw-r--r--src/net/java/sip/communicator/util/swing/ExtendedTransferHandler.java191
7 files changed, 444 insertions, 175 deletions
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
index 05afb70..7227c70 100755
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
@@ -200,6 +200,7 @@ public class ChatConversationPanel
String contentType = chatMessage.getContentType();
long date = chatMessage.getDate();
String messageType = chatMessage.getMessageType();
+ String messageTitle = chatMessage.getMessageTitle();
String message = chatMessage.getMessage();
String msgID = "message";
@@ -320,8 +321,7 @@ public class ChatConversationPanel
+ "' </IMG>";
chatString += errorIcon
- + GuiActivator.getResources()
- .getI18NString("service.gui.MSG_DELIVERY_FAILURE")
+ + messageTitle
+ endHeaderTag + "<h5>" + message + "</h5>";
}
else if (messageType.equals(Constants.HISTORY_INCOMING_MESSAGE))
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatMessage.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatMessage.java
index 21c07bd..eb0b473 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatMessage.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatMessage.java
@@ -30,6 +30,12 @@ public class ChatMessage
private final String messageType;
/**
+ * The title of the message. This property is optional and could be used
+ * to show a title for error messages.
+ */
+ private String messageTitle;
+
+ /**
* The content of the message.
*/
private String message;
@@ -62,6 +68,30 @@ public class ChatMessage
}
/**
+ * Creates a <tt>ChatMessage</tt> by specifying all parameters of the
+ * message.
+ * @param contactName the name of the contact
+ * @param date the date and time
+ * @param messageType the type (INCOMING or OUTGOING)
+ * @param message the content
+ * @param contentType the content type (e.g. "text", "text/html", etc.)
+ */
+ public ChatMessage( String contactName,
+ long date,
+ String messageType,
+ String messageTitle,
+ String message,
+ String contentType)
+ {
+ this.contactName = contactName;
+ this.date = date;
+ this.messageType = messageType;
+ this.messageTitle = messageTitle;
+ this.message = message;
+ this.contentType = contentType;
+ }
+
+ /**
* Returns the name of the contact sending the message.
*
* @return the name of the contact sending the message.
@@ -92,6 +122,16 @@ public class ChatMessage
}
/**
+ * Returns the title of the message.
+ *
+ * @return the title of the message.
+ */
+ public String getMessageTitle()
+ {
+ return messageTitle;
+ }
+
+ /**
* Returns the content of the message.
*
* @return the content of the message.
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
index 4d56686..465d0f1 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
@@ -574,11 +574,12 @@ public class ChatPanel
* for processing and appends it at the end of the conversationPanel
* document.
*
- * @param contactName The name of the contact sending the message.
- * @param date The time at which the message is sent or received.
- * @param messageType The type of the message. One of OUTGOING_MESSAGE
- * or INCOMING_MESSAGE.
- * @param message The message text.
+ * @param contactName the name of the contact sending the message
+ * @param date the time at which the message is sent or received
+ * @param messageType the type of the message. One of OUTGOING_MESSAGE
+ * or INCOMING_MESSAGE
+ * @param message the message text
+ * @param contentType the content type
*/
public void addMessage(String contactName, long date,
String messageType, String message, String contentType)
@@ -586,6 +587,40 @@ public class ChatPanel
ChatMessage chatMessage = new ChatMessage(contactName, date,
messageType, message, contentType);
+ this.addChatMessage(chatMessage);
+ }
+
+ /**
+ * Passes the message to the contained <code>ChatConversationPanel</code>
+ * for processing and appends it at the end of the conversationPanel
+ * document.
+ *
+ * @param contactName the name of the contact sending the message
+ * @param date the time at which the message is sent or received
+ * @param messageType the type of the message. One of OUTGOING_MESSAGE
+ * or INCOMING_MESSAGE
+ * @param title the title of the message
+ * @param message the message text
+ * @param contentType the content type
+ */
+ public void addMessage(String contactName, long date,
+ String messageType, String title, String message, String contentType)
+ {
+ ChatMessage chatMessage = new ChatMessage(contactName, date,
+ messageType, title, message, contentType);
+
+ this.addChatMessage(chatMessage);
+ }
+
+ /**
+ * Passes the message to the contained <code>ChatConversationPanel</code>
+ * for processing and appends it at the end of the conversationPanel
+ * document.
+ *
+ * @param chatMessage the chat message to add
+ */
+ private void addChatMessage(ChatMessage chatMessage)
+ {
if (ConfigurationManager.isHistoryShown() && !isHistoryLoaded)
{
synchronized (incomingEventBuffer)
@@ -599,7 +634,23 @@ public class ChatPanel
}
// change the last history message timestamp after we add one.
- this.lastHistoryMsgTimestamp = date;
+ this.lastHistoryMsgTimestamp = chatMessage.getDate();
+ }
+
+ /**
+ * Adds the given error message to the chat window conversation area.
+ *
+ * @param contactName the name of the contact, for which the error occured
+ * @param message the error message
+ */
+ public void addErrorMessage(String contactName,
+ String message)
+ {
+ this.addMessage(contactName, System.currentTimeMillis(),
+ Constants.ERROR_MESSAGE,
+ GuiActivator.getResources()
+ .getI18NString("service.gui.MSG_DELIVERY_FAILURE"),
+ message, "text");
}
/**
@@ -608,10 +659,14 @@ public class ChatPanel
* @param contactName the name of the contact, for which the error occured
* @param message the error message
*/
- public void addErrorMessage(String contactName, String message)
+ public void addErrorMessage(String contactName,
+ String title,
+ String message)
{
this.addMessage(contactName, System.currentTimeMillis(),
- Constants.ERROR_MESSAGE, message, "text");
+ Constants.ERROR_MESSAGE,
+ title,
+ message, "text");
}
/**
@@ -914,9 +969,7 @@ public class ChatPanel
public void catchException(Throwable ex)
{
- logger.error("Failed to send message.", ex);
-
- refreshWriteArea();
+ logger.error("Failed to send file.", ex);
if (ex instanceof IllegalStateException)
{
@@ -949,13 +1002,38 @@ public class ChatPanel
final ChatTransport fileTransferTransport
= findFileTransferChatTransport();
+ // If there's no operation set we show some "not supported" messages
+ // and we return.
+ if (fileTransferTransport == null)
+ {
+ logger.error("Failed to send file.");
+
+ this.addErrorMessage(
+ chatSession.getChatName(),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.FILE_SEND_FAILED",
+ new String[]{file.getName()}),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.FILE_TRANSFER_NOT_SUPPORTED"));
+
+ return;
+ }
+
final SendFileConversationComponent fileComponent
= new SendFileConversationComponent(
this,
fileTransferTransport.getDisplayName(),
file);
- getChatConversationPanel().addComponent(fileComponent);
+ if (ConfigurationManager.isHistoryShown() && !isHistoryLoaded)
+ {
+ synchronized (incomingEventBuffer)
+ {
+ incomingEventBuffer.add(fileComponent);
+ }
+ }
+ else
+ getChatConversationPanel().addComponent(fileComponent);
this.sendFile(file, fileComponent);
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransferHandler.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransferHandler.java
index 4b1c685..f2c8d62 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransferHandler.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransferHandler.java
@@ -15,6 +15,7 @@ import javax.swing.*;
import javax.swing.text.*;
import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.swing.*;
/**
* A TransferHandler that we use to handle copying, pasting and DnD operations
@@ -28,7 +29,7 @@ import net.java.sip.communicator.util.*;
* @author Yana Stamcheva
*/
public class ChatTransferHandler
- extends TransferHandler
+ extends ExtendedTransferHandler
{
/**
* This class logger.
@@ -53,75 +54,6 @@ public class ChatTransferHandler
}
/**
- * Returns the type of transfer actions supported by the source;
- * any bitwise-OR combination of <tt>COPY</tt>, <tt>MOVE</tt>
- * and <tt>LINK</tt>.
- * <p>
- * Some models are not mutable, so a transfer operation of <tt>MOVE</tt>
- * should not be advertised in that case. Returning <tt>NONE</tt>
- * disables transfers from the component.
- *
- * @param c the component holding the data to be transferred;
- * provided to enable sharing of <code>TransferHandler</code>s
- * @return {@code COPY} if the transfer property can be found,
- * otherwise returns <code>NONE</code>
- */
- public int getSourceActions(JComponent c)
- {
- return TransferHandler.COPY_OR_MOVE;
- }
-
- /** Indicates whether a component will accept an import of the given
- * set of data flavors prior to actually attempting to import it. We return
- * <tt>true</tt> to indicate that the transfer with at least one of the
- * given flavors would work and <tt>false</tt> to reject the transfer.
- * <p>
- * @param support the object containing the details of the transfer, not
- * <code>null</code>.
- * @param transferFlavors the data formats available
- * @return true if the data can be inserted into the component, false
- * otherwise
- * @throws NullPointerException if <code>support</code> is {@code null}
- */
- public boolean canImport(JComponent comp, DataFlavor flavor[])
- {
- JTextComponent c = (JTextComponent)comp;
-
- for (int i = 0, n = flavor.length; i < n; i++)
- {
- if (flavor[i].equals(DataFlavor.javaFileListFlavor))
- {
- return true;
- }
- else if (flavor[i].equals(DataFlavor.stringFlavor))
- {
- if (c.isEditable() && c.isEnabled())
- {
- return true;
- }
-
- return false;
- }
- }
-
- return false;
- }
-
- /**
- * Creates a transferable for text pane components in order to enable drag
- * and drop of text.
- */
- public Transferable createTransferable(JComponent comp)
- {
- if (comp instanceof JTextPane)
- {
- return new SelectedTextTransferable((JTextPane) comp);
- }
-
- return null;
- }
-
- /**
* Handles transfers to the chat panel from the clip board or a
* DND drop operation. The <tt>Transferable</tt> parameter contains the
* data that needs to be imported.
@@ -202,95 +134,4 @@ public class ChatTransferHandler
}
return false;
}
-
- /**
- * Handles transport (cut and copy) from the chat panel to
- * <tt>clipboard</tt>. This method will only transfer plain text and would
- * explicitly ignore any formatting.
- * <p>
- * @param comp the component holding the data to be transferred;
- * provided to enable sharing of <code>TransferHandler</code>s
- * @param clip the clipboard to transfer the data into
- * @param action the transfer action requested; this should
- * be a value of either <code>COPY</code> or <code>MOVE</code>;
- * the operation performed is the intersection of the transfer
- * capabilities given by getSourceActions and the requested action;
- * the intersection may result in an action of <code>NONE</code>
- * if the requested action isn't supported
- * @throws IllegalStateException if the clipboard is currently unavailable
- * @see Clipboard#setContents(Transferable, ClipboardOwner)
- */
- public void exportToClipboard(JComponent comp,
- Clipboard clipboard,
- int action)
- throws IllegalStateException
- {
- if (comp instanceof JTextComponent)
- {
- JTextComponent textComponent = (JTextComponent)comp;
- int startIndex = textComponent.getSelectionStart();
- int endIndex = textComponent.getSelectionEnd();
- if (startIndex != endIndex)
- {
- try
- {
- Document doc = textComponent.getDocument();
- String srcData = doc.getText(startIndex,
- endIndex - startIndex);
- StringSelection contents =new StringSelection(srcData);
-
- // this may throw an IllegalStateException,
- // but it will be caught and handled in the
- // action that invoked this method
- clipboard.setContents(contents, null);
-
- if (action == TransferHandler.MOVE)
- {
- doc.remove(startIndex, endIndex - startIndex);
- }
- }
- catch (BadLocationException ble)
- {
- //we simply ignore
- }
- }
- }
- }
-
- /**
- * Transferable for text pane components that enables drag and drop of text.
- */
- public class SelectedTextTransferable implements Transferable
- {
- private JTextPane textPane;
-
- public SelectedTextTransferable(JTextPane textPane)
- {
- this.textPane = textPane;
- }
-
- // Returns supported flavors
- public DataFlavor[] getTransferDataFlavors()
- {
- return new DataFlavor[]{DataFlavor.stringFlavor};
- }
-
- // Returns true if flavor is supported
- public boolean isDataFlavorSupported(DataFlavor flavor)
- {
- return DataFlavor.stringFlavor.equals(flavor);
- }
-
- // Returns Selected Text
- public Object getTransferData(DataFlavor flavor)
- throws UnsupportedFlavorException, IOException
- {
- if (!DataFlavor.stringFlavor.equals(flavor))
- {
- throw new UnsupportedFlavorException(flavor);
- }
-
- return textPane.getSelectedText();
- }
- }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java
new file mode 100644
index 0000000..8f1a58f
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTransferHandler.java
@@ -0,0 +1,118 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.contactlist;
+
+import java.awt.datatransfer.*;
+import java.io.*;
+import java.util.*;
+
+import javax.swing.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.main.chat.*;
+import net.java.sip.communicator.service.contactlist.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.swing.*;
+
+/**
+ * A TransferHandler that we use to handle DnD operations of files in our
+ * <tt>ContactList</tt>.
+ *
+ * @author Yana Stamcheva
+ */
+public class ContactListTransferHandler
+ extends ExtendedTransferHandler
+{
+ private static final Logger logger
+ = Logger.getLogger(ContactListTransferHandler.class);
+
+ private final DefaultContactList contactList;
+
+ public ContactListTransferHandler(DefaultContactList contactList)
+ {
+ this.contactList = contactList;
+ }
+
+ /**
+ * Handles transfers to the contact list from the clip board or a
+ * DND drop operation. The <tt>Transferable</tt> parameter contains the
+ * data that needs to be imported.
+ * <p>
+ * @param comp the component to receive the transfer;
+ * @param transferable the data to import
+ * @return true if the data was inserted into the component and false
+ * otherwise
+ * @see #importData(TransferHandler.TransferSupport)
+ */
+ public boolean importData(JComponent comp, Transferable t)
+ {
+ if (t.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
+ {
+ try
+ {
+ Object o = t.getTransferData(DataFlavor.javaFileListFlavor);
+
+ ChatPanel chatPanel = getChatPanel();
+
+ if (chatPanel != null)
+ {
+ if (o instanceof java.util.Collection)
+ {
+ Collection<File> files = (Collection<File>) o;
+
+ for(File file: files)
+ {
+ if (chatPanel != null)
+ chatPanel.sendFile(file);
+
+ GuiActivator.getUIService().getChatWindowManager()
+ .openChat(chatPanel, false);
+ }
+
+ // Otherwise fire files dropped event.
+ return true;
+ }
+ }
+ }
+ catch (UnsupportedFlavorException e)
+ {
+ logger.debug("Failed to drop files.", e);
+ }
+ catch (IOException e)
+ {
+ logger.debug("Failed to drop files.", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the <tt>ChatPanel</tt> corresponding to the currently selected
+ * contact.
+ *
+ * @return the <tt>ChatPanel</tt> corresponding to the currently selected
+ * contact.
+ */
+ private ChatPanel getChatPanel()
+ {
+ ChatPanel chatPanel = null;
+
+ Object selectedObject = contactList.getSelectedValue();
+
+ if (selectedObject != null && selectedObject instanceof MetaContact)
+ {
+ MetaContact metaContact = (MetaContact) selectedObject;
+
+ // Obtain the corresponding chat panel.
+ chatPanel
+ = GuiActivator.getUIService().getChatWindowManager()
+ .getContactChat(metaContact);
+ }
+
+ return chatPanel;
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/DefaultContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/DefaultContactList.java
index b8c74d9..a96d748 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/DefaultContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/DefaultContactList.java
@@ -36,6 +36,7 @@ public class DefaultContactList
this.getSelectionModel().setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);
+ this.setTransferHandler(new ContactListTransferHandler(this));
this.setCellRenderer(new ContactListCellRenderer());
}
diff --git a/src/net/java/sip/communicator/util/swing/ExtendedTransferHandler.java b/src/net/java/sip/communicator/util/swing/ExtendedTransferHandler.java
new file mode 100644
index 0000000..20de777
--- /dev/null
+++ b/src/net/java/sip/communicator/util/swing/ExtendedTransferHandler.java
@@ -0,0 +1,191 @@
+/*
+ * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.util.swing;
+
+import java.awt.datatransfer.*;
+import java.io.*;
+
+import javax.swing.*;
+import javax.swing.text.*;
+
+/**
+ * A TransferHandler that we use to handle copying, pasting and DnD operations.
+ * The string handler is heavily inspired by Sun's
+ * <tt>DefaultTransferHandler</tt> with the main difference being that
+ * we only accept pasting of plain text. We do this in order to avoid html
+ * support problems that appear when pasting formatted text into our editable
+ * area.
+ *
+ * @author Emil Ivov
+ * @author Yana Stamcheva
+ */
+public class ExtendedTransferHandler
+ extends TransferHandler
+{
+ /**
+ * Returns the type of transfer actions supported by the source;
+ * any bitwise-OR combination of <tt>COPY</tt>, <tt>MOVE</tt>
+ * and <tt>LINK</tt>.
+ * <p>
+ * Some models are not mutable, so a transfer operation of <tt>MOVE</tt>
+ * should not be advertised in that case. Returning <tt>NONE</tt>
+ * disables transfers from the component.
+ *
+ * @param c the component holding the data to be transferred;
+ * provided to enable sharing of <code>TransferHandler</code>s
+ * @return {@code COPY} if the transfer property can be found,
+ * otherwise returns <code>NONE</code>
+ */
+ public int getSourceActions(JComponent c)
+ {
+ return TransferHandler.COPY_OR_MOVE;
+ }
+
+ /** Indicates whether a component will accept an import of the given
+ * set of data flavors prior to actually attempting to import it. We return
+ * <tt>true</tt> to indicate that the transfer with at least one of the
+ * given flavors would work and <tt>false</tt> to reject the transfer.
+ * <p>
+ * @param support the object containing the details of the transfer, not
+ * <code>null</code>.
+ * @param transferFlavors the data formats available
+ * @return true if the data can be inserted into the component, false
+ * otherwise
+ * @throws NullPointerException if <code>support</code> is {@code null}
+ */
+ public boolean canImport(JComponent comp, DataFlavor flavor[])
+ {
+ for (int i = 0, n = flavor.length; i < n; i++)
+ {
+ if (flavor[i].equals(DataFlavor.javaFileListFlavor))
+ {
+ return true;
+ }
+ else if (flavor[i].equals(DataFlavor.stringFlavor))
+ {
+ if (comp instanceof JTextComponent)
+ {
+ JTextComponent c = (JTextComponent)comp;
+
+ if (c.isEditable() && c.isEnabled())
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Creates a transferable for text pane components in order to enable drag
+ * and drop of text.
+ */
+ public Transferable createTransferable(JComponent comp)
+ {
+ if (comp instanceof JTextPane)
+ {
+ return new SelectedTextTransferable((JTextPane) comp);
+ }
+
+ return super.createTransferable(comp);
+ }
+
+ /**
+ * Handles transport (cut and copy) from the chat panel to
+ * <tt>clipboard</tt>. This method will only transfer plain text and would
+ * explicitly ignore any formatting.
+ * <p>
+ * @param comp the component holding the data to be transferred;
+ * provided to enable sharing of <code>TransferHandler</code>s
+ * @param clip the clipboard to transfer the data into
+ * @param action the transfer action requested; this should
+ * be a value of either <code>COPY</code> or <code>MOVE</code>;
+ * the operation performed is the intersection of the transfer
+ * capabilities given by getSourceActions and the requested action;
+ * the intersection may result in an action of <code>NONE</code>
+ * if the requested action isn't supported
+ * @throws IllegalStateException if the clipboard is currently unavailable
+ * @see Clipboard#setContents(Transferable, ClipboardOwner)
+ */
+ public void exportToClipboard(JComponent comp,
+ Clipboard clipboard,
+ int action)
+ throws IllegalStateException
+ {
+ if (comp instanceof JTextComponent)
+ {
+ JTextComponent textComponent = (JTextComponent)comp;
+ int startIndex = textComponent.getSelectionStart();
+ int endIndex = textComponent.getSelectionEnd();
+ if (startIndex != endIndex)
+ {
+ try
+ {
+ Document doc = textComponent.getDocument();
+ String srcData = doc.getText(startIndex,
+ endIndex - startIndex);
+ StringSelection contents =new StringSelection(srcData);
+
+ // this may throw an IllegalStateException,
+ // but it will be caught and handled in the
+ // action that invoked this method
+ clipboard.setContents(contents, null);
+
+ if (action == TransferHandler.MOVE)
+ {
+ doc.remove(startIndex, endIndex - startIndex);
+ }
+ }
+ catch (BadLocationException ble)
+ {
+ //we simply ignore
+ }
+ }
+ }
+ }
+
+ /**
+ * Transferable for text pane components that enables drag and drop of text.
+ */
+ public class SelectedTextTransferable implements Transferable
+ {
+ private JTextPane textPane;
+
+ public SelectedTextTransferable(JTextPane textPane)
+ {
+ this.textPane = textPane;
+ }
+
+ // Returns supported flavors
+ public DataFlavor[] getTransferDataFlavors()
+ {
+ return new DataFlavor[]{DataFlavor.stringFlavor};
+ }
+
+ // Returns true if flavor is supported
+ public boolean isDataFlavorSupported(DataFlavor flavor)
+ {
+ return DataFlavor.stringFlavor.equals(flavor);
+ }
+
+ // Returns Selected Text
+ public Object getTransferData(DataFlavor flavor)
+ throws UnsupportedFlavorException, IOException
+ {
+ if (!DataFlavor.stringFlavor.equals(flavor))
+ {
+ throw new UnsupportedFlavorException(flavor);
+ }
+
+ return textPane.getSelectedText();
+ }
+ }
+}