eXtropia: the open web technology company
Technology | Support | Tutorials | Development | About Us | Users | Contact Us
Resources
 ::   Tutorials
 ::   Presentations
Perl & CGI tutorials
 ::   Intro to Perl/CGI and HTML Forms
 ::   Intro to Windows Perl
 ::   Intro to Perl 5
 ::   Intro to Perl
 ::   Intro to Perl Taint mode
 ::   Sherlock Holmes and the Case of the Broken CGI Script
 ::   Writing COM Components in Perl

Java tutorials
 ::   Intro to Java
 ::   Cross Browser Java

Misc technical tutorials
 ::   Intro to The Web Application Development Environment
 ::   Introduction to XML
 ::   Intro to Web Design
 ::   Intro to Web Security
 ::   Databases for Web Developers
 ::   UNIX for Web Developers
 ::   Intro to Adobe Photoshop
 ::   Web Programming 101
 ::   Introduction to Microsoft DNA

Misc non-technical tutorials
 ::   Misc Technopreneurship Docs
 ::   What is a Webmaster?
 ::   What is the open source business model?
 ::   Technical writing
 ::   Small and mid-sized businesses on the Web

Offsite tutorials
 ::   ISAPI Perl Primer
 ::   Serving up web server basics
 ::   Introduction to Java (Parts 1 and 2) in Slovak

 

Introduction to Web Programming
Graphics  
  • So what do you do inside a Container? Well the most basic thing you can do is draw in it.

  • For example, you may find yourself in a situation in which you want to draw various shapes, lines, or points inside of your application. Perhaps you will want to draw three-dimensional lines that surrounding a component.

You can draw a raised 3D border by simply drawing a light line on the top and left of a component and dark lines on the right and bottom.

  • Or perhaps you will want to graph points along a curve from data you receive from outside of your application. Either way, when you need to draw within a window, the JDK provides a host of supporting classes to help you.

  • Graphics manipulation is handled by the java.awt.Graphics class which you can study using the online documentation. As you can see, there is a vast array of tools you can use for drawing.

  • So how do you draw?

  • To draw using the JDK, you first need something to draw on. Most commonly, you will draw in the visible window of a component or in a container.

  • All components and containers (since containers are actually components) in the JDK have two methods that are called by the system to paint their surface. These are the paint() and update() methods. Their signatures are provided below:

    public void paint(FxGraphics g);
    public void update(FxGraphics g);
    

  • To cause a drawing to appear in a window, you normally override either or both of the paint() and the update() methods.

The paint() method

  • When a component needs to draw itself, its paint() method is called to do the work. Whether the component draws a letter, a line, a circle, or a check box, the process is the same.

  • Since every time the component is drawn its paint() method is called, the component's paint() method can be called hundreds of times in the life of an applet. After all, there are many reasons for the component to be redrawn. The component must draw itself when it first becomes visible. The component must also use its paint() method if the user drags a window over the component to paint the area when it' is re-exposed.

  • The most simple paint() method looks like the following:

    public void paint(Graphics g)
    	{
    	}
    

  • Notice that the method takes a Graphics object as a parameter. This object represents the graphics surface that needs to be painted. We'll talk more about Graphics objects in just a bit.

  • Thus, in order to draw on a Panel, we could subclass panel and override the paint method as follows:

    import java.awt.*;
    class MyPanel extends Panel
    {
    public void paint(Graphics g)
    	{
    	g.setColor(Color.green);
    	g.fillRect(10, 10, 50, 50);
    	}
    }
    

  • If we used this new subclass of Panel instead of the default Panel for the example in Exercise Six, we would get the following interface:

    [Example]

Update

  • The second method that you need to understand which is called by a components to paint its surface is the update() method.

  • The update() method clears the surface of the component to its background color and then calls the paint() method to paint the rest of the component. This is quite convenient because you don't have to draw the whole component within a paint() method, the background is filled for you. Then, when you override paint() you only need to draw what should appear on top of the background.

  • Of course, there are times when you may want to override update(). Consider the case in which you want to draw a large, white rectangle inside a control. If you don't override update(), the control's entire background will be drawn by the update() method, and then the white rectangle will be drawn by the paint() method. A large area of one color is first drawn and then the large area of the rectangle in another color is redrawn. This could cause a user to see some slight flickering on the display, especially if the rectangle needs to be drawn a number of times in succession.

  • You can overcome this problem by overriding update(). You would override the update() method so that it calls paint(), and then have paint() first draw only the background areas that surrounding the white rectangle-- (and not the rectangle itself--) and then draw the white rectangle. This would remove flicker by eliminating the drawing of two overlapping objects of different colors.

