aspose file tools*
The moose likes Java in General and the fly likes How to listen to the clipboard? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "How to listen to the clipboard?" Watch "How to listen to the clipboard?" New topic
Author

How to listen to the clipboard?

Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
Hi,
I have a dictionary application.
Now I want my application to listen to the system clipboard events, and when it finds a string copied to the clipboard, get it, find its meaning, and display the result in a (pop-up?) window.
It is easy to make the required transfer manually. Instead, I want it to be made automatically.
For example, while you were browsing on the internet, a simple select-copy will give the definition of that selection. I want to obtain a user friendly solution.
Do you have any suggestions?
Thanks in advance.
Ahmet Aksoy
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 686
Don't know of any listeners for clipboard events.
Possibly you could have your application poll the clipboard using a timer.
Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
Hi Norm,
Thanks for your suggestion.
This is what I will do, if I can't find a better solution.
I prefer an event tracking system still.
Thank you.
Ahmet Aksoy
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24184
    
  34

Ahmet,

Please don't repost the same question multiple times. Have a look at this for an explanation. I deleted the other copy of this thread.


[Jess in Action][AskingGoodQuestions]
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Ahmet Aksoy:
... I want my application to listen to the system clipboard events...

I'm not sure if this is workable, but here's an idea...

The clipboard "owner" is the client that last put an object on the clipboard. When a client becomes an owner, the previous owner is notified that it has lost ownership. So if you could make your app the owner, then it would be notified whenever the clipboard contents change. Your app could then perform its task on the contents, and get ownership back for the next occurrence.

:roll:


"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer
sscce.org
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

I was curious about this, so I gave it a test. The code below works for certain applications (e.g., when copying from WordPad or Lotus Notes). However, with other applications (e.g., MS Word or Paint), it throws a runtime exception at line 15. (Note that the thread needs to be killed manually with Ctrl+c.)

H:\Java>java BoardListener
Listening to board...
Processing: sun.awt.datatransfer.ClipboardTransferable@60aeb0
Processing: sun.awt.datatransfer.ClipboardTransferable@66848c
Processing: sun.awt.datatransfer.ClipboardTransferable@1d58aae
Processing: sun.awt.datatransfer.ClipboardTransferable@e09713
Processing: sun.awt.datatransfer.ClipboardTransferable@156ee8e
Processing: sun.awt.datatransfer.ClipboardTransferable@19b49e6
Processing: sun.awt.datatransfer.ClipboardTransferable@e0e1c6
Processing: sun.awt.datatransfer.ClipboardTransferable@1bf216a
Processing: sun.awt.datatransfer.ClipboardTransferable@1389e4
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: cannot open system clipboard
at sun.awt.windows.WClipboard.openClipboard(Native Method)
at sun.awt.datatransfer.ClipboardTransferable.<init>(Unknown Source)
at sun.awt.datatransfer.SunClipboard.getContents(Unknown Source)
at BoardListener.lostOwnership(BoardListener.java:15)
at sun.awt.datatransfer.SunClipboard$2.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)

at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
Hi Marc,
That's the clue that I wanted!
I'm sure the exceptions can be solved.
I'm starting to work on your sample code, immediately!
Thanks a lot!
Ahmet Aksoy
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Ahmet Aksoy:
...I'm sure the exceptions can be solved...

I think I found something.

It appears that when the Java app is notified that it has lost ownership, it sometimes needs to allow a small amount of time for the clipboard to be "ready."

By adding a very short sleep command to the method, I've been able to avoid the runtime exceptions. In experimenting with how long this needs to be, I found that sleep(0) is actually sufficient for large pieces of MS Word docs with complex formatting. However, this was not sufficient for a large bitmap copied to the clipboard. For this, sleep(10) worked most of the time; and when I increased this to sleep(20), I did not get any exceptions.

So rather than (or in addition to) guessing at the milliseconds needed to be "safe," you might want to catch this exception, wait a bit, then recall the method. Just be careful to avoid an infinite loop in case the exception is actually being caused by something else.

