Following example shows how to store multiple items from previous cut/copy/paste actions. These items (clipboard history) can be accessed via menus or Ctrl+Shift+V shortcut for the current paste selection.
Example
Utility class to handle cut/copy/paste and maintain Clipboard history
public class PasteFromClipboardHistorySupport {
private static int clipboardHistorySetSize = 20;
private LinkedHashSet<String> clipboardSet = new LinkedHashSet<>(clipboardHistorySetSize);
private JPopupMenu popupMenu;
private JMenu editMenu;
private TextAction cutAction;
private TextAction copyAction;
private TextAction pasteAction;
private TextAction pasteHistoryAction;
public PasteFromClipboardHistorySupport() {
init();
}
private void init() {
editMenu = new JMenu("Edit");
popupMenu = new JPopupMenu();
this.cutAction = newTextAction(this::onCutAction, "Cut", KeyEvent.VK_X,
InputEvent.CTRL_DOWN_MASK);
this.copyAction = newTextAction(this::onCopyAction, "Copy", KeyEvent.VK_C,
InputEvent.CTRL_DOWN_MASK);
this.pasteAction = newTextAction(this::onPasteAction, "Paste", KeyEvent.VK_V,
InputEvent.CTRL_DOWN_MASK);
this.pasteHistoryAction = newTextAction(this::onPasteHistoryAction, "Paste From History",
KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK + InputEvent.SHIFT_DOWN_MASK);
popupMenu.addPopupMenuListener(new PopupMenuListener() {
@Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
pasteHistoryAction.setEnabled(clipboardSet.size() > 0);
}
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
}
@Override
public void popupMenuCanceled(PopupMenuEvent e) {
}
});
}
private TextAction newTextAction(Consumer<JTextComponent> textEventConsumer,
String name, int key, int mask) {
TextAction ta = new TextAction(name) {
@Override
public void actionPerformed(ActionEvent e) {
textEventConsumer.accept(super.getFocusedComponent());
}
};
ta.putValue(AbstractAction.ACCELERATOR_KEY, KeyStroke.getKeyStroke(key, mask));
popupMenu.add(new JMenuItem(ta));
editMenu.add(new JMenuItem(ta));
return ta;
}
private void onPasteAction(JTextComponent tc) {
String s = getSystemClipboardContent();
if (s == null) {
return;
}
tc.paste();
CollectionUtil.addToCollectionWithLimit(clipboardSet, s, clipboardHistorySetSize);
}
private void onCopyAction(JTextComponent tc) {
String s = tc.getSelectedText();
if (s == null) {
return;
}
tc.copy();
CollectionUtil.addToCollectionWithLimit(clipboardSet, s, clipboardHistorySetSize);
}
private void onCutAction(JTextComponent tc) {
String s = tc.getSelectedText();
if (s == null) {
return;
}
tc.cut();
CollectionUtil.addToCollectionWithLimit(clipboardSet, s, clipboardHistorySetSize);
}
private void onPasteHistoryAction(JTextComponent tc) {
showPasteHistoryPopup(tc);
}
public void register(JTextComponent... textComponents) {
if (textComponents == null) {
return;
}
for (JTextComponent tc : textComponents) {
//overriding default key shortcuts for cut/copy/paste
register(tc, cutAction, KeyEvent.VK_X);
register(tc, copyAction, KeyEvent.VK_C);
register(tc, pasteAction, KeyEvent.VK_V);
tc.setComponentPopupMenu(popupMenu);
}
}
private void register(JTextComponent tc, TextAction action, int key) {
tc.registerKeyboardAction(action::actionPerformed, KeyStroke.getKeyStroke(key,
InputEvent.CTRL_DOWN_MASK), JComponent.WHEN_FOCUSED);
}
public JMenu getEditMenu() {
return editMenu;
}
private void showPasteHistoryPopup(JTextComponent tc) {
JPopupMenu historyPopup = new JPopupMenu();
historyPopup.setBackground(Color.WHITE);
historyPopup.setBorder(
BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.LIGHT_GRAY, 3),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
JLabel label = new JLabel("Clipboard History");
label.setForeground(Color.BLUE);
historyPopup.add(label);
Iterator<String> itr = new LinkedList<>(clipboardSet).descendingIterator();
while (itr.hasNext()) {
String s = itr.next();
JMenuItem item = new JMenuItem(s.length() > 60 ? s.substring(0, 30) + " .... " +
s.substring(s.length() - 30) : s);
item.setBackground(Color.WHITE);
historyPopup.add(item);
item.addActionListener(ae -> {
try {
tc.getDocument().insertString(tc.getCaretPosition(), s, null);
} catch (BadLocationException e) {
System.err.println(e);
}
});
}
Point p = tc.getCaret().getMagicCaretPosition();
historyPopup.show(tc, p.x, p.y);
}
public static String getSystemClipboardContent() {
try {
return (String) Toolkit.getDefaultToolkit()
.getSystemClipboard().getData(DataFlavor.stringFlavor);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Rolling collection utility
In above class, we are keeping history of only 20 recent items. Older items are discarded, for that we are using following utility class (taken from this example).
public class CollectionUtil {
public static <T, C extends Collection<T>> void addToCollectionWithLimit(C c, T itemToAdd, int limit) {
List<T> list = new ArrayList<>(c);
list.add(itemToAdd);
while (list.size() > limit) {
list.remove(0);
}
c.clear();
c.addAll(list);
}
}
Example Main class
public class MultiCopyPasteExampleMain {
public static void main(String[] args) {
JTextArea ta = new JTextArea(5, 5);
JTextField tf = new JTextField();
JTextPane tp = new JTextPane();
ta.setText("mark torch even owl young ");
tf.setText("Money is the root of all money");
tp.setText("skip atmosphere screw shot grounds X-ray foot extreme confidence");
PasteFromClipboardHistorySupport copyPasteSupport = new PasteFromClipboardHistorySupport();
copyPasteSupport.register(ta, tf, tp);
JSplitPane splitPane = new JSplitPane();
splitPane.setDividerLocation(300);
splitPane.setLeftComponent(new JScrollPane(ta));
splitPane.setRightComponent(new JScrollPane(tp));
JMenuBar menuBar = new JMenuBar();
menuBar.add(copyPasteSupport.getEditMenu());
JFrame frame = createFrame("Paste from clipboard history");
frame.setJMenuBar(menuBar);
frame.add(tf, BorderLayout.NORTH);
frame.add(splitPane);
frame.setVisible(true);
}
public static JFrame createFrame(String title) {
JFrame frame = new JFrame(title);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(600, 300));
return frame;
}
}
Output
Cut/copy/paste/paste from History actions can be invoked from shortcut keys or via right click menu or JMenuBar. Externally copied items to the system clipboard are only available in the application after we pasted them via standard paste action.
On clicking 'Paste From History' menu (or via key Ctrl+shift+V) another popup shows up listing previous items which can be selected by clicking.
Example ProjectDependencies and Technologies Used:
|
|