当前位置: 首页 > 知识库问答 >
问题:

在重新绘制过程中调用paintComponent()时

颜乐
2023-03-14

我正在遵循我上一篇关于绘画的帖子中的建议,即Oracle Swing教程。现在我对何时以及如何调用paintComponent()方法感到困惑。

下面是课程:

public class MyPanel extends JPanel
{

private int squareX=50;
private int squareY=50;
private int squareW=50;
private int squareH=20;
public MyPanel()
{
    setBorder(BorderFactory.createLineBorder(Color.BLACK));

    addMouseListener(new MouseAdapter() { 
        public void mousePressed(MouseEvent e) {
            moveSquare(e.getX(), e.getY());
        }
    });
    addMouseMotionListener(new MouseAdapter(){
        public void mouseDragged(MouseEvent e) {
            moveSquare(e.getX(), e.getY());
        }
    });
}

private void moveSquare(int x, int y)
{
    int OFFSET = 1;
    if((squareX!=x)||(squareY!=y))
    {
        repaint(squareX, squareY, squareW+OFFSET, squareH+OFFSET);
        squareX=x;
        squareY=y;
        repaint(squareX, squareY, squareW+OFFSET, squareH+OFFSET);
    }
}

public Dimension getPreferredSize()
{
    return new Dimension(250, 200);
}

protected void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.drawString("This is my custom panel!", 10, 20);
    g.setColor(Color.RED);
    g.fillRect(squareX, squareY, squareW, squareH);
    g.setColor(Color.BLACK);
    g.drawRect(squareX, squareY, squareW, squareH);
}
}

教程说,两种重绘方法都是重绘以前的鼠标位置以及新的鼠标位置。我明白,但是paintComponent从何而来?当我们说重绘时,它被调用了吗?如果是这样,为什么不在前面的位置也画一个矩形呢?

共有1个答案

程举
2023-03-14

repaint()方法将画图请求传递给repaintManager

当在短时间内收到多个请求时,repaintManager将把这两个单独的请求合并为一个请求,以提高绘制效率。

所以如果你有这样的东西:

repaint(5, 5, 20, 20);
...
repaint( 30, 30, 20, 20);

rePaintManager最终将它们合并为(5,5,45,45)的一次重绘。这个较大的区域将包括两个单独请求的区域。

repaint()方法不进行任何绘制。repaint()方法只调用repaintManager提示组件中需要绘制的区域。

  1. 第一个repaint()建议要绘制的区域。
  2. 第二个重绘()表示要绘制的另一个区域。

rePaintManager将两个较小的区域合并为一个较大的区域。几毫秒后,它将告诉组件根据较大的区域重新绘制自己(这称为剪辑边界)。对于每次鼠标单击,PaintComponent()方法只调用一次。

super.paintComponent(g);

上面的代码只是绘制受Graphics对象的剪辑边界中指定的区域约束的组件的背景。背景颜色由setBackground(...)控制方法。

g.drawString("This is my custom panel!", 10, 20);
g.setColor(Color.RED);
g.fillRect(squareX, squareY, squareW, squareH);
g.setColor(Color.BLACK);
g.drawRect(squareX, squareY, squareW, squareH);

上面的代码将在清除的背景上绘制正方形。

将绘画代码更改为:

super.paintComponent(g);
System.out.println( g.getClipBounds() );
//repaint(squareX, squareY, squareW+OFFSET, squareH+OFFSET);
squareX=x;
squareY=y;
//repaint(squareX, squareY, squareW+OFFSET, squareH+OFFSET);
repaint();

并且您仍然会有相同的绘制结果(使用更简单的代码)。只要注意,剪辑边界现在是整个面板的大小,无论您在哪里单击。

 类似资料:
  • 我对用Java制作GUI是新手。据我所知,有一个名为Graphics的类负责在JPanel中绘制形状。当我的应用程序启动时,我调用paintComponent方法,该方法绘制我正在编程的游戏的棋盘,paintComponent方法接受图形g作为输入。然而,稍后,我想更新棋盘,那么当用户做点击之类的事情时,我如何告诉在游戏开始时绘制棋盘的同一个g绘制其他东西呢? 我相信这应该有一个很简单的答案。

  • 这里我的程序旨在创建一个GUI,允许用户通过在JPanel上单击和释放鼠标来绘制图形。其他选项包括更改颜色和是否填充形状。一旦绘制了形状,其他选项应该使用任何新的修饰符重新绘制相同的形状。例如,如果我画一个红色矩形,如果我选择蓝色,矩形应该只是改变颜色。到目前为止,我只实现了“矩形”选项。

  • 我是java图形的新手,很难掌握从一个方法(绘制组件())绘制所有图形的整个概念。我只是很好奇,看看我们是否可以在绘制组件之外绘制图形。这可能吗?是否可以在main方法中写一行,如:fillRect(100,100, 500,400);并让它绘制一个矩形?如果可能,是否根据Java常规? 基本上,我想问的是,你是否可以在paintComponent类之外绘制图形,这是常规的吗。

  • 我试图绘制一个矩形,它的位置每秒钟更新一次,因为我有一个类,它扩展了JPanel,在它里面我重写了油漆(或油漆组件)function_我已经尝试了这两个_但显然这个函数只被调用一次,正如下面的代码所示,当我试图用reaint函数在无限循环中调用它时,它没有被调用,我能做什么? 上面的代码是图形部分,下面是主函数,它位于另一个类中: 在上面的代码中,食物。加法器是矩形位置更新的地方,我已经检查过了,

  • 我被一些奇怪的东西卡住了。我有一个带有JScrollPane的JFrame,其中包含一个比实际屏幕大得多的jPanel。我用圆柱画正方形,我希望这些正方形越过JPanel的右边框。(以便在向右滚动时显示它们。)但是使用paintComponents方法绘制的方块只是在JScrollPane的可见视口处停止。 下面是JFrame内部的JScrollPane的代码: public void initC