[ September 16, 2005: Message edited by: marc weber ]
Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
Hi Marc,
When I put a sleep(50) in your new code, it run perfectly in my system also without any exceptions.
(I found a very similar solution for the problem at http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_20562227.html)
Now, I will isolate the Strings from the clipboard for my application.
That's the solution I wanted!
Thanks you very much!
Ahmet Aksoy
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Ahmet Aksoy:
... I found a very similar solution for the problem at http://www.experts-exchange.com/Programming/Programming_Languages/Java/Q_20562227.html...

Interesting. I wonder how they arrived at a sleep value of 200. I think catching the exception might be the best way to handle this, rather than guessing at how much of a pause might be needed to cover all situations. You definitely don't want runtime exceptions.

(I'm thinking of a counter to keep track of how many times this exception is caught within the method. If it's still happening after a few attempts with sleep pauses, I would assume the exception has some other cause and re-throw it instead of trying to re-call the method.)
Jayesh Lalwani
Ranch Hand

Joined: Nov 05, 2004
Posts: 502
Why don't you query the clipboard whenever your application gets focus? User cannot copy anything into the clipboard from other apps without taking focus out of your clipboard. So, when user puts focus back on your app, query the clipboard and get the data
Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
I think Jayesh is right.
In lostOwnership method, there should be only the method to regain the ownership.
Data should be accessed whenever ownership regained.
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Jayesh Lalwani:
Why don't you query the clipboard whenever your application gets focus? ...

If the app is running in the background, and a user puts something on the system clipboard, then how would the app get focus?
marc weber
Sheriff

Joined: Aug 31, 2004
Posts: 11343

Originally posted by Ahmet Aksoy:
... In lostOwnership method, there should be only the method to regain the ownership...

I agree that ownership should probably be regained before the call to process the data (which might be done in a separate thread), but you still need the call to process. Or am I missing something?
Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
Hi Marc,
I tried your code in different combinations. However, the result did not change.
The exception occurs if this.sleep(x) was not used.
Also processContents() did not show any difference before and after regainOwnership().
I applied the code into my project, and now it works.
Thank you very much.
Ahmet Aksoy

package net.belletmen.arayuz;

import java.awt.*;
import java.awt.datatransfer.*;

import net.belletmen.arayuz.AnaPanel;

class ClipboardListener extends Thread implements ClipboardOwner {
public static AnaPanel aPanel;
Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
boolean bEnough=false;

public void run() {
Transferable trans = sysClip.getContents(this);
regainOwnership(trans);
///System.out.println("Listening to board...");
while(true) {
if(isitEnough())break;
}
///System.out.println("No more Listening...");
}

public void itisEnough(){
bEnough=true;
}
public void itisNotEnough(){
bEnough=false;
}
boolean isitEnough(){
return bEnough;
}
public void lostOwnership(Clipboard c, Transferable t) {
try{
sleep(200);
}catch(Exception e){
System.out.println("Exception: "+e);
}
try{
Transferable contents = c.getContents(this); //EXCEPTION
//processContents(contents);
regainOwnership(contents);
}catch(Exception e){e.printStackTrace();}
}

void processContents(Transferable t) {
if(isitEnough())return;
DataFlavor[] flavors=t.getTransferDataFlavors();
for(int i=flavors.length-1;i>=0;i--){
try{
Object o=t.getTransferData(flavors[i]);
//System.out.println("Flavor "+i+" gives "+o.getClass().getName());
if(o instanceof String){
///System.out.println("String="+(String)o);
aPanel.sozlukAlani.getjTextInput().setText(((String)o).toLowerCase());
aPanel.sozlukAlani.getGenelButton().doClick();
break;
}
}catch(Exception exp){exp.printStackTrace();}
}
///System.out.println("Processing: ");
}

void regainOwnership(Transferable t) {
sysClip.setContents(t, this);
processContents(t);
}

public static void main(String[] args) {
ClipboardListener b = new ClipboardListener();
b.itisNotEnough();
b.start();
}
}
Ahmet Aksoy
Ranch Hand

Joined: Apr 04, 2005
Posts: 30
Hi Marc,
I will use the ClipboardListener class in an open source project.
It's at http://belletmen.dev.java.net

I want to use the following lines at the head of the class code.
May I?

/*
* Created on 18.Sep.2005
* Original code from Marc Weber
* http://www.coderanch.com/t/377833/java/java/listen-clipboard
*
*/

Thanks in advance.

Ahmet Aksoy
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How to listen to the clipboard?