Repainting

  • As we said previously, when a component is created and displayed, its update() and paint() methods are called to paint the component to the surface of the screen. If you hide and show the component or drag another window over the component, the system handles calling update() and paint() to repaint areas which require repainting.

  • However, there are times when you may want to force an on-screen component to repaint manually. For example, if you change certain properties on a component you may want it to repaint to reflect its new appearance. To accomplish this repaint you can call the repaint() method.

  • Here is an example:

    text.setBackground(Color.green);
    text.repaint();
    

  • Calling the repaint() method causes the whole component to repaint. You may find times when you only want a section of a given component to repaint. You can perform this by calling repaint() and giving a specific portion of the area to redraw.

  • For example, the following code repaints only a 50x50 portion of a component starting at the origin:

    comp.repaint(0, 0, 50, 50);
    

  • There are a few more things that you should know about repainting. First, when you call repaint, the paint() method on the given component does not immediately get called to paint its surface. The call to repaint() tells the system that the component needs to be repainted. The system can collect a number of repaint requests and perform them by repainting the component a single time. So, if you make 10 requests for a component to repaint, its paint() method may only be called once.

  • This does not normally cause any problems, but you may find cases where you need the system to paint a surface immediately. For example, if you had a loop in your program where you wanted a surface to paint 10 times in a loop to perform an animation, calling repaint() in the loop could cause all the paint requests to be combined into one paint operation.

  • In these cases, you may want to call the update() method directly on a component to cause it to paint immediately. You can do this by creating your own graphics object and then calling update() directly. The getGraphics() method Component allows you to create a Graphics object for the surface of a given component. For example the following code will forces an immediate repaint of a component:

    Graphics g = comp.getGraphics();
    if (g != null)
    	{
    	comp.update(g);
    	g.dispose();
    	}
    

Notice that we call the dispose() method on the graphics object after its use. As with AWT graphics objects, you should call dispose() on any graphics object you create after you have completed using it. You should not call dispose() on graphics' objects that are passed to you from the AFC, only on those you create. For example, you should not call dispose() on the graphics object passed to you in a paint() method.

The Coordinate System

  • Each component in the JDK has its own coordinate system. This means that when you add a component to your application and implement a paint() method in that component, a drawing position of 0, 0 is the upper, left- hand corner of the component, not the upper left of the screen or frame the component is contained in.

  • But the upper, left- hand corner is only half of what you need to know about the coordinate system in order to draw correctly. You also need to know the bottom, right corner of the coordinate system if you want to place lines and points correctly within your component when painting.

  • To determine the bottom, right corner of the coordinate system in the component, you can use the getSize() method to determine the width and height of the component.

  • For example, the following paint() method draws a blue rectangle in the center of the component (10 in from all sides)

    public void paint(Graphics g)
    	{
    	Dimension size = getSize();
    	g.setColor(Color.blue);
    	g.fillRect(10, 10,
                       size.width - 20,
                       size.height - 20);
    	}
    
    

Graphics by Example

  • Let's look at an example. All of the methods used here are readily accessible by referencing the online documentation.

    import java.awt.*;
    
    public class GraphicsExample extends Frame
      {
      public static void main(String[] args)
        {
        Frame f = new GraphicsExample();
        f.setTitle("Graphics Example");
        f.reshape(10,10,200,300);
        f.setBackground(Color.yellow);
        f.setForeground(Color.black);
        f.show();
        }
    
      public void paint(Graphics g)
        {
        Font f = new Font("Arial", Font.BOLD +
                                   Font.ITALIC, 10);
        Font f1 = new Font("TimesRoman", Font.BOLD, 20);
        String s = "Hello Cyberspace";
        Color purple = new Color(200,0,255);
    
        g.setFont(f);
        g.drawString("Hello Cyberspace",10, 50);
    
        g.setColor(purple);
        g.setFont(f1);
        g.drawString("Hello Cyberspace",10, 80);
    
        g.setColor(Color.blue);
        g.drawLine(20,90,40,110);
    
        g.setColor(new Color(0,0,0));
        g.drawArc(90,90,40,40,30,200);
    
        g.drawRect(10,120,20,40);
        g.drawRoundRect(50,120,20,40, 10,10);
    
        g.drawOval(100,120,30,40);
    
    
        g.setColor(Color.blue);
        g.fillRect(10,180,30,40);
        g.setColor(Color.green);
        g.fillOval(50,180,40,40);
    
        Image image =
        Toolkit.getDefaultToolkit().getImage
                         ("afraid_icon.gif");
        g.drawImage(image,110,180,this);
    
        }
      }
    
    

    [Example]

Previous Page | Next Page