关注JPanel的功能:paintcomponent() [英] Concerns about the function of JPanel: paintcomponent()

查看:154
本文介绍了关注JPanel的功能:paintcomponent()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好我是java编程的新手,我需要有人向我解释这些代码行:

hello I'm new in java programming, and i need someone explaining me these lines of code:

 public class drawpanel extends JPanel
 {
     public void paintComponent(Graphics g)
     { 
         super.paintComponent(g);
         ...
     }
 }

我不明白line public void paintComponent(Graphics g):如果在JPanel中预定义了,为什么我必须声明那个函数?

I dont understand the line public void paintComponent(Graphics g): why do i have to declare that function like that if it's predefined in JPanel?

此行 super.paintComponent(g):我根本不明白。谢谢你的帮助。

And this line super.paintComponent(g): I dont understand it at all. Thank you for your help.

推荐答案

基本结构:



extends 关键字表示 DrawPanel 继承自 JPanel 。换句话说, DrawPanel 是一个 JPanel 。因此,它可以覆盖其方法(未标记 final 的方法)。您可能希望这样做有几个原因。例如,您可能希望获得对面板的 Graphics 类的访问权限,您可以使用该类在面板上绘制圆圈,或条形图或文本字符串。

The Basic Structure:

The extends keyword means that DrawPanel inherits from JPanel. In other words, DrawPanel "is a" JPanel. As such, it can override its methods (the ones that aren't marked final). You might want to do that for several reasons. For example, you might want to gain access to the panel's Graphics class, which you could use to draw a circle on the panel, or a bar graph, or a string of text.

如果你没有覆盖任何方法,那么当你扩展 JPanel 时你会得到这样的结果:

If you don't override any methods, then when you extend JPanel you get something like this:

public class DrawPanel extends JPanel {
    //TODO not much
}

然而,这不是很有用......除非你不喜欢名字 JPanel 并且想要调用它 AwesomePanel 而不是(注意:不要那样做)。如果这就是你所拥有的,那么你最好只创建一个实例 JPanel ,如下所示: JPanel drawPanel = new JPanel();

However, that's not very useful ...unless you just don't like the name JPanel and want to call it AwesomePanel instead (note: don't do that). If that's all you have, you're better off just creating an instance of JPanel, like this: JPanel drawPanel = new JPanel();

扩展 JPanel 的目的是覆盖 paintComponent 方法。在覆盖 paintComponent 之前, JPanel 是不可见的(注意:不可见是使其成为有用容器的原因按钮和其他组件)。你是对的, paintComponent 方法是预先定义的(如果你想知道的话,在 JComponent 类中),但是所有该方法的作用是使空 JPanel 。如果你想在面板上绘制一些东西,那么你需要覆盖它,如下所示:

The purpose of extending a JPanel is to override the paintComponent method. The JPanel is invisible until you override paintComponent (note: being invisible is what makes it a useful container for buttons and other components). You are right that the paintComponent method is pre-defined (in the JComponent class if you were wondering), but all that method does is make an empty JPanel. If you want to draw something on the panel, then you need to override it, like this:

public class DrawPanel extends JPanel {
    @Override public void paintComponent(Graphics g) { // <-- HERE!
        //TODO draw stuff
    }
}

注意: @Override 部分并不是绝对必要的,但最好包含它,因为它减少了运行时错误的数量并提高了代码的可读性

您现在可以访问图形对象 g 用于面板。 Graphics 是一个帮助类,允许您在面板上绘制内容,如下所示:

You now have access to the Graphics object g for the panel. Graphics is a helper class that allows you to draw things on the panel, like this:

public class DrawPanel extends JPanel {
    @Override public void paintComponent(Graphics g) {
        g.drawOval(50, 50, 50, 50); // <-- draws an oval on the panel
    }
}






super.paintComponent:



有用的比喻(我刚刚编写): JPanel 是画布, 图形 对象是你的画笔,并且 super.paintComponent(g) 是你的橡皮擦。 (另外, JFrame 是你的画架。)


super.paintComponent:

helpful metaphor (that I just made up): The JPanel is the canvas, the Graphics object is your paintbrush, and super.paintComponent(g) is your eraser. (Also, JFrame is your easel.)

所以 super.paintComponent(g) JPanel paintComponent 方法$ c>( JComponent 类)删除当前在面板上绘制的内容。 这对动画很有用。

So super.paintComponent(g) invokes the paintComponent method from the superclass of JPanel (the JComponent class) to erase whatever is currently drawn on the panel. This is useful for animation.

例如,考虑在面板上绘制模拟时钟。你需要每秒刷新一次,所以每秒你必须擦除前一个时钟并重新绘制时钟,调整秒针。如果在重新绘制时钟之前没有调用 super.paintComponent(g),它将继续在旧时钟之上绘制新时钟,并在60秒内绘制你的时钟。 ll只是一个充满圆圈,或多或少。

For example, consider drawing an analog clock on the panel. You need to refresh it every second, so each second you have to erase the previous clock and redraw the clock, adjusting the second hand. If you don't invoke super.paintComponent(g) before redrawing the clock, it will just keep drawing new clocks on top of the old clocks and in 60 seconds what you'll have is just a filled in circle, more or less.

还有一件事需要记住:始终在<$ c $中首先调用 super.paintComponent(g) c> paintComponent 方法,如下所示:

Only one more thing to remember: always call super.paintComponent(g) first in the paintComponent method, like this:

public class DrawPanel extends JPanel {
    public void paintComponent(Graphics g) {
        super.paintComponent(g); // <-- HERE!
        g.drawOval(50, 50, 50, 50);
    }
}

就是这样。请随时与我联系。

That's it. Feel free to contact me.

I创建了一个简单的示例,它使用这些概念在面板上显示一串文本(放在框架内)。在IDE中保存为 TestPanel.java

I created a simple example that uses these concepts to display a string of text on a panel (which is placed inside a frame). Save in your IDE as TestPanel.java.

import java.awt.*;
import java.util.*;
import javax.swing.*;

/**
 * A frame containing a panel that is sometimes red and sometimes 
 * blue. Also, it displays the word to go with it. 
 * 
 * Inspired by www.sometimesredsometimesblue.com.
 *
 */
public class TestPanel extends JPanel {

    private Random random = new Random();
    private boolean isRed;
    private String s = "";

    public TestPanel() {
        //randomly determine whether the background should be red
        isRed = random.nextBoolean();

        //set the background to blue
        setBackground(Color.BLUE);
        s = "BLUE";

        //if 'isRed' is true, set the background to red
        if (isRed) {
            setBackground(Color.RED);
            s = "RED";
        }
    }

    @Override 
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        //write either "RED" or "BLUE" using graphics
        g.setColor(Color.WHITE);
        g.setFont(new Font("serif", Font.BOLD, 60));
        g.drawString(s, getWidth() / 2 - g.getFontMetrics().stringWidth(s) / 2,
                getHeight() / 2 + g.getFontMetrics().getHeight() / 2);
    }

    //main method: create an instance of TestPanel and output it on a JFrame
    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setSize(500, 500);
        f.setTitle("Sometimes Red, Sometimes Blue");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setContentPane(new TestPanel());
        f.setVisible(true);
    }
}

这篇关于关注JPanel的功能:paintcomponent()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