基本结构:
extends关键字意味着DrawPanel继承自JPanel。换句话说,DrawPanel是“JPanel”。因此,它可以覆盖其方法(未标记为final的方法)。您可能希望这样做有几个原因。例如,您可能希望访问面板的Graphics类,您可以使用该类来绘制面板上的圆形,或条形图或文本字符串。
如果你不覆盖任何方法,那么当你扩展JPanel你会得到这样的东西:
public class DrawPanel extends JPanel {
//TODO not much
}
但是,这不是非常有用的…除非你不喜欢名称JPanel并且想要称为AwesomePanel(注意:不要这样做)。如果这是所有的,你最好只是创建一个JPanel的例子,像这样:JPanel drawPanel = new JPanel();
的paintComponent:
扩展JPanel的目的是覆盖paintComponent方法。在你重写paintComponent之前,JPanel是不可见的(注意:不可见是什么使它成为按钮和其他组件的有用容器)。你是对的,paintComponent方法是预定义的(如果你想知道在JComponent类中),但是所有的方法都是一个空的JPanel。如果你想在面板上画一些东西,那么你需要重写它,就像这样:
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) { //
//TODO draw stuff
}
}
注意:@Override部分不是严格必要的,但是包含它的好习惯是因为它减少了运行时错误的数量并提高了代码的可读性
您现在可以访问面板的Graphics对象g。 Graphics是一个帮助类,可以让您在面板上绘制东西,如下所示:
public class DrawPanel extends JPanel {
@Override public void paintComponent(Graphics g) {
g.drawOval(50, 50, 50, 50); //
}
}
super.paintComponent方法:
有用的比喻(我刚刚组成):JPanel是画布,Graphics对象是您的画笔,super.paintComponent(g)是您的橡皮擦。 (另外,JFrame是你的画架。)
所以super.paintComponent(g)从JPanel(JComponent类)的超类调用paintComponent方法来擦除面板上当前绘制的任何内容。这对于动画很有用。
例如,考虑在面板上绘制模拟时钟。你需要每秒刷新一次,所以每秒钟你必须擦除以前的时钟并重绘时钟,调整秒针。如果在重新绘制时钟之前没有调用super.paintComponent(g),它将只会在旧时钟之上继续绘制新的时钟,而在60秒内,您将拥有的只是一个圆圈,或多或少。
还有一件事要记住:总是在paintComponent方法中首先调用super.paintComponent(g),如下所示:
public class DrawPanel extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g); //
g.drawOval(50, 50, 50, 50);
}
}
而已。随时联系我。
例:
我创建了一个简单的例子,使用这些概念在面板上显示一个文本字符串(放置在一个框架内)。将您的IDE保存为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);
}
}