Received: from PACIFIC-CARRIER-ANNEX.MIT.EDU by po10.MIT.EDU (5.61/4.7) id AA00635; Wed, 12 May 99 06:31:07 EDT Received: from hermes.javasoft.com by MIT.EDU with SMTP id AA28033; Wed, 12 May 99 06:30:59 EDT Received: by hermes.java.sun.com (SMI-8.6/SMI-SVR4) id KAA17974; Wed, 12 May 1999 10:55:02 GMT Date: Wed, 12 May 1999 10:55:02 GMT Message-Id: <199905121055.KAA17974@hermes.java.sun.com> X-Mailing: 107 From: JDCTechTips@sun.com Subject: JDC Tech Tips May 11, 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) Tech Tips, May 11, 1999. This issue covers: * Custom Carets * Reference Objects Notice: To make it easier to identify specific issues of Tech Tips, we are using the publishing date only. We are no longer using volume and number to identify issues of Tech Tips. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CUSTOM CARETS In the Java(tm) programming language, the term "cursor" refers to a visual location indicator that is typically set by the mouse. The term "caret" refers to a location indicator used while inserting text. A cursor set by the mouse is commonly rendered as a pointer, while a caret is often drawn as a thin vertical line between text characters. In the Java 2 platform, there's a new feature that allows you to define custom carets, that is, carets of different shapes. To see how this works, let's look at a short example: import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; class MyCaret extends DefaultCaret { // draw the caret public void paint(Graphics g) { if (!isVisible()) return; try { JTextComponent c = getComponent(); int dot = getDot(); Rectangle r = c.modelToView(dot); g.setColor(c.getCaretColor()); g.drawLine(r.x, r.y + r.height - 1, r.x + 3, r.y + r.height - 1); } catch (BadLocationException e) { System.err.println(e); } } // specify the size of the caret for redrawing // and do repaint() -- this is called when the // caret moves protected synchronized void damage(Rectangle r) { if (r == null) return; x = r.x; y = r.y + r.height - 1; width = 4; height = 1; repaint(); } } public class caret { public static void main(String args[]) { JFrame frame = new JFrame("Caret demo"); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); JTextArea area = new JTextArea(10, 40); area.setCaret(new MyCaret()); JPanel panel = new JPanel(); panel.add(area); frame.getContentPane().add("Center", panel); frame.pack(); frame.setVisible(true); } } A Caret interface is defined in Java Foundation Classes (JFC)(TM) Project Swing components. The interface specifies caret properties such as paint and setBlinkRate methods. DefaultCaret is an implementation of this interface. To define a custom caret, you extend a subclass, MyCaret, from this superclass. To draw the caret, you need to first determine the current X,Y location. You do this by obtaining the current caret location as an offset into the text (getDot). This location is then converted into an X,Y position using modelToView. In other words, one way of describing the position of the caret in some text is as a character offset into the text. Another, lower-level, approach describes the position as an X,Y coordinate on the screen. To draw the caret, the screen coordinate is required. The caret is rendered as a horizontal line with width 4 and height 1, below and to the left of the current character. In addition to the paint method for MyCaret, there's another important method that you need to include, the damage method. If you remove the damage method from the example above, you will notice that moving the cursor leaves debris, that is, stray pixels. The damage method specifies the bounding box for the custom caret drawn by paint. Without this method, the text area is not correctly refreshed as the caret moves. So the damage method is called repeatedly. You can use the custom caret feature to define different types of carets, such as an I-beam caret. REFERENCE OBJECTS In the Java programming language, the term "reference" usually refers to addresses of objects, for example, in passing an object argument (by reference) to a method that has a reference parameter. Java 2 software introduces another use of the term, the Reference class. An object of one of the Reference classes (WeakReference, SoftReference, PhantomReference) contains a "referent." The referent is an arbitrary Java object of any type. In other words, a Reference object is a wrapper for a reference. It's somewhat analogous to an Integer object being a wrapper for an integer. The reason why this feature is important is that the Java garbage collector knows about the Reference classes, and interacts with them. To see how this works, consider an example: import java.lang.ref.*; public class ref { static Reference weakref; static void f() { String s = new String("abc"); weakref = new WeakReference(s); } public static void main(String args[]) { // create garbage (a String with no references to it) f(); System.out.println("Before GC = " + weakref.get()); // run garbage collector until no // more memory freed up Runtime rt = Runtime.getRuntime(); long free = rt.freeMemory(); long oldfree; do { oldfree = free; rt.gc(); free = rt.freeMemory(); } while (free > oldfree); System.out.println("After GC = " + weakref.get()); } } This program starts up and immediately calls method f, which in turn, creates a string. There are situations where an application would like to have some control over the process of garbage collection, and the Reference classes offer this. In the example above, a WeakReference object is set up, with the string as its referent. When the method returns, the string is garbage (except for the WeakReference object referring to it). But the garbage collector has not run yet, and so the referent of the WeakReference object is accessible via the get method. Then the garbage collector runs, iterating until no additional memory is freed. The referent is checked again, and this time it's null. In other words, when garbage collection occurs, the referent is "cleared." It's also possible to specify a queue for the Reference object. The Reference object is added to the queue ("enqueued") at some point after the referent is cleared. This might not seem like very much, but it's quite useful in a variety of applications. For example, one of the collection classes in the Java 2 platform, WeakHashMap, makes use of WeakReference objects. A WeakHashMap has the property that keys in the map are discarded when no longer in use. Or to say it more precisely, unused keys are subject to being discarded when the garbage collector runs. Conceptually, this mechanism is implemented by using a WeakReference object as a wrapper on the actual key, and then periodically examining a queue of WeakReference objects whose referents (the actual keys) have been cleared by the garbage collector. Another example is the use of SoftReference objects, whose referents are cleared before the Java Virtual Machine throws an OutOfMemory error. You can use this type of Reference object to implement caches, where a cached data structure is normally saved, but may be given up by the garbage collector in response to memory demand. . . . . . . . . . . . . . . . . . . . . . . . . - 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 May 11, 1999