You can use a custom TransferHandler
to do this.
According to the section from the Swing tutorial on Using and Creating a Data Flavor you should be able to use the char[] as the object written to the clipboard.
However, I couldn't get it working and ended up writing a StringBuilder to the clipboard. I commented out the code were I attempted to use the char[], maybe someone else can figure out what I did wrong.
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import java.io.*;
public class PasswordHandler extends TransferHandler
{
// public final static DataFlavor CHAR_ARRAY_FLAVOR = new DataFlavor(char[].class, "Char Array");
public final static DataFlavor CHAR_ARRAY_FLAVOR = new DataFlavor(StringBuilder.class, "StringBuilder");
@Override
public int getSourceActions(JComponent c)
{
return COPY;
}
@Override
public Transferable createTransferable(final JComponent c)
{
return new Transferable()
{
@Override
public Object getTransferData(DataFlavor flavor)
{
JPasswordField textField = (JPasswordField)c;
// return textField.getPassword();
return new StringBuilder( textField.getText() );
}
@Override
public DataFlavor[] getTransferDataFlavors()
{
DataFlavor[] flavors = new DataFlavor[1];
flavors[0] = CHAR_ARRAY_FLAVOR;
return flavors;
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor)
{
return flavor.equals(CHAR_ARRAY_FLAVOR);
}
};
}
@Override
public boolean canImport(TransferSupport support)
{
boolean canImport = support.isDataFlavorSupported(CHAR_ARRAY_FLAVOR);
return canImport;
}
@Override
public boolean importData(TransferSupport support)
{
// char[] password;
StringBuilder password;
try
{
// password = (char[])support.getTransferable().getTransferData(CHAR_ARRAY_FLAVOR);
password = (StringBuilder)support.getTransferable().getTransferData(CHAR_ARRAY_FLAVOR);
}
catch (Exception e)
{
e.printStackTrace();
return false;
}
JPasswordField textField = (JPasswordField)support.getComponent();
textField.setText(password.toString());
return true;
}
private static void createAndShowUI()
{
JPasswordField tf1 = new JPasswordField(10);
JPasswordField tf2 = new JPasswordField(10);
TransferHandler handler = new PasswordHandler();
tf1.setTransferHandler( handler );
tf2.setTransferHandler( handler );
tf1.putClientProperty("JPasswordField.cutCopyAllowed",true);
tf2.putClientProperty("JPasswordField.cutCopyAllowed",true);
JFrame frame = new JFrame("Password Copy");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(tf1, BorderLayout.WEST);
frame.add(tf2, BorderLayout.EAST);
frame.add(new JTextField(), BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
The code takes the entire text from the password field. If you only want the selected characters then you will need to modify the getTransferData()
method to only add the selected characters to the StringBuilder.