From a260d41f82f24dce2c73a575d1610598e072f9aa Mon Sep 17 00:00:00 2001 From: sgoudham Date: Sun, 18 Jul 2021 23:06:49 +0100 Subject: [PATCH] Experiment with different clipboard retrieval methods --- .../java/me/goudham/ClipboardHistory.java | 111 +++++++++++++++ .../java/me/goudham/ClipboardListener.java | 52 +++++++ .../java/me/goudham/view/ClipboardView.form | 18 +-- .../java/me/goudham/view/ClipboardView.java | 131 +++++++++++------- 4 files changed, 254 insertions(+), 58 deletions(-) create mode 100644 src/main/java/me/goudham/ClipboardHistory.java create mode 100644 src/main/java/me/goudham/ClipboardListener.java diff --git a/src/main/java/me/goudham/ClipboardHistory.java b/src/main/java/me/goudham/ClipboardHistory.java new file mode 100644 index 0000000..ea5bbe6 --- /dev/null +++ b/src/main/java/me/goudham/ClipboardHistory.java @@ -0,0 +1,111 @@ +package me.goudham; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.StringSelection; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.ListSelectionModel; +import javax.swing.SwingUtilities; + +// We are going to build the UI of our Clipboard History software +// We will use Swing API +public class ClipboardHistory extends JPanel implements ClipboardListener.EntryListener { + + // for the list of entries copied in clipboard + private final JList list; + private final DefaultListModel listModel; + private ListSelectionModel listSelectionModel; + + public ClipboardHistory() { + super(new BorderLayout()); + listModel = new DefaultListModel<>(); + list = new JList<>(listModel); + listSelectionModel = list.getSelectionModel(); + listSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + // we create a JScrollPane to embed our control pane + JScrollPane listPane = new JScrollPane(list); + JPanel controlPane = new JPanel(); + + // we add a button to let users copy old entries to the clipboard + final JButton button = new JButton("Copy"); + button.addActionListener(e -> { + String value = list.getSelectedValue(); + int index = list.getSelectedIndex(); + // remove selected index to avoid duplicate in our list ... + listModel.remove(index); + // copy to clipboard + copyToClipboard(value); + }); + + // we add the button + controlPane.add(button); + + JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); + add(splitPane, BorderLayout.CENTER); + + JPanel topHalf = new JPanel(); + topHalf.setLayout(new BoxLayout(topHalf, BoxLayout.LINE_AXIS)); + JPanel listContainer = new JPanel(new GridLayout(1, 1)); + listContainer.setBorder(BorderFactory.createTitledBorder("Entries")); + listContainer.add(listPane); + + topHalf.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5)); + topHalf.add(listContainer); + topHalf.setMinimumSize(new Dimension(100, 50)); + topHalf.setPreferredSize(new Dimension(100, 250)); + splitPane.add(topHalf); + + JPanel bottomHalf = new JPanel(new BorderLayout()); + bottomHalf.add(controlPane, BorderLayout.CENTER); + bottomHalf.setPreferredSize(new Dimension(450, 30)); + splitPane.add(bottomHalf); + } + + public void copyToClipboard(String value) { + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + StringSelection data = new StringSelection(value); + clipboard.setContents(data, data); + } + + public void createAndShowGUI() { + // We create a top JFrame + JFrame frame = new JFrame("Clipboard History"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + setOpaque(true); + frame.setContentPane(this); + frame.pack(); + frame.setVisible(true); // we display on the screen + + // we connect the Clipboard Listener to our UI + ClipboardListener listener = new ClipboardListener(); + listener.setEntryListener(this); + listener.start(); + } + + @Override + public void onCopy(String data) { + // we add new entry on the top of our list + listModel.add(0, data); + } + + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> new ClipboardHistory().createAndShowGUI()); + } + +} diff --git a/src/main/java/me/goudham/ClipboardListener.java b/src/main/java/me/goudham/ClipboardListener.java new file mode 100644 index 0000000..7a84237 --- /dev/null +++ b/src/main/java/me/goudham/ClipboardListener.java @@ -0,0 +1,52 @@ +package me.goudham; + +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.ClipboardOwner; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; + +public class ClipboardListener extends Thread implements ClipboardOwner { + + public interface EntryListener { + void onCopy(String data); + } + + private final Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + private EntryListener entryListener; + + @Override + public void lostOwnership(Clipboard c, Transferable t) { + try { + System.out.println("Sleeping for 200 milliseconds"); + sleep(200); + } catch (Exception ignored) { } + + Transferable contents = c.getContents(currentThread()); + processContents(contents); + regainOwnership(c, contents); + } + + public void processContents(Transferable t) { + try { + String what = (String) (t.getTransferData(DataFlavor.stringFlavor)); + + if (entryListener != null) { + entryListener.onCopy(what); + } + } catch (Exception ignored) { } + } + + public void regainOwnership(Clipboard c, Transferable t) { + c.setContents(t, this); + } + + public void run() { + Transferable transferable = clipboard.getContents(this); + regainOwnership(clipboard, transferable); + } + + public void setEntryListener(EntryListener entryListener) { + this.entryListener = entryListener; + } +} \ No newline at end of file diff --git a/src/main/java/me/goudham/view/ClipboardView.form b/src/main/java/me/goudham/view/ClipboardView.form index 4785fa9..fa331d4 100644 --- a/src/main/java/me/goudham/view/ClipboardView.form +++ b/src/main/java/me/goudham/view/ClipboardView.form @@ -1,7 +1,6 @@
- - + @@ -16,6 +15,7 @@ + @@ -26,7 +26,8 @@ - + + @@ -36,18 +37,18 @@ + + + - - - - + @@ -57,7 +58,8 @@ - + + diff --git a/src/main/java/me/goudham/view/ClipboardView.java b/src/main/java/me/goudham/view/ClipboardView.java index 1cf7c6f..ebe2b55 100644 --- a/src/main/java/me/goudham/view/ClipboardView.java +++ b/src/main/java/me/goudham/view/ClipboardView.java @@ -1,69 +1,100 @@ package me.goudham.view; +import me.goudham.ClipboardListener; import me.goudham.controller.MyClipboardContent; import me.goudham.model.TransferableImage; import javax.swing.*; +import java.awt.Color; +import java.awt.Dimension; import java.awt.Image; import java.awt.Toolkit; import java.awt.datatransfer.*; import java.io.IOException; -public class ClipboardView { - private JPanel Clipboard; - private JButton copyButton; - private JList clipboardContentList; - private JLabel title; - private JScrollPane scrollPane; +public class ClipboardView implements ClipboardListener.EntryListener { + private JPanel Clipboard; + private JButton copyButton; + private JList clipboardContentList; + private final DefaultListModel listModel; + private JLabel title; + private JScrollPane scrollPane; - public ClipboardView() { - scrollPane.setBorder(BorderFactory.createEmptyBorder()); + public ClipboardView() { + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + listModel = new DefaultListModel<>(); + clipboardContentList.setModel(listModel); - final java.awt.datatransfer.Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); - final MyClipboardContent previousContent = new MyClipboardContent<>(""); - final int[] count = { 0 }; +// final java.awt.datatransfer.Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); +// final MyClipboardContent previousContent = new MyClipboardContent<>(""); +// final int[] count = {0}; +// +// systemClipboard.addFlavorListener(e -> { +// MyClipboardContent clipboardContent = null; +// try { +// if (systemClipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { +// String stringContent = (String) systemClipboard.getData(DataFlavor.stringFlavor); +// clipboardContent = new MyClipboardContent<>(stringContent); +// } else if (systemClipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)) { +// Image imageContent = (Image) systemClipboard.getData(DataFlavor.imageFlavor); +// clipboardContent = new MyClipboardContent<>(imageContent); +// } +// } catch (UnsupportedFlavorException | IOException unsupportedFlavorException) { +// unsupportedFlavorException.printStackTrace(); +// } +// +// if (previousContent.getContent().equals(clipboardContent.getContent())) { +// count[0]++; +// } +// +// if (!previousContent.getContent().equals(clipboardContent.getContent()) || count[0] > 1) { +// systemClipboard.setContents(new TransferableImage((Image) clipboardContent.getContent()), null); +//// systemClipboard.setContents(new StringSelection((String) clipboardContent.getContent()), null); +// System.out.println("The clipboard contains: " + clipboardContent.getContent()); +// +// DefaultListModel demoList = new DefaultListModel<>(); +// int size = clipboardContentList.getModel().getSize(); +// demoList.addElement("0. " + clipboardContent.getContent()); +// for (int i = 0; i < size; i++) { +// demoList.addElement((i + 1) + ". " + clipboardContentList.getModel().getElementAt(i)); +// } +// clipboardContentList.setModel(demoList); +// +// previousContent.setContent(clipboardContent.getContent()); +// count[0] = 0; +// } +// }); + } - systemClipboard.addFlavorListener(new FlavorListener() { - @Override - public void flavorsChanged(FlavorEvent e) { - MyClipboardContent clipboardContent = null; - try { - if (systemClipboard.isDataFlavorAvailable(DataFlavor.stringFlavor)) { - String stringContent = (String) systemClipboard.getData(DataFlavor.stringFlavor); - clipboardContent = new MyClipboardContent<>(stringContent); - } else if (systemClipboard.isDataFlavorAvailable(DataFlavor.imageFlavor)) { - Image imageContent = (Image) systemClipboard.getData(DataFlavor.imageFlavor); - clipboardContent = new MyClipboardContent<>(imageContent); - } - } catch (UnsupportedFlavorException | IOException unsupportedFlavorException) { - unsupportedFlavorException.printStackTrace(); - } + public JPanel getClipboard() { + return Clipboard; + } - if (previousContent.getContent().equals(clipboardContent.getContent())) { - count[0]++; - } + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> new ClipboardView().createAndShowGUI()); + } - if (!previousContent.getContent().equals(clipboardContent.getContent()) || count[0] > 1) { - systemClipboard.setContents(new TransferableImage((Image) clipboardContent.getContent()), null); -// systemClipboard.setContents(new StringSelection((String) clipboardContent.getContent()), null); - System.out.println("The clipboard contains: " + clipboardContent.getContent()); + private void createAndShowGUI() { + ClipboardListener listener = new ClipboardListener(); + listener.setEntryListener(this); + listener.start(); - DefaultListModel demoList = new DefaultListModel<>(); - int size = clipboardContentList.getModel().getSize(); - demoList.addElement("0. " + clipboardContent.getContent()); - for (int i = 0; i < size; i++) { - demoList.addElement((i + 1) + ". " + clipboardContentList.getModel().getElementAt(i)); - } - clipboardContentList.setModel(demoList); + JFrame jFrame = new JFrame(); + jFrame.setTitle("My Clipboard History"); + jFrame.setContentPane(Clipboard); + jFrame.setVisible(true); + jFrame.setAlwaysOnTop(true); + jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + jFrame.getContentPane().setBackground(new Color(1, 3, 25)); + jFrame.setPreferredSize(new Dimension(1000, 680)); + jFrame.setMaximumSize(new Dimension(1000, 680)); + jFrame.setResizable(false); + jFrame.pack(); + jFrame.setLocationRelativeTo(null); + } - previousContent.setContent(clipboardContent.getContent()); - count[0] = 0; - } - } - }); - } - - public JPanel getClipboard() { - return Clipboard; - } + @Override + public void onCopy(String data) { + listModel.add(0, data); + } }