Link to home
Start Free TrialLog in
Avatar of comsult
comsult

asked on

Disable printscreen in Java application.

I have created a Java browser which runs a local HTML manual. I don't want my users to be able to copy the information via printscreen. Is there any way to prevent this ? I need a resolution quickly hence the large amount of points offered.
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Not without JNI, if at all
 Take a look here: http://forum.java.sun.com/thread.jsp?thread=194577&forum=52&message=640226 someone suggests you might be able to do it with Windows Management Interface (if you are running Java udner Win32).
A whole SDK seems to be something of an overkill when all you need to do is consume key messages from the print screen key.
Avatar of comsult
comsult

ASKER

Thanks for the comments. I will have a look at the JNI and the WMI. I do need to keep the solution as simple as possible as the browser runs from a JAR on a CD. Is there an actual key mapping that is called when printscreen is used that could be captured ? I suppose it would also have to look at ALT printscreen as well.
Avatar of comsult

ASKER

Thanks for the comments. I will have a look at the JNI and the WMI. I do need to keep the solution as simple as possible as the browser runs from a JAR on a CD. Is there an actual key mapping that is called when printscreen is used that could be captured ? I suppose it would also have to look at ALT printscreen as well.
Avatar of comsult

ASKER

Thanks for the comments. I will have a look at the JNI and the WMI. I do need to keep the solution as simple as possible as the browser runs from a JAR on a CD. Is there an actual key mapping that is called when printscreen is used that could be captured ? I suppose it would also have to look at ALT printscreen as well.
... or implement a ClipboardMonitor. Every time the clipboard will contain a screen capture you should flush'it out.
Avatar of comsult

ASKER

Thanks for the comments. I will have a look at the JNI and the WMI. I do need to keep the solution as simple as possible as the browser runs from a JAR on a CD. Is there an actual key mapping that is called when printscreen is used that could be captured ? I suppose it would also have to look at ALT printscreen as well.
Avatar of comsult

ASKER

Something strange going on here, my comments posted once are quadrupled !

Ovi, a ClipboardMonitor sounds like an interesting idea. I'm still quite a novice when it comes to Java, is that difficult to implement ?
Avatar of comsult

ASKER

Something strange going on here, my comments posted once are quadrupled !

Ovi, a ClipboardMonitor sounds like an interesting idea. I'm still quite a novice when it comes to Java, is that difficult to implement ?
Not really. I will post soon details if you are interested.

About multiplication, don't reload the question page with the reload button of your browser. You have a link in the top left corner of your question page for that ("Reload This Question").
ASKER CERTIFIED SOLUTION
Avatar of Ovi
Ovi

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This method is unused so you should remove'it:

     private int getCurrentEventModifiers() {
          int modifiers = 0;
          AWTEvent currentEvent = EventQueue.getCurrentEvent();
          if (currentEvent instanceof InputEvent) {
               modifiers = ((InputEvent) currentEvent).getModifiers();
          } else
               if (currentEvent instanceof ActionEvent) {
                    modifiers = ((ActionEvent) currentEvent).getModifiers();
               }
          return modifiers;
     }
That's some pretty neat code Ovi :-) Although you have to make a few adjustments to run it on earlier java versions than 1.4.
Avatar of comsult

ASKER

Thank you very much for this, it is exactly what I need. Thanks to everyone else for their comments also.
Thanks for the points(comsult) and for the nice laugh(schybert) :-).
This is a little more cleaner version, and a final one.

import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;

public final class ClipboardMonitor extends Observable implements ClipboardOwner {
     private static ClipboardMonitor monitor = null;

     private ClipboardMonitor() {
          gainOwnership();
     }

     private void gainOwnership() {
          Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();
          try {
               Transferable content = clip.getContents(null);
               DataFlavor[] f = content.getTransferDataFlavors();
               boolean imageDetected = false;
               for (int i = 0; i < f.length; i++) {
                    if (f[i].equals(DataFlavor.imageFlavor)) {
                         imageDetected = true;
                         break;
                    }
               }
               if (imageDetected) {
                    System.out.println("Image content detected");
                    flushClipboard();
               } else {
                    clip.setContents(content, this);
               }
               setChanged();
               notifyObservers(content);
          } catch (IllegalArgumentException istateexception) {
               istateexception.printStackTrace();
          } catch (Exception ioexception) {
               ioexception.printStackTrace();
          }
     }

     public void lostOwnership(Clipboard clipboard, Transferable contents) {
          System.out.println("Ownership lost ...");
          new Thread(new Runnable() {
               public void run() {
                    try {
                         Thread.sleep(200);
                         gainOwnership();
                    } catch (Exception e) {
                         e.printStackTrace();
                    }
               }
          }).start();
     }

     public void flushClipboard() {
          Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(""), this);
     }
     
     public Object clone() throws CloneNotSupportedException {
          throw new CloneNotSupportedException("There can be only one instance of this monitor!");
     }

     public static final ClipboardMonitor getMonitor() {
          if (monitor == null)
               monitor = new ClipboardMonitor();
          return (monitor);
     }

     public static void main(String[] args) {
          JFrame f = new JFrame();
          ClipboardMonitor monitor = ClipboardMonitor.getMonitor();
          monitor.addObserver(new Observer() {
               public void update(Observable o, Object arg) {
                    System.out.println("Clipboard has been regained!");
               }
          });
          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          f.setSize(500, 100);
          f.setVisible(true);
     }
}
For people who want to use this cool tool with java 1.3.1 you have to create the imageFlavor yourself since the static field in DataFlavor didn't exist back then. Just create your own imageFlavor object like this:

private static final DataFlavor IMAGE_FLAVOR = new DataFlavor(java.awt.Image.class, "image/x-java-image");

When I mentioned adjustments in plural I had tried it on java 1.2.2 :-)
Yes, indeed, the other solution is to test the contents of the default DataFlavor from clipboard using following methods:
                    //                    System.out.println("Name: " + f[i].getHumanPresentableName());
                    //                    System.out.println("MimeType: " + f[i].getMimeType());
                    //                    System.out.println("PrimaryType: " + f[i].getPrimaryType());
                    //                    System.out.println("SubType: " + f[i].getSubType());

If you test with those you'll be abble to see if the clipboard content is a image or not and take necesary actions. If I remember corectly the primary type is allways "image", the name is "image/x-java-image" and so on. An 'if' on those properties will be enough to decide if you have a image or not.
Avatar of comsult

ASKER

Thanks again Ovi, I am using Java 1.4 so this is perfect. I appreciate all the help from everyone :-)