• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

How to listen to the clipboard?

 
Ranch Hand
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
Rancher
Posts: 5008
38
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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.
 
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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:
 
marc weber
Sheriff
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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.)
 
Ranch Hand
Posts: 502
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 11343
Mac Safari Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

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
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
Posts: 30
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
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
* https://coderanch.com/t/377833/java/java/listen-clipboard
*
*/

Thanks in advance.

Ahmet Aksoy
 
reply
    Bookmark Topic Watch Topic
  • New Topic