mouseListener 和 while 循环的问题

Problem with mouseListener and while loop

我正在尝试解决一个问题:我应该使用 mouseListeners 并在鼠标单击时执行以下操作之一:

  1. 如果点击空白 space(我的程序扩展了 GraphicsProgram)添加一个圆并使其颜色随机。
  2. 如果单击圆圈,使圆圈闪烁(从 5 种可能的颜色)直到达到绿色。
//instance variables:
Color[] arr = new Color[] { Color.GREEN, Color.RED, Color.BLUE, Color.BLACK, Color.YELLOW };
private RandomGenerator rgen = RandomGenerator.getInstance();

public void mouseClicked(MouseEvent e) {
        GObject object = getElementAt(e.getX(), e.getY());
        if (object == null) {
            addCircle(e.getX(), e.getY());
        }
        else {
            GOval oval = (GOval) object;
            colorCircle(oval);          
        }
    }

private void colorCircle(GOval circle) {
        while (true) {
            int rand = rgen.nextInt(0, 4);
            circle.setFillColor(arr[rand]);
            pause(DELAY);
            if (rand == 0)
                break;
        }
    }

问题是点击圆圈的时候不闪烁,只是输出绿色。增加 DELAY 只会延迟绿色输出。所以它会跳过其他颜色的着色,直到变成绿色。

我正在使用 Stanford 的库来解决这个问题(我必须使用它们来解决这个问题)。

P.S。我已经在没有鼠标点击的情况下测试了 while 循环,它工作得很好,所以 mouseListener 绝对是导致问题的原因。可能是什么问题以及如何克服它?

问题是由于尝试 运行 来自 mouseClicked 的代码引起的。取而代之的是,我创建了 boolean mouseClicked 并在鼠标单击圆圈时使其为真。然后我调用了运行中的闪烁方法(同main)。这是完整的代码:

public class BlankClass extends GraphicsProgram {

    private final static int CIRCLE_D = 40;
    private RandomGenerator rgen = RandomGenerator.getInstance();   
    private final static int DELAY = 50;
    private volatile boolean  clickedCircle = false;
    Color[] arr = new Color[] { Color.GREEN, Color.RED, Color.BLUE, Color.BLACK, Color.YELLOW };


    public void init() {
        addMouseListeners();
    }

    public void run() {
        while (true) {
            if (clickedCircle) {
                colorCircle();
                clickedCircle = false;
            }
        }
    }

    public void mouseClicked(MouseEvent e) {
        GObject object = getElementAt(e.getX(), e.getY());
        if (object == null) {
            addCircle(e.getX(), e.getY());
        } else {
            oval = (GOval) object;
            clickedCircle = true;
        }
    }

    private void addCircle(int x, int y) {
        int centerX = (x - CIRCLE_D / 2);
        int centerY = (y - CIRCLE_D / 2);
        GOval oval = new GOval(centerX, centerY, CIRCLE_D, CIRCLE_D);
        oval.setFilled(true);
        oval.setFillColor(rgen.nextColor());
        add(oval);
    }

    private void colorCircle() {
        while (true) {
            int rand = rgen.nextInt(0, 4);
            oval.setFillColor(arr[rand]);
            if (rand == 0)
                break;
            pause(DELAY);
        }
    }
}

将布尔 clickedCircle 设置为易失性很重要,否则编译器可能会忽略 while(true) 循环中的条件(这是我遇到的另一个问题)。