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

在JPanel中使用repaint()方法而不擦除已绘制的内容

濮阳耀
2023-03-14

我最初是这样制作程序的。我使用extends Canvas和update方法来不断地绘制更多的点。我的理解是,每次调用repaint()时,新的点都会通过使用update()方法添加到现有的画布上。如果方法是paint()而不是update(),那么每次调用repaint()时,它将绘制一个只有50个点的新画布。这是我的扩展画布的BarnsleyFern类。

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Canvas;
import java.lang.Math;
import java.awt.event.*;
import javax.swing.*;
public class BarnsleyFern extends Canvas
{
   private double newX,x=0;
   private double newY,y=0;
   public BarnsleyFern(int width, int height)
   {
      setBackground(Color.BLACK);
      setSize(width,height);
      setVisible(true);
      ActionListener action = new ActionListener()
      {
         public void actionPerformed(ActionEvent event)
         {  
            repaint();
         }
      };
      Timer timer = new Timer(100,action);
      timer.start();
   }
   public void update(Graphics window)
   {
      Graphics2D g2d = (Graphics2D)window;
      window.translate(360,800);
      //g2d.rotate(Math.toRadians(180));
      fern(window);
   }
   public void fern(Graphics window)
   {
      Color newColor = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
      for(int i=0;i<50;i++)
      {
         window.setColor(Color.BLUE);
         int rand = (int)(Math.random()*100);
         if(rand<1)
         {
            newX=0;
            newY=0.16*y;
         }
         else if(rand<86)
         {
            newX=0.85*x + 0.04*y;
            newY=0.85*y - 0.04*x + 1.6;
         }  
         else if(rand<93)
         {
            newX=0.20*x - 0.26*y;
            newY=0.23*x + 0.22*y + 1.6;
         }
         else
         {
            newX=0.28*y - 0.15*x;
            newY=0.26*x + 0.24*y + 0.44;
         }
         window.fillOval((int)(newX*165.364),-(int)(newY*80.014),2,2);   
         x=newX;
         y=newY;
      }
   }
}

下面的代码是扩展JFrame的BarnsleyFernRunner类。这将设置JFrame,并包含main方法。

import javax.swing.JFrame;
public class BarnsleyFernRunner extends JFrame
{
   public BarnsleyFernRunner()
   {
      setTitle("Barnsley Fern");
      setSize(800,800);
      add(new BarnsleyFern(800,800));
      setVisible(true);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }
   public static void main(String[] args)
   {  
      BarnsleyFernRunner runner = new BarnsleyFernRunner();
   }
}

然后,我决定通过扩展JPanel而不是扩展Canvas来稍微更改代码。我选择这样做是因为JPanel和JFrame都来自javax.swing包。新的BarnsleyFern类使用上面的BarsnleyFernRunner类。这个类的工作方式与以前不同。每次调用repaint()时,将绘制50个新点,旧点将消失。我的理解是,情况就是这样,因为每次调用repaint()时都会生成一个新的JPanel。我的问题是如何在JPanel中调用repaint()方法而不创建一个全新的JPanel。是否有一种方法可以调用repaint()而不“擦除”我已经绘制的内容。有没有一种方法可以用update()方法复制我在第一个类中所做的事情。这是我的BarnsleyFern类,它扩展了JPanel

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Color;
import java.awt.Canvas;
import java.lang.Math;
import java.awt.event.*;
import javax.swing.*;
public class BarnsleyFern extends JPanel
{
   private double newX,x=0;
   private double newY,y=0;
   public BarnsleyFern(int width, int height)
   {
      setBackground(Color.BLACK);
      setSize(width,height);
      setVisible(true);
      ActionListener action = new ActionListener()
      {
         public void actionPerformed(ActionEvent event)
         {  
            repaint();
         }
      };
      Timer timer = new Timer(100,action);
      timer.start();
   }
   public void paintComponent(Graphics window)
   {
      super.paintComponent(window);
      Graphics2D g2d = (Graphics2D)window;
      window.translate(360,800);
      //g2d.rotate(Math.toRadians(180));
      fern(window);
   }
   public void fern(Graphics window)
   {
      Color newColor = new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
      for(int i=0;i<50;i++)
      {
         window.setColor(Color.BLUE);
         int rand = (int)(Math.random()*100);
         if(rand<1)
         {
            newX=0;
            newY=0.16*y;
         }
         else if(rand<86)
         {
            newX=0.85*x + 0.04*y;
            newY=0.85*y - 0.04*x + 1.6;
         }  
         else if(rand<93)
         {
            newX=0.20*x - 0.26*y;
            newY=0.23*x + 0.22*y + 1.6;
         }
         else
         {
            newX=0.28*y - 0.15*x;
            newY=0.26*x + 0.24*y + 0.44;
         }
         window.fillOval((int)(newX*165.364),-(int)(newY*80.014),2,2);   
         x=newX;
         y=newY;
      }
   }
}

共有1个答案

越信鸥
2023-03-14

paintcomponent()方法中调用super.paintcomponent(window);时,要求JPanel绘制边框和背景。画一个背景意味着摧毁以前的任何东西。

处理此问题的最简单方法是简单地省略对super.paintcomponent(window);的调用。另一种方法是调用setopaque(false);。这告诉面板你自己负责绘制背景。

 类似资料:
  • 我是新来的Java,刚刚开始学习图形用户界面组件。所以,我正在阅读HeadfirstJava,有一个代码解释了的方法。只要用户点击“改变颜色”按钮,它就可以改变椭圆形的颜色。- MyDrawPanel类- 我从这个例子中得到了所有的东西,除了我们调用方法的部分。 书中提到,只需覆盖的方法,当您调用时,它将调用来呈现内容(因为我们不直接调用)。 现在,我通过扩展创建了类,并覆盖了它的方法。现在,当我

  • 将显示JFrame和JPanel,但paintComponent方法不在JPanel上绘制。我只看到我添加的JLabel、JTextField和JButton,而没有看到应该在JPanel上绘制的内容。

  • 问题内容: 我尝试了一些用Java绘图的源代码,它们工作正常,但是当我尝试制作自己的源代码时,我无法使用该方法!我再次查看了自己拥有的代码,并查看了Oracle页面中的一些教程,但是我似乎无法得知为什么它不起作用。有人可以检查一下,告诉我这里有什么问题吗? 主要方法:公共类主要 板: car.java: 没有错误,它向我显示了正确的图像宽度,计时器也触发,也可以正常工作,但是图像无法绘制!该方法只

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

  • 我有一个扩展JPanel的类“GUI”。我有另一个扩展JFrame的类“Buttons”。我试图让JFrame类调用JPanel类中的方法“clearscreen()”,当在JFrame上按下JButton“clearb”时。实现这一工作的唯一方法是在JButton的actionlistener中为JPanel类“GUI”构建对象: 但是当我调用方法clearScreen()时,它看起来如下所示:

  • 我有一个小计算器,我正在添加到我的HTML。它有几个下拉选择的东西,当一个人点击提交按钮,我想显示一张图片在计算器下面我的HTML。我尝试使用javascript函数:document.write(),但这会清除整个页面。有没有一种方法,我可以得到一个javascript函数运行,它只添加图片到我的页面时,提交按钮被单击? 下面是我的代码的基本大纲,其中有我遇到的问题: 是否可以使用某种内部HTM