Java 绘画方法中 while 循环后绘图擦除

Drawing erases after while loop in Java paint method

我正在开发一个小程序,使用由嵌套循环控制的绘制方法来绘制堆叠的杯子。我的一切正常,除了当外部 While 循环结束时,绘图被擦除。

该程序由两个 While 循环组成。第一个用于增加绘图的行,第二个用于绘制行中的杯子。

在Debug模式下看程序,最后执行完外层While循环后,外层While语句被求值(while (baseLength > 0))为false,然后程序上行到int counter2 = 0 ,绘图消失,程序退出。

我也尝试用 For 循环而不是 While 来构建它,我得到了同样的效果。一旦外部循环被评估为 false,绘图就会消失。

似乎 paint(g) 方法做了一些我不太明白的事情,导致绘图被擦除。有什么想法吗?

import javax.swing.JFrame;
import java.awt.Graphics;
import java.awt.Color;

public class Cups1 extends JFrame {

    /*
     * Declaring instance variables. startX and startY represent the top left coordinates
     * of the first cup block in the bottom row. cupWidth and cupHeight represent the width
     * and height of each row.
     */
    int startX, startY, cupWidth, cupHeight;
    int baseLength; //number of cups in bottom row
    int cupSpacing; //spacing between adjacent cups

        //Constructor calls constructor from JFrame class, argument is window title
        public Cups1()
        {
        super("Example");
        startX = 100;
        startY = 300;
        cupWidth = 25;
        cupHeight = 40;
        baseLength = 7;
        cupSpacing = 6;
        }

        //Paint method fills pattern from bottom to top
        public void paint(Graphics g)
        {
            //Call paint method of JFrame
            super.paint(g);
            //startX and startY are variables to set original point of reference
            //drawX and drawY are local variables for each cup instance
            int drawY = startY, drawX = startX;
            int counter1 = 0;
            while (baseLength > 0)
            {
                int counter2 = 0;
                //Control number of cups in level 
                while (baseLength > counter2) 
                {

                    //Make odd levels red and even levels blue to alternate colors
                    if (baseLength % 2 == 0)
                    {
                        g.setColor(Color.blue);
                    } else {
                        g.setColor(Color.red);
                    }

                    //Draw cup shapes   
                g.fillRect(drawX, drawY, cupWidth, cupHeight);
                drawX = drawX + cupWidth + cupSpacing;
                counter2++;
                }
            //Decrement base length to reduce number of cups on next level   
            baseLength--;

            counter1++;
            //Shift x by 1/2 of the total value of cupWidth and cupSpacing
            drawX = startX + (((cupWidth + cupSpacing)/2) * counter1);
            //Raise height of next level by one cup height
            drawY = startY - (cupHeight * counter1);   
            }       
        }

        public static void main(String[] args) {

            //Create application object with 550 x 550 size and visibility = true
            Cups1 cup = new Cups1();
            cup.setSize(550,550);
            cup.setVisible(true);
            //Close application by clicking "x"
            cup.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }

}

只要 Swing 确定应该绘制组件,Swing 组件就会不断地重新绘制。

组件在绘制时做的第一件事是清除它自己的背景,然后重新绘制。

因此,变量总是需要重置为初始值(在绘制方法中),这样循环才能正确执行。例如,在您的情况下,需要在绘画方法中将 "baseLength" 变量 wound 设置为“7”,否则第一次调用该方法时将其设置为 0,因此永远不需要做又画了。

此外,自定义绘画是通过覆盖 JPanel(或 JComponent)的 paintComponent(...) 方法来完成的。然后将面板添加到框架中。阅读有关 Custom Painting 的 Swing 教程部分,了解更多信息和工作示例。