Displaying Information in a Panel

   


In this section, we show you how to display information inside a frame. For example, rather than displaying "Not a Hello, World program" in text mode in a console window as we did in Chapter 3, we display the message in a frame, as shown in Figure 7-6.

Figure 7-6. A simple graphical program


You could draw the message string directly onto a frame, but that is not considered good programming practice. In Java, frames are really designed to be containers for components such as a menu bar and other user interface elements. You normally draw on another component, called a panel, which you add to the frame.

The structure of a JFrame is surprisingly complex. Look at Figure 7-7, which shows the makeup of a JFrame. As you can see, four panes are layered in a JFrame. The root pane, layered pane, and glass pane are of no interest to us; they are required to organize the menu bar and content pane and to implement the look and feel. The part that most concerns Swing programmers is the content pane. When designing a frame, you add components into the content pane, using code such as the following:

 Container contentPane = frame.getContentPane(); Component c = . . .; contentPane.add(c); 

Figure 7-7. Internal structure of a JFrame


Up to JDK 1.4, the add method of the JFrame class was defined to throw an exception with the message "Do not use JFrame.add(). Use JFrame.getContentPane().add() instead". As of JDK 5.0, the JFrame.add method has given up trying to reeducate programmers, and it simply calls add on the content pane.

Thus, as of JDK 5.0, you can simply use the call

 frame.add(c); 

In our case, we want to add a single panel to the frame onto which we will draw our message. Panels are implemented by the JPanel class. They are user interface elements with two useful properties:

  • They have a surface onto which you can draw.

  • They themselves are containers.

Thus, they can hold other user interface components such as buttons, sliders, and so on.

To make a panel more interesting, you use inheritance to create a new class, and then override or add methods to get the extra functionality you want.

In particular, to draw on a panel, you

  • Define a class that extends JPanel; and

  • Override the paintComponent method in that class.

The paintComponent method is actually in JComponent the superclass for all nonwindow Swing components. It takes one parameter of type Graphics. A Graphics object remembers a collection of settings for drawing images and text, such as the font you set or the current color. All drawing in Java must go through a Graphics object. It has methods that draw patterns, images, and text.

NOTE

The Graphics parameter is similar to a device context in Windows or a graphics context in X11 programming.


Here's how to make a panel onto which you can draw:

 class MyPanel extends JPanel {    public void paintComponent(Graphics g)    {       . . . // code for drawing will go here    } } 

Each time a window needs to be redrawn, no matter what the reason, the event handler notifies the component. This causes the paintComponent methods of all components to be executed.

Never call the paintComponent method yourself. It is called automatically whenever a part of your application needs to be redrawn, and you should not interfere with this automatic process.

What sorts of actions trigger this automatic response? For example, painting occurs because the user increased the size of the window or minimized and then restored the window. If the user popped up another window and it covered an existing window and then made the overlaid window disappear, the application window that was covered is now corrupted and will need to be repainted. (The graphics system does not save the pixels underneath.) And, of course, when the window is displayed for the first time, it needs to process the code that specifies how and where it should draw the initial elements.

TIP

If you need to force repainting of the screen, call the repaint method instead of paintComponent. The repaint method will cause paintComponent to be called for all components, with a properly configured Graphics object.


As you saw in the code fragment above, the paintComponent method takes a single parameter of type Graphics. Measurement on a Graphics object for screen display is done in pixels. The (0, 0) coordinate denotes the top-left corner of the component on whose surface you are drawing.

Displaying text is considered a special kind of drawing. The Graphics class has a drawString method that has the following syntax:

 g.drawString(text, x, y) 

In our case, we want to draw the string "Not a Hello, World Program" in our original window, roughly one-quarter of the way across and halfway down. Although we don't yet know how to measure the size of the string, we'll start the string at coordinates (75, 100). This means the first character in the string will start at a position 75 pixels to the right and 100 pixels down. (Actually, it is the baseline for the text that is 100 pixels down see below for more on how text is measured.) Thus, our paintComponent method looks like this:

 class NotHelloWorldPanel extends JPanel {    public void paintComponent(Graphics g)    {       . . . // see below       g.drawString("Not a Hello, World program", MESSAGE_X, MESSAGE_Y);    }    public static final int MESSAGE_X = 75;    public static final int MESSAGE_Y = 100; } 

However, this paintComponent method is not complete. The NotHelloWorldPanel class extends the JPanel class, which has its own idea of how to paint the panel, namely, to fill it with the background color. To make sure that the superclass does its part of the job, we must call super.paintComponent before doing any painting on our own.

 class NotHelloWorldPanel extends JPanel {    public void paintComponent(Graphics g)    {       super.paintComponent(g);       . . . // code for drawing will go here    } } 

Example 7-3 shows the complete code. If you use JDK 1.4 or below, remember to change the call add(panel) to getContentPane().add(panel).

Example 7-3. NotHelloWorld.java
  1. import javax.swing.*;  2. import java.awt.*;  3.  4. public class NotHelloWorld  5. {  6.    public static void main(String[] args)  7.    {  8.       NotHelloWorldFrame frame = new NotHelloWorldFrame();  9.       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 10.       frame.setVisible(true); 11.   } 12.} 13. 14. /** 15.   A frame that contains a message panel 16. */ 17. class NotHelloWorldFrame extends JFrame 18. { 19.   public NotHelloWorldFrame() 20.   { 21.      setTitle("NotHelloWorld"); 22.      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 23. 24.      // add panel to frame 25. 26.      NotHelloWorldPanel panel = new NotHelloWorldPanel(); 27.      add(panel); 28.   } 29. 30.   public static final int DEFAULT_WIDTH = 300; 31.   public static final int DEFAULT_HEIGHT = 200; 32. } 33. 34. /** 35.    A panel that displays a message. 36. */ 37. class NotHelloWorldPanel extends JPanel 38. { 39.    public void paintComponent(Graphics g) 40.    { 41.       super.paintComponent(g); 42. 43.       g.drawString("Not a Hello, World program", MESSAGE_X, MESSAGE_Y); 44.    } 45. 46.    public static final int MESSAGE_X = 75; 47.    public static final int MESSAGE_Y = 100; 48. } 


 javax.swing.JFrame 1.2 

  • Container getContentPane()

    returns the content pane object for this JFrame.

  • void add(Component c)

    adds the given component to the content pane of this frame. (Before JDK 5.0, this method threw an exception.)


 java.awt.Component 1.0 

  • void repaint()

    causes a repaint of the component "as soon as possible."

  • public void repaint(int x, int y, int width, int height)

    causes a repaint of a part of the component "as soon as possible."


 javax.swing.JComponent 1.2 

  • void paintComponent(Graphics g)

    override this method to describe how your component needs to be painted.


       
    top



    Core Java 2 Volume I - Fundamentals
    Core Java(TM) 2, Volume I--Fundamentals (7th Edition) (Core Series) (Core Series)
    ISBN: 0131482025
    EAN: 2147483647
    Year: 2003
    Pages: 132

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net