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

查看:34
本文介绍了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);
         ...
     }
 }

我不明白public voidpaintComponent(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 方法.JPanel 在您覆盖 paintComponent 之前是不可见的(注意:不可见使其成为按钮和其他组件的有用容器).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 部分不是绝对必要的,但包含它是一种很好的做法,因为它减少了运行时错误的数量并提高了代码可读性

您现在可以访问面板的 Graphics 对象 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 是画布, Graphics object 是你的画笔, super.paintComponent(g) 是你的橡皮擦.(另外, JFrame 是你的画架.)

所以 super.paintComponent(g)JPanel 的超类(JComponentclass) 擦除当前在面板上绘制的任何内容.这对动画很有用.

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 秒内您将拥有的只是一个填充在圈子里,或多或少.

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.

还有一点要记住:总是在 paintComponent 方法中首先调用 super.paintComponent(g),像这样:

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.

我创建了一个简单的示例,该示例使用这些概念在面板(位于框架内)上显示文本字符串.在您的 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天全站免登陆