for循环仅在调试时运行(eclipse)&各种变化

时间:2014-12-26 17:24:21

标签: java eclipse debugging loops user-interface

我试图创建一系列具有不同颜色(随机)的同心圆轮廓,并编写了一个脚本来实现这一目标。问题是,当我运行程序时,只绘制一个一个圆圈。然而,当我单步执行代码时,圆圈会按照我希望的方式显示,直到我单击“恢复”,此时代码会再次稍微混乱。我很茫然,因为调试似乎是诊断问题的唯一方法,但似乎也是脚本远程工作的唯一方式。 我试图通过让系统打印变量 i 来实际查看循环是否实际被跳过,每个循环出现多个圆圈,但是仍然只有3或4个,这一点要点因为它有所不同!每次我运行脚本时,我都会得到一个不同数量的圆圈,这让我相信一些非常奇怪的事情,这对我来说太直觉了。感谢阅读,这里是脚本(我建议人们将其复制到eclipse中,看看他们得到了什么输出)。附:我知道这些圈子并不是同心的,但这是我现在担心的最少 的问题
1)为什么在运行此脚本时似乎跳过了for循环? 2)为什么当我让系统在每个循环中打印一些东西时,这会稍微解决问题,但仍然会产生这种随机变化?

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

public class CircleGenerator {
    private int outerDiameter;
    private int innerDiameter;
    private int colorRange;
    private Color bgColor;
    private JFrame frame;
    private JPanel mainPanel;
    //private JButton nextCircleButton;
    private CircleDrawer drawer;

    public CircleGenerator(int outer, int inner, int colorRange, Color bgColor) {
        this.outerDiameter = outer;
        this.innerDiameter = inner;
        this.colorRange = colorRange;
        this.bgColor = bgColor;
    }

    public static void main(String[] args) {
        CircleGenerator myGenerator = new CircleGenerator(300,20,200,Color.RED);
        myGenerator.setupGUI();
        myGenerator.genCircle();
    }
    public void setupGUI() {
        // Sets up the environment for the circles to be drawn
        frame = new JFrame("Beautiful Circles");
        mainPanel = new JPanel();
        mainPanel.setBackground(bgColor);
        //JButton nextCircleButton = new JButton("Next Circle");          //will use later to regenerate more circles
        drawer = new CircleDrawer();
        //mainPanel.add(drawer);
        frame.getContentPane().add(drawer);
        frame.setSize(outerDiameter+innerDiameter, outerDiameter+innerDiameter+20);
        frame.setVisible(true);
    }

    private void genCircle() {
        // generate the necessary parameters to send to the Circle Drawer
        for (int i = innerDiameter; i < outerDiameter+1; i++) {
            //System.out.println(i);      //REMOVE THIS TO GET THE VARIATION!!!!
            int red = (int) (Math.random() * colorRange) + 1;
            int green = (int) (Math.random() * colorRange + 1);
            int blue = (int) (Math.random() * colorRange + 1);
            //int x = i - innerDiameter;
            //int y = frame.getContentPane().getHeight() - i;
            int x = 0;
            int y = 0;
            drawer.updateValues(i, x, y, red, green, blue);
            drawer.repaint();
        }

    }

    class CircleDrawer extends JPanel {
        private int diameter;
        private int x;       //  the two x and y values are for the
        private int y;       //  coordinates of the upper left corner of the oval.
        private int red;
        private int green;
        private int blue;

        void updateValues(int diameter, int x, int y, int red, int green, int blue) {
            this.diameter = diameter;
            this.x = x;
            this.y = y;
            this.red = red;
            this.green = green;
            this.blue = blue;
        }

        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(new Color(red,green,blue));
            g.drawOval(x,y,diameter,diameter);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

您的代码似乎很奇怪但我对您有快速反应。试试这个:

private void genCircle()
{
    // generate the necessary parameters to send to the Circle Drawer
    for (int i = innerDiameter; i < outerDiameter + 1; i++)
    {
        //System.out.println(i); //REMOVE THIS TO GET THE VARIATION!!!!
        int red = (int) (Math.random() * colorRange) + 1;
        int green = (int) (Math.random() * colorRange + 1);
        int blue = (int) (Math.random() * colorRange + 1);
        // int x = i - innerDiameter;
        // int y = frame.getContentPane().getHeight() - i;
        int x = 0;
        int y = 0;
        drawer.updateValues(i, x, y, red, green, blue);
        drawer.repaint();

        try
        {
            Thread.sleep(5);
        }
        catch (InterruptedException e){}
    }
}

如果你想看到一些东西,你必须给AWT线程一些时间来完成他的工作。

答案 1 :(得分:0)

另一种解决方案(清洁工)可能是:

public class CircleGenerator
{
    private int outerDiameter;
    private int innerDiameter;
    private int colorRange;
    private Color bgColor;
    private JFrame frame;
    private JPanel mainPanel;
    private CircleDrawer drawer;

    public CircleGenerator(int outer, int inner, int colorRange, Color bgColor)
    {
        this.outerDiameter = outer;
        this.innerDiameter = inner;
        this.colorRange = colorRange;
        this.bgColor = bgColor;
    }

    public static void main(String[] args)
    {
        CircleGenerator myGenerator = new CircleGenerator(300, 20, 200, Color.RED);
        myGenerator.setupGUI();
    }

    public void setupGUI()
    {
        // Sets up the environment for the circles to be drawn
        frame = new JFrame("Beautiful Circles");
        mainPanel = new JPanel();
        mainPanel.setBackground(bgColor);
        // JButton nextCircleButton = new JButton("Next Circle"); //will use later to regenerate more circles
        drawer = new CircleDrawer();
        // mainPanel.add(drawer);
        frame.getContentPane().add(drawer);
        frame.setSize(outerDiameter + innerDiameter, outerDiameter + innerDiameter + 20);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    class CircleDrawer extends JPanel
    {
        @Override
        protected void paintComponent(Graphics g)
        {
            // generate the necessary parameters to send to the Circle Drawer
            for (int i = innerDiameter; i < outerDiameter + 1; i++)
            {
                int red   = (int) (Math.random() * colorRange) + 1;
                int green = (int) (Math.random() * colorRange + 1);
                int blue  = (int) (Math.random() * colorRange + 1);
                int x = 0;
                int y = 0;

                g.setColor(new Color(red, green, blue));
                g.drawOval(x, y, i, i);
            }
        }
    }
}

绘制圆圈是在paint方法中完成的。在这种情况下,绘画方法是绘制所有圆圈不仅一个。 注意,一般来说,甚至禁止使用repaint()方法。您应该使用invalidate()来表示您的绘图作业已完成,然后AWT线程可以绘制整个场景。不要忘记你在AWT线程中。