?
Solved

Disable printscreen in Java application.

Posted on 2003-03-25
19
Medium Priority
?
1,388 Views
Last Modified: 2013-11-23
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
Comment
Question by:comsult
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 6
  • 2
  • +2
19 Comments
 
LVL 86

Expert Comment

by:CEHJ
ID: 8202065
Not without JNI, if at all
0
 
LVL 35

Expert Comment

by:girionis
ID: 8202078
 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
 
LVL 86

Expert Comment

by:CEHJ
ID: 8202101
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
Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

 

Author Comment

by:comsult
ID: 8202147
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
 

Author Comment

by:comsult
ID: 8202152
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
 

Author Comment

by:comsult
ID: 8202157
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8202160
... or implement a ClipboardMonitor. Every time the clipboard will contain a screen capture you should flush'it out.
0
 

Author Comment

by:comsult
ID: 8202167
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
 

Author Comment

by:comsult
ID: 8202186
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
 

Author Comment

by:comsult
ID: 8202194
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8202196
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
 
LVL 9

Accepted Solution

by:
Ovi earned 1800 total points
ID: 8202555
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8202602
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
 
LVL 3

Expert Comment

by:schybert
ID: 8203464
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
 

Author Comment

by:comsult
ID: 8204949
Thank you very much for this, it is exactly what I need. Thanks to everyone else for their comments also.
0
 
LVL 9

Expert Comment

by:Ovi
ID: 8208420
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
 
LVL 3

Expert Comment

by:schybert
ID: 8208611
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
 
LVL 9

Expert Comment

by:Ovi
ID: 8208916
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
 

Author Comment

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

Featured Post

Optimize your web performance

What's in the eBook?
- Full list of reasons for poor performance
- Ultimate measures to speed things up
- Primary web monitoring types
- KPIs you should be monitoring in order to increase your ROI

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Java Flight Recorder and Java Mission Control together create a complete tool chain to continuously collect low level and detailed runtime information enabling after-the-fact incident analysis. Java Flight Recorder is a profiling and event collectio…
In this post we will learn how to make Android Gesture Tutorial and give different functionality whenever a user Touch or Scroll android screen.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
This video teaches viewers about errors in exception handling.
Suggested Courses
Course of the Month9 days, 19 hours left to enroll

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question