Sunday Sep 23, 2007
by John Zukowski
When you work with the Java Foundation Classes/Swing (JFC/Swing) text components, the cut, copy, and paste operations are automatically handled for you with the help of the
Given a
Code to do the pasting operation is a little more involved, due to the necessary exceptions you need to handle. First, you get a Transferable object from the clipboard; then, you have fun with flavors. A
Although the work in this program demonstrates how to transfer text through the clipboard, the custom
Behaviors like copy and paste are special Action objects called
To use the actions associated with a text component, you get the list of actions from the text component and find the specific one you are looking for based on keys provided by the
To replace the action handlers in the previous example with the built-in handlers, you would use the following code to get the specific
When you work with the Java Foundation Classes/Swing (JFC/Swing) text components, the cut, copy, and paste operations are automatically handled for you with the help of the
EditorKit.
Normally, you do not have to worry about creating code to access the
clipboard. Instead, you ask the EditorKit for its support. To
demonstrate text transfer capabilities, you'll create a program that
manually copies and pastes with a JTextArea and then changes that
program to use EditorKit.
Given a
JTextArea (or any JTextComponent), the code to do a copy
operation involves getting the selected text from the component and
placing it on the clipboard:
String selection = jt.getSelectedText();
StringSelection data = new StringSelection(selection);
Clipboard clipboard =
Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(data, data);
The related classes here, StringSelection and Clipboard, are found
in the java.awt.datatransfer package.
Code to do the pasting operation is a little more involved, due to the necessary exceptions you need to handle. First, you get a Transferable object from the clipboard; then, you have fun with flavors. A
DataFlavor is a format for transferring data across the
clipboard. If, for instance, the current data on the clipboard is an
image, you won't be able to paste it into a JTextArea as a string.
Provided the format is correct, you get the data and put it into the
text component.
Transferable clipData = clipboard.getContents(clipboard);
if (clipData != null) {
try {
if (clipData.isDataFlavorSupported(DataFlavor.stringFlavor)) {
String s = (String)(clipData.getTransferData(
DataFlavor.stringFlavor));
jt.replaceSelection(s);
}
} catch (UnsupportedFlavorException ufe) {
System.err.println("Flavor unsupported: " + ufe);
} catch (IOException ioe) {
System.err.println("Data not available: " + ioe);
}
}
Putting all this together gives you the following program:
import java.awt.*;
import java.awt.event.*;
import java.awt.datatransfer.*;
import javax.swing.*;
import java.io.*;
public class Clip {
public static void main(String args[]) {
Runnable runner = new Runnable() {
public void run() {
JFrame frame = new JFrame("Clip");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Clipboard clipboard =
frame.getToolkit().getSystemClipboard();
final JTextArea jt = new JTextArea();
JScrollPane pane = new JScrollPane(jt);
frame.add(pane, BorderLayout.CENTER);
JButton copy = new JButton("Copy");
copy.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String selection = jt.getSelectedText();
StringSelection data = new StringSelection(selection);
clipboard.setContents(data, data);
}
});
JButton paste = new JButton("Paste");
paste.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
Transferable clipData = clipboard.getContents(clipboard);
if (clipData != null) {
try {
if
(clipData.isDataFlavorSupported
(DataFlavor.stringFlavor)) {
String s = (String)(clipData.getTransferData(
DataFlavor.stringFlavor));
jt.replaceSelection(s);
}
} catch (UnsupportedFlavorException ufe) {
System.err.println("Flavor unsupported: " + ufe);
} catch (IOException ioe) {
System.err.println("Data not available: " + ioe);
}
}
}
});
JPanel p = new JPanel();
p.add(copy);
p.add(paste);
frame.add(p, BorderLayout.SOUTH);
frame.setSize(300, 300);
frame.setVisible(true);
}
};
EventQueue.invokeLater(runner);
}
}
You should see an application similar to the image below:
Although the work in this program demonstrates how to transfer text through the clipboard, the custom
ActionListener implementations
were unnecessary. You can swap out the two new ActionListener()
calls with something much simpler. Each Swing text component uses an
EditorKit to define the set of actions that can be done with the
component. By default, the kit used is the DefaultEditorKit, which
defines behaviors for copy-and-paste support, as well as cursor
movement and many others.
Behaviors like copy and paste are special Action objects called
TextAction. They work by automatically finding the last focused
text component and performing the designated action against them.
To use the actions associated with a text component, you get the list of actions from the text component and find the specific one you are looking for based on keys provided by the
EditorKit. This
gives you an ActionListener that you can associate with the JButton
component in this case or with a JMenuItem if there are menus. When
the component is activated, the action is then automatically done
against the last focused text component.
To replace the action handlers in the previous example with the built-in handlers, you would use the following code to get the specific
ActionListener objects. Basically, you first create a table
of all the handlers and then look for the specific two of interest.
import javax.swing.text.*; ... // get command table ActionMap actionMap = jt.getActionMap(); // Find specific commands Action copyAction = actionMap.get(DefaultEditorKit.copyAction); Action pasteAction = actionMap.get(DefaultEditorKit.pasteAction);Once you have the handlers, you just attach them to the buttons, and you're done. You don't have to programmatically access the clipboard at all.
copy.addActionListener(copyAction); paste.addActionListener(pasteAction);Functionally, the two programs are identical. With the changes, the second version takes advantage of the code already written to do operations on text components. Be sure to see the
DefaultEditorKit
class for a list of all the different predefined operations you can
perform.
nice code
Posted by Anand on September 26, 2007 at 09:30 PM PDT #
you don't have a cut action...
Posted by cerebus on February 28, 2009 at 01:11 AM PST #