杰瑞科技汇

getgraphics java

Of course! The phrase getGraphics() in Java refers to a method used to obtain a Graphics object, which is the fundamental drawing object in the Abstract Window Toolkit (AWT). This Graphics object acts as your "paintbrush" for drawing shapes, text, and images onto a component like a window or a panel.

getgraphics java-图1
(图片来源网络,侵删)

Let's break it down in detail.

What is the Graphics Object?

Think of a Graphics object as a drawing context. It encapsulates all the information needed to draw on a specific component, such as:

  • The component itself (the canvas you're drawing on).
  • The current color (setColor()).
  • The current font (setFont()).
  • The clipping region (the area that is allowed to be drawn on).

You don't create Graphics objects directly with new Graphics(). Instead, you get one from a component that is already visible on the screen.

The getGraphics() Method

The getGraphics() method is a method of the java.awt.Component class. Since almost all AWT and Swing components (like JFrame, JPanel, Button, etc.) inherit from Component, they all have this method.

getgraphics java-图2
(图片来源网络,侵删)

Syntax:

public Graphics getGraphics()

What it returns:

  • A Graphics object that you can use to draw on the component.
  • null if the component is not yet displayable (e.g., it hasn't been added to a visible JFrame yet).

The "Old Way" vs. The "Modern Way"

This is the most important concept to understand about getGraphics().

The Old Way (Direct Drawing)

In the early days of AWT, you would sometimes call getGraphics() directly in your constructor or in an event handler to draw something immediately.

getgraphics java-图3
(图片来源网络,侵删)

Example of the Old Way (Problematic):

import javax.swing.*;
import java.awt.*;
public class OldWayDrawing extends JFrame {
    public OldWayDrawing() {
        setTitle("Old Way Example");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // This is generally NOT a good idea!
        Graphics g = this.getGraphics(); // Get the graphics context of the JFrame
        if (g != null) {
            g.setColor(Color.BLUE);
            g.drawString("Hello, World!", 50, 50);
        }
    }
    public static void main(String[] args) {
        new OldWayDrawing().setVisible(true);
    }
}

Why is this bad?

  • Flickering: The drawing happens once. If the window is resized, minimized, or another window moves over it, the operating system will erase the content and your drawing will disappear. You would have to redraw it every time this happens.
  • Not Persistent: The drawing is not tied to the component's natural lifecycle. It's a one-shot command.

The Modern Way (Overriding paintComponent)

The correct, modern approach is to let the Swing/AWT framework handle the drawing for you. You do this by creating a custom component (usually a JPanel) and overriding its paintComponent(Graphics g) method.

The framework automatically calls paintComponent whenever it needs to redraw the component (e.g., on startup, after being resized, after being uncovered by another window).

The Golden Rule of Painting:

Always call the super.paintComponent(g) method as the first line of your overridden paintComponent method. This ensures that the component is properly cleared and painted by the underlying Swing/AWT system.

Example of the Modern Way (Correct):

import javax.swing.*;
import java.awt.*;
// 1. Create a custom JPanel and override paintComponent
class DrawingPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics g) {
        // 2. Call the parent's paintComponent method first!
        super.paintComponent(g);
        // 3. Now, use the 'g' object (which is provided by the system) to draw
        g.setColor(Color.BLUE);
        g.drawString("Hello, Modern World!", 50, 50);
        g.setColor(Color.RED);
        g.fillRect(100, 80, 80, 60); // Draw a filled rectangle
    }
}
public class ModernWayDrawing extends JFrame {
    public ModernWayDrawing() {
        setTitle("Modern Way Example");
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 4. Add our custom drawing panel to the frame
        this.add(new DrawingPanel());
    }
    public static void main(String[] args) {
        // Use SwingUtilities.invokeLater for thread safety
        SwingUtilities.invokeLater(() -> {
            new ModernWayDrawing().setVisible(true);
        });
    }
}

When is getGraphics() Useful?

While you shouldn't use it for persistent painting, getGraphics() has some valid use cases:

  1. Offscreen Buffering (Double Buffering): This is the most common use case. To prevent flickering, you can draw everything to an offscreen Image first, and then use getGraphics() on that image. Once the offscreen image is complete, you draw it to the screen in a single, fast operation.

    // Conceptual example of double buffering
    Image offscreenImage = createImage(getWidth(), getHeight());
    Graphics offscreenGraphics = offscreenImage.getGraphics(); // <-- USEFUL!
    // Draw everything to the offscreenGraphics...
    offscreenGraphics.setColor(...);
    offscreenGraphics.fillRect(...);
    // Then, in paintComponent, just draw the image
    g.drawImage(offscreenImage, 0, 0, this);
  2. Printing: When printing from a Java application, you get a Graphics object from the PrinterJob and use it to draw on a virtual "printable page." The concept is similar to offscreen drawing.

  3. Capturing a Component's Appearance: You can get the Graphics object of a component to render its current state into an Image file.

Summary Table

Feature getGraphics() (Direct) Overriding paintComponent() (Modern)
Purpose To manually grab a drawing context. To define what a component should look like.
When to Use Offscreen buffering, printing, capturing. For almost all standard UI drawing (shapes, text, images).
Persistence No. Drawing is temporary and lost on repaint. Yes. The framework calls it whenever a redraw is needed.
Flickering High risk of flickering. No flickering (when used correctly).
Code Example Graphics g = myPanel.getGraphics(); g.drawString(...); @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawString(...); }

Conclusion

For everyday Swing and AWT development, you should almost always override the paintComponent() method instead of calling getGraphics() directly. The framework-managed painting approach is more robust, persistent, and avoids common problems like flickering.

Reserve getGraphics() for specific, advanced tasks like offscreen rendering for double buffering or when working with printing APIs.

分享:
扫描分享到社交APP
上一篇
下一篇