How to intercept paste (to modify content) before inserted to TextPane
Hi, i'd like to intercept a users paste for some modifications before the clipboard is actually inserted into my TextPane. In this case i'd want to strip the pasted html of some tags when the user pastes formatted text from browsers into a TextPane - script tags etc.
I figured that paste uses insertHtml: I could override it and strip away whatever I don't want inserted - but I still need to allow those tags to be inserted programmatically.
[459 byte] By [
dogeatsdog] at [2007-9-27 19:42:42]

Well, if you intercept the KeyPressed events, and check whether the "paste" command arrives, then you can do whatever you wish:
public void keyPressed(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_V) {
System.out.println("V arrived: " + ke.getModifiers());
int i = ke.getModifiers();
if ( (i & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) {
System.out.println("Ctrl-V");
Clipboard clb = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable contents = clb.getContents(ke.getSource());
if (contents != null) {
if (contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
String str = (String) contents.getTransferData(DataFlavor.stringFlavor);
System.out.println("Clipboard: " + str);
} catch (Exception e) {
e.printStackTrace();
}
}
}
ke.consume();
}
}
}
Right now I've just checked it on windows, and hard coded the Ctrl-V as the paste command, but you might correct that.
Please don't forget to consume the paste command (that means the internal processing of it will be blocked).
Here is another way to do it by overriding the default paste action:
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
public class SimpleFrame extends JFrame
{
JTextPane textPane;
JTabbedPane tabbedPane;
public SimpleFrame()
{
JToolBar toolBar = new JToolBar();
getContentPane().add(toolBar, BorderLayout.NORTH);
Action pasteAction = new MyPasteAction();
toolBar.add( createButtonFromAction( new DefaultEditorKit.CutAction() ) );
toolBar.add( createButtonFromAction( new DefaultEditorKit.CopyAction() ) );
toolBar.add( createButtonFromAction( pasteAction ) );
toolBar.add( createButtonFromAction( new SelectAll() ) );
textPane = new JTextPane();
JScrollPane scrollPane = new JScrollPane( textPane );
scrollPane.setPreferredSize( new Dimension(300, 200) );
getContentPane().add(scrollPane);
// Override Ctrl+V to use your paste action
Object key = pasteAction.getValue(Action.NAME);
KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_A, KeyEvent.CTRL_MASK);
textPane.getInputMap().put(ks, key);
textPane.getActionMap().put(key, pasteAction);
}
private JButton createButtonFromAction(Action action)
{
JButton button = new JButton( action );
button.setRequestFocusEnabled(false);
return button;
}
public static void main(String[] args)
{
SimpleFrame frame = new SimpleFrame();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.show();
frame.textPane.requestFocus();
}
class SelectAll extends TextAction
{
public SelectAll()
{
super("Select All");
}
public void actionPerformed(ActionEvent e)
{
JTextComponent component = getFocusedComponent();
component.selectAll();
}
}
class MyPasteAction extends DefaultEditorKit.PasteAction
{
public void actionPerformed(ActionEvent e)
{
try
{
// Get clipboard contents
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable t = c.getContents( null );
String data = (String)t.getTransferData( DataFlavor.stringFlavor );
// Do your stuff
data = "<" + data + ">";
// Paste your new data
getFocusedComponent().replaceSelection( data );
}
catch (Exception x) {}
}
}
}