【问题标题】:add multiple shapes to jpanel with delay延迟向jpanel添加多个形状
【发布时间】:2012-07-15 05:10:47
【问题描述】:

我想在延迟后一次将正方形添加到 jpanel 上。在我尝试使用 setBackgound() 更改背景颜色之前,我的程序运行良好。它没有改变。我发现我必须在我的 paintComponent 方法中调用 super.paintComponent(gr)。但是当我这样做并调用 repaint() 时,只显示当前方块。以前的方块消失了。我知道这是因为 repaint 每次都显示一个全新的面板但是为什么当我不调用 super.paintComponent() 时它会起作用。这是代码的简化版本:

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

public class Squares extends JFrame{
    aPanel ap = new aPanel();   
    SlowDown sd = new SlowDown(); //slows down program by given number of milliseconds 

    public Squares(){
        super("COLOURED SQUARES");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        add(ap);
        ap.setPreferredSize(new Dimension(300, 300));
        pack();
        setVisible(true);
        addSquares();
   }

    private void addSquares(){
        sd.slowDown(500);
        ap.changeSquare( 100 , 100 , 255 , 0 , 0);
        ap.repaint();

        sd.slowDown(500);
        ap.changeSquare( 200 , 200 , 0 , 0 , 255);
        ap.repaint();     
   }



    public static void main(String[] arguments) {
        Squares sq  = new Squares();
    }


class aPanel extends JPanel{

    private int x = 0;
    private int y = 0;
    private int r = 0;
    private int g = 0;
    private int b = 0;  

    public void paintComponent(Graphics gr) {
        //super.paintComponent(gr);
        Color theColor = new Color (r, g, b);
        gr.setColor(theColor);
        gr.fillRect(x,y,30,30); 
    }
    void changeSquare(int i , int j, int rd , int gr , int bl){
        x = i;
        y = j;
        r = rd;
        g = gr;
        b = bl;
    }
}

class SlowDown{
    void slowDown(long delay){
         long t = System.currentTimeMillis();
         long startTime = t;
         while(t < startTime + delay){
             t = System.currentTimeMillis();            
         }
  }
}
}

【问题讨论】:

    标签: jpanel delay shapes


    【解决方案1】:

    因此,您可以做很多事情来改进代码。首先,如果您想绘制多个矩形并“记住”这些矩形,那么您需要存储过去绘制的矩形。否则会发生什么,您基本上每次都在先前绘制的矩形上进行绘制。所以我建议将每个矩形存储在某种列表中。然后在绘制时,您可以遍历列表并绘制每个矩形。

    其次,延迟可以通过 Thread.sleep() 调用来完成。也许这将是一个例子:

    class APanel extends JPanel{
    
      List<Shape> rects;  
      private int r = 0;
      private int g = 0;
      private int b = 0; 
    
      public APanel(){
             rects = new ArrayList<Shape>();
      }
    
    public void paintComponent(Graphics gr) {
        super.paintComponent(gr);
        Color theColor = new Color (r, g, b);
        gr.setColor(theColor);
        for(Shape s: rects){
           ((Graphics2D)gr).fill(s);
        }        
    }
    
    void changeSquare(int i , int j, int rd , int gr , int bl){
        rects.add(new Rectangle2D.Double(i, j, 30, 30));        
        //we have to deal with colors
    }
    }
    

    现在,上面的示例将允许您不断地将新矩形添加到列表中,并且每次都绘制所有矩形。如果您需要用不同的颜色绘制每个矩形,那么您可能必须创建自己的矩形类来存储在列表中。至于延迟你可以这样做:

     class SlowDown{
        void slowDown(long delay){          
           Thread.sleep(delay);
      }
     }
    

    这应该会暂停延迟毫秒。

    【讨论】:

    • 我很好奇如果我不使用 super.paintComponent(gr),为什么原始代码可以工作。除了无法更改背景颜色之外,它可以在不设置 ArrayList 的情况下完成我想要的
    • 不是原来的代码错了。但这是解决问题的有限方法。尤其是您需要更改背景并将方块留在屏幕上。这就是为什么我建议使用 ArrayList of Rectangle Shapes。
    • 好的,但它没有回答我的问题,即如果我不调用 super.paintComponent(gr),它为什么会起作用。谢谢
    • 当您调用 super.paintComponent 时,您基本上是以背景颜色绘制整个组件,而不是绘制之前绘制的任何内容,包括所有过去的正方形。当你不打电话时,你在过去画的东西仍然存在。
    猜你喜欢
    • 2015-09-07
    • 1970-01-01
    • 2017-04-01
    • 2015-03-02
    • 2017-10-29
    • 2019-12-15
    • 2011-09-20
    • 2023-04-05
    • 1970-01-01
    相关资源
    最近更新 更多