站内搜索: 请输入搜索关键词
当前页面: 在线文档首页 > Java Tutorial 5.0 英文版

Solving Common 2D Graphics Problems - Java Tutorial 5.0 英文版

The JavaTM Tutorial
Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail Search
Feedback Form

Trail: 2D Graphics

Lesson: Solving Common 2D Graphics Problems

Also see Improving Printing Performance (in the 2D Graphics trail), which has tips for solving printing performance problems.

Problem: I can run my Java2D applets with appletviewer, but they do not run in my browser. The Java console of the browser says: defn not found for java/awt/Graphics2D.


Problem: How can you write over a previous image? Our problem is that our applet displays an image of a map, but when we draw a line on top of the map, the line overwrites the map.
  • You should try drawing your image into a BufferedImage. Then, draw the BufferedImage into the Graphics2D context and then draw the line to the Graphics2D context. Here's a sample that does this:
    Map_Line.java
    Just substitute the name of your image for images/bld.jpg.

Problem: How do you create a BufferedImage from a gif or jpeg file?
  • To create a BufferedImage from a gif or jpeg, you load your gif or jpeg into an Image object and then draw the Image to the BufferedImage object. The following snippet illustrates this:
    Image img = getImage("picture.gif");
    int width = img.getWidth(this);
    int height = img.getHeight(this);
    
    BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D biContext = bi.createGraphics();
    biContext.drawImage(img, 0, 0, null);
    
    getImage is an Applet method. If you have an application, you can use:
    Image img = Toolkit.getDefaultToolkit().getImage("picture.gif");
    try {
        MediaTracker tracker = new MediaTracker(this);
        tracker.addImage(img, 0);
                    tracker.waitForID(0);
    } catch (Exception e) {}
    int width = img.getWidth(this);
    int height = img.getHeight(this);
    BufferedImage bi = new BufferedImage(width, height,
    BufferedImage.TYPE_INT_RGB);
    Graphics2D biContext = bi.createGraphics();
    biContext.drawImage(img, 0, 0, null);
    
    BufferedImage.TYPE_INT_RGB is one of many BufferedImage types. For more information, see:
    java.awt.image.BufferedImage (in the API reference documentation)
    You need to create a Graphics2D context for the BufferedImage by using the createGraphics method. Then, you can use the drawImage method from the Graphics2D class to draw the image into the buffered image. In the ImageOps sample on the "Filtering a BufferedImage" page, images are drawn into buffered images. You could also look at this page: http://java.sun.com/products/java-media/2D/samples/index.html (outside of the tutorial), which has links to samples that use gifs, jpegs and BufferedImage objects.

Problem: I can't compile the source code for StrokeAndFill.java and Transform.java with jdk1.2beta4.
  • The TextLayout.getOutline implementation was changed between beta4 and the current JDK. The new implementation takes only an AffineTransform as an argument. You need to download the new JDK to run the sample.

Problem: Is there a way to specify a formula for a line and draw a picture according to it?
  • Using line segments would be the easiest way. You can represent the line segments either by filling a GeneralPath with them, or by implementing Shape and PathIterator and reading back the line segments "on demand" to save the intermediate storage of the GeneralPath object. Note that you could analyze your formula and determine how to match it with cubic or quadratic bezier curves, but this is probably overkill.

Problem: How do I add text to a graphic field at a certain location?
  • A class called Graphics2D was added with JDK 1.2 (now called Java 2 SDK). This class extends Graphics. There are drawString methods in Graphics2D that you can use. If you will be rotating the text, you should use Graphics2D rather than Graphics so that you can perform rotations and other transformations on your Graphics2D context.

    The Transform sample in the 2D tutorial doesn't use drawString to render the text. What happens is that a TextLayout is created from the string "Text." The TextLayout allows us to create a Shape object from the String by getting it's outline. We enter this Shape into the shapes array, along with the rectangle and ellipse shapes. When we draw or fill the selected Shape from the shapes array, we call g2.draw(Shape) or g2.fill(Shape).

    You could use drawString to render the text to the Graphics2D context and then call g2.rotate (angle of rotation). This will rotate everything that you've already rendered into the Graphics2D context, however. So, you could reset the g2 context transform each time you want to transform a particular image or piece of text in the context separately from other things that have already been rendered into the g2 context.

    There are other 2D samples you can look at here: http://java.sun.com/products/java-media/2D/samples/index.html (outside of the tutorial)

    They are a little more advanced than the tutorial samples. If you will be transforming text, I would recommend looking at the sample, "Transformation of Characters" from the Fonts group of samples. There is another one in the Transforms group of samples that performs animation of both text and images rotating, scaling and translating. It is the third sample in this group. This sample does use g2.drawString. It uses g2.setTransform to reset the transformation for each object to be transformed. If you will be using Swing components in your interface, keep in mind that these components are affected when you use g2.setTransform. To fix this problem, you can perform all of your drawing in a BufferedImage and then draw this BufferedImage to the g2 context when you are finished drawing. This sample solves the problem in this way.


Problem: I noticed your comment on the bottom of Creating and Deriving Fonts regarding bug 4155852. This bug has been closed with no action taken. Is it true that you can't apply a style to fonts such as Arial?
    The problem is that font-to-style matching is not working properly for physical fonts (such as Arial or Palatino). You can only apply styles to logical fonts at this point (such as Dialog or SansSerif). As a workaround until the bug is fixed, you could do the following:
     Font f = new Font("Palatino Bold", Font.PLAIN, 12); 
    
    instead of:
                       
     Font f = new Font("Palatino", Font.BOLD, 12);
    


Previous Page Lesson Contents Next Page Start of Tutorial > Start of Trail Search
Feedback Form

Copyright 1995-2005 Sun Microsystems, Inc. All rights reserved.