Received: from SOUTH-STATION-ANNEX.MIT.EDU by po10.MIT.EDU (5.61/4.7) id AA16813; Wed, 14 Jul 99 05:56:57 EDT Received: from hermes.javasoft.com by MIT.EDU with SMTP id AA20245; Wed, 14 Jul 99 05:52:26 EDT Received: by hermes.java.sun.com (SMI-8.6/SMI-SVR4) id KAA23098; Wed, 14 Jul 1999 10:21:07 GMT Date: Wed, 14 Jul 1999 10:21:07 GMT Message-Id: <199907141021.KAA23098@hermes.java.sun.com> X-Mailing: 130 From: JDCTechTips@sun.com Subject: JDC Tech Tips July, 1999 To: JDCMember@sun.com Reply-To: JDCTechTips@sun.com Errors-To: JDCMailErrors@sun.com Precedence: junk Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Beyond Email 2.1 J D C T E C H T I P S TIPS, TECHNIQUES, AND SAMPLE CODE WELCOME to the Java Developer Connection(sm) (JDC) Tech Tips, July 13, 1999. This issue covers: * Undoing Text Edits * Adding Security Features to Applications - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UNDOING TEXT EDITS A new feature in Java Foundation Classes (JFC) Project Swing is the ability to undo text edits. For example, suppose you have a JTextArea that you use in some application. You might want to keep track of user edits to the text area, and then possibly undo some of them to change the content of the area back to some previous state. Consider the following example that uses undo: import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.undo.*; public class undo { static UndoManager undomanager; static class UndoHandler implements UndoableEditListener { public void undoableEditHappened(UndoableEditEvent e) { if (undomanager != null) { undomanager.addEdit(e.getEdit()); //System.out.println(e.getEdit()); } } } public static void main(String args[]) { // set up frames, panels, text areas JFrame frame = new JFrame("Undo demo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); final JTextArea textarea = new JTextArea(10, 40); JPanel textpanel = new JPanel(); textpanel.add(new JScrollPane(textarea)); textarea.getDocument().addUndoableEditListener( new UndoHandler()); // create buttons and set up listeners for them JPanel buttonpanel = new JPanel(); JButton startbutton = new JButton("Start Edits"); JButton undobutton = new JButton("Undo Edits"); startbutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { undomanager = new UndoManager(); undomanager.setLimit(1000); textarea.requestFocus(); } }); undobutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (undomanager != null) { undomanager.end(); undomanager.undo(); undomanager = null; } else { Toolkit.getDefaultToolkit().beep(); } textarea.requestFocus(); } }); buttonpanel.add(startbutton); buttonpanel.add(undobutton); panel.add("North", textpanel); panel.add("South", buttonpanel); // make frame visible frame.getContentPane().add("Center", panel); frame.pack(); frame.setVisible(true); } } The example sets up a JTextArea in the usual way, and then adds an UndoableEditListener to the area's underlying Document object. This has the effect of setting up a listener for all document edits. For example, if a character is added to the text area, this constitutes an edit, and the listener is notified. An object of the UndoManager class is used to collect edits. This object is set up when the Start Edits button is selected, and then edits are accumulated. An edit limit of 1000 is set, meaning that at most 1000 edits are accumulated in the UndoManager object. If you uncomment the "System.out.println" statement in the example, you can look at a description of each edit as it comes in. When Undo Edits is selected, all of the accumulated edits are undone. For example, suppose that you enter the letters "abc" into the text area, then select Start Edits, then add, delete, cut, copy, and paste text at will, and then select Undo Edits. This sequence puts you back where you started, with only "abc" in the text area. It is also possible to redo undone edits using the "redo" method of UndoManager. You can use undo/redo in other areas besides text. The UndoableEdit interface and the AbstractUndoableEdit class provide a framework for undo support, and can be applied in a variety of contexts. ADDING SECURITY FEATURES TO APPLICATIONS Java(tm) security has many aspects to it, and in this tip, we illustrate one simple technique for adding security features to applications. This technique demonstrates how permissions in a central policy file can be used to enable application features. Note that this tip assumes the standard Java 2 default security setup, which may have been modified in your local environment. The first thing to look at is a dummy application: import java.security.*; import local.*; public class perm { public static void main(String args[]) { MyPermission myp = new MyPermission("perm1"); try { AccessController.checkPermission(myp); System.out.println("Permission granted"); } catch (AccessControlException e) { System.out.println("Permission denied"); } } } MyPermission is a class, and "myp" an object of that class. The myp object represents a permission, that is, something that the application is allowed to do. This class resides in a package called "local" somewhere on your local system. The class itself looks like this: package local; import java.security.*; public class MyPermission extends BasicPermission { public MyPermission(String s) {super(s);} public MyPermission(String s, String t) {super(s, t);} } The class simply defines a couple of constructors, that pass through their arguments to the superclass, java.security.BasicPermission. So there is an object of a local permission type, representing some local policy. AccessController.checkPermission is called with this object as its argument, and it throws an AccessControlException if access is not granted. By default this application will print "Permission denied", that is, the permission "perm1" for the permission class "MyPermission" is denied. But how does checkPermission know whether a permission should be allowed or denied? In the default security setup, permissions are declared in the file: jre/lib/security/java.policy under the installation root, and the "master security properties file" is: jre/lib/security/java.security If you add a line to java.policy just after "grant {", like this: grant { permission local.MyPermission "perm1"; then you've enabled this permission locally. But it's more complicated than simply editing this file. You might not have the right to edit a central policy file on your local system. So the security properties file allows an administrator to specify which policy files are checked, with the default being: policy.url.1=file:${java.home}/lib/security/java.policy policy.url.2=file:${user.home}/.java.policy In other words, the central file is checked, along with a file you have control over in your home directory. If you want to run the above example without editing jre/lib/security/java.policy, you can instead create a file, ".java.policy", in your home directory. Here is the content of the local .java.policy file: grant { permission local.MyPermission "perm1"; }; This feature does not advance the enforcement of centralized policies. So an administrator may disable the line in the java.security file that allows for checking of local policy files. Another aspect of specifying policy files is the default feature that allows specification of a policy file on the command line: java -Djava.security.policy=pathname The line in the java.security file that reads: policy.allowSystemProperty=true can be toggled to "false" to disallow this type of override. . . . . . . . . . . . . . . . . . . . . . . . . - NOTE The names on the JDC mailing list are used for internal Sun Microsystems(tm) purposes only. To remove your name from the list, see Subscribe/Unsubscribe below. - FEEDBACK Comments? Send your feedback on the JDC Tech Tips to: JDCTechTips@Sun.com - SUBSCRIBE/UNSUBSCRIBE The JDC Tech Tips are sent to you because you elected to subscribe when you registered as a JDC member. To unsubscribe from JDC Email, go to the following address and enter the email address you wish to remove from the mailing list: http://developer.java.sun.com/unsubscribe.html To become a JDC member and subscribe to this newsletter go to: http://java.sun.com/jdc/ - ARCHIVES You'll find the JDC Tech Tips archives at: http://developer.java.sun.com/developer/TechTips/index.html - COPYRIGHT Copyright 1999 Sun Microsystems, Inc. All rights reserved. 901 San Antonio Road, Palo Alto, California 94303 USA. This document is protected by copyright. For more information, see: http://developer.java.sun.com/developer/copyright.html The JDC Tech Tips are written by Glen McCluskey. JDC Tech Tips July 13, 1999