• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1432
  • Last Modified:

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.
0
comsult
Asked:
comsult
  • 8
  • 6
  • 2
  • +2
1 Solution
 
CEHJCommented:
Not without JNI, if at all
0
 
girionisCommented:
 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).
0
 
CEHJCommented:
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
comsultAuthor Commented:
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.
0
 
comsultAuthor Commented:
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.
0
 
comsultAuthor Commented:
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.
0
 
OviCommented:
... or implement a ClipboardMonitor. Every time the clipboard will contain a screen capture you should flush'it out.
0
 
comsultAuthor Commented:
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.
0
 
comsultAuthor Commented:
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 ?
0
 
comsultAuthor Commented:
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 ?
0
 
OviCommented:
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").
0
 
OviCommented:
Here is the necesary code. The ClipboardMonitor class extends Observable (from a old source of mine) to allow notification to other interested objects. Yu can get rid of this feature if is not relevant for you. Just run this class and play a little with PrintScreen. If the content is a image will be overwriten by a dummy text. This works for PrintScreen and Alt-PrintScreen. Be aware that as long as the application is running, the users (including you :-) ), will be not able to capture screenshots, even of other applications. This should not bother you too much.

import java.awt.AWTEvent;
import java.awt.EventQueue;
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.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.io.IOException;
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;

      public 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++) {
                        //                        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 (f[i].equals(DataFlavor.imageFlavor)) {
                              imageDetected = true;
                              break;
                        }
                  }
                  if (imageDetected) {
                        System.out.println("Image content detected");
                        Transferable t = new Transferable() {
                              public DataFlavor[] getTransferDataFlavors() {
                                    return new DataFlavor[] { DataFlavor.stringFlavor };
                              }
                              public boolean isDataFlavorSupported(DataFlavor flavor) {
                                    return false;
                              }
                              public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                                    return "dummy text instead of snapshot image";
                              }
                        };
                        clip.setContents(t, this);
                  } else {
                        clip.setContents(content, this);
                  }
                  setChanged();
                  notifyObservers(content);
            } catch (IllegalArgumentException istateexception) {
                  istateexception.printStackTrace();
            } catch (Exception ioexception) {
                  ioexception.printStackTrace();
            }
      }

      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;
      }

      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(""), null);
      }

      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);
      }
}
0
 
OviCommented:
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;
     }
0
 
schybertCommented:
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.
0
 
comsultAuthor Commented:
Thank you very much for this, it is exactly what I need. Thanks to everyone else for their comments also.
0
 
OviCommented:
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);
     }
}
0
 
schybertCommented:
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 :-)
0
 
OviCommented:
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.
0
 
comsultAuthor Commented:
Thanks again Ovi, I am using Java 1.4 so this is perfect. I appreciate all the help from everyone :-)
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 8
  • 6
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now