Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
奇怪的随机错误,java绘图_Java - Fatal编程技术网

奇怪的随机错误,java绘图

奇怪的随机错误,java绘图,java,Java,我已经写了一个程序,我认为它应该能完美地工作。由于某种原因,它没有。我会提供代码,希望有人能找出问题所在。我已经坐了好几个小时了,但我再也坐不住了 import java.awt.*; import javax.swing.*; public class CrystalModel { private int radius; private int index; private boolean[][] crystal; private Point concludi

我已经写了一个程序,我认为它应该能完美地工作。由于某种原因,它没有。我会提供代码,希望有人能找出问题所在。我已经坐了好几个小时了,但我再也坐不住了

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

public class CrystalModel
{
    private int radius;
    private int index;
    private boolean[][] crystal;
    private Point concludingPoint;
    private int escapeRadius;

    /**
     * Constructor. Initiates an electron bath of size 30x30.
     */
    public CrystalModel()
    {
        radius = 30;
        index = 30*2-1;
        start();
    }

    /**
     * Constructor. Initiates an electron bath of size r.
     * @param r bath radius
     */
    public CrystalModel(int r)
    {
        radius = r;
        index = r*2-1;
        start();
    }

    /**
     * Initiates the experiment
     */
    private void start()
    {
        crystal = new boolean[radius*2][radius*2];
        crystal[radius][radius] = true; //The width is always even (2*r), this is as close to the center as one gets
        escapeRadius = (int)(1.1*radius);
    }

    /**
     * Determines if a given xy-coordinate is within radius
     * @param x x-coordinate
     * @param y y-coordinate
     * @return whether the active ion is out of range
     */
    private boolean outsideCircle(int r, int x, int y)
    {
        return (Math.pow(x,2)+Math.pow(y,2) >= Math.pow(r, 2));
    }

    /**
     * Determines if the currently active ion has a neighbouring crystallized ion
     * @param whether the is a neighbour
     */
    private boolean anyNeighbours(int x, int y)
    {
            x = xBathToModel(x);
            y = yBathToModel(y);

            boolean left    = (x-1 >= 0) && (x-1 <= index) && (y >= 0) && (y <= index)  ? crystal[x-1][y] : false;
            boolean right   = (x+1 >= 0) && (x+1 <= index) && (y >= 0) && (y <= index)  ? crystal[x+1][y] : false;
            boolean up      = (y-1 >= 0) && (y-1 <= index) && (x >= 0) && (x <= index)  ? crystal[x][y-1] : false;
            boolean down    = (y+1 >= 0) && (y+1 <= index) && (x >= 0) && (x <= index)  ? crystal[x][y+1] : false;

            return ( left || right || up || down );
    }

    /**
     * Determines an xy-coordinate at radius distance from the center
     * @param radius radius of escape for ions
     * @return Point object encapsulating x, y
     */
    private Point dropNewIon()
    {
        double angle = (int)(Math.random()*2*Math.PI);
        return new Point( (int)( Math.cos(angle)*(index/2) ), (int)( Math.sin(angle)*(index/2) ) );
    }

    /**
     * Transform x-coordinate upon the moving of origo from center to top-left
     * @ x x-coordinate
     */
    public int xBathToModel(int x)
    {
        return radius+x;
    }

    /**
     * Transform y-coordinate upon the moving of origo from center to top-left
     * @param y y-coordinate
     */
    public int yBathToModel(int y)
    {
        return radius+y;
    }

    /**
     * Increments the number of ions in the crystal by one
     * @return boolean indicating whether the experiment is done or not
     */
    private Point crystallizeOneIon()
    {
        Point point = dropNewIon();
        for( ; ; )
        {
            switch((int)(Math.random()*4+1))
            {
                case 1: point.x+=1;
                    break;
                case 2: point.x-=1;
                    break;
                case 3: point.y+=1;
                    break;
                case 4: point.y-=1;
                    break;
            }

            if(outsideCircle(escapeRadius, point.x, point.y)) point = dropNewIon();

            if(anyNeighbours(point.x, point.y)) break;
        }

        crystal[xBathToModel(point.x)][yBathToModel(point.y)] = true;
        return point;
    }

    /**
     * Let the algorithm (CrystalExperiment) simulate a number of steps
     * @param steps how many steps
     * @return boolean indiciating whether the experiment is concluded
     */
    public boolean runExperiment(int steps)
    {
        for(int i=0; i<steps; i++)
        {
            concludingPoint = crystallizeOneIon();

            if(outsideCircle((int)index/2, concludingPoint.x, concludingPoint.y)) 
            {
                concludingPoint.x = xBathToModel(concludingPoint.x);
                concludingPoint.y = yBathToModel(concludingPoint.y);
                return true;
            }
            else
            {
                concludingPoint.x = xBathToModel(concludingPoint.x);
                concludingPoint.y = yBathToModel(concludingPoint.y);
            }
        }

        return false;
    }

    /**
     * Return a textual representation of the crystal
     * @return String representing the crystal
     */
    public String toString()
    {
        String output = "";
        for(int y=-1; y<=index+1; y++)
        {
            for(int x=-1; x<=index+1; x++)
            {
                if(y == -1) output+="--";
                else if(y == index+1) output+="--";
                else
                {
                    if(x == -1) output+="|";
                    else if(x == index+1) output+="|";
                    else
                    {
                        if(concludingPoint.equals(new Point(x,y))) output+="# ";
                        else if(crystal[x][y] == true) output+="* ";
                        else output+="  ";
                    }
                }
            }
            output+="\n";
        }

        return output;
    }

    public int getIndexSize()
    {
        return index;
    }

    public boolean getMatrixValue(int x, int y)
    {
        return crystal[x][y];
    }

    private void drawCrystal()
    {
        JFrame frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setBounds(0, 0, 200, 200);

        CrystalView drawing = new CrystalView(this);
        frame.add(drawing);
    }

    public static void main(String[] args)
    {
        (new CrystalModel(200)).drawCrystal();
    }

}
import java.awt.*;
导入javax.swing.*;
公共类晶体模型
{
私有整数半径;
私有整数索引;
私有布尔[][]晶体;
私人点总结点;
私家车;
/**
*建造商。启动尺寸为30x30的电子浴。
*/
公共水晶模型()
{
半径=30;
指数=30*2-1;
start();
}
/**
*建造师。启动尺寸为r的电子浴。
*@param r浴池半径
*/
公共水晶模型(INTR)
{
半径=r;
指数=r*2-1;
start();
}
/**
*开始实验
*/
私有void start()
{
crystal=新布尔值[radius*2][radius*2];
crystal[radius][radius]=true;//宽度始终为偶数(2*r),这是最接近中心的距离
逃逸半径=(int)(1.1*半径);
}
/**
*确定给定xy坐标是否在半径范围内
*@param x x坐标
*@param y坐标
*@return活动离子是否超出范围
*/
私有布尔外圆(int r,int x,int y)
{
return(Math.pow(x,2)+Math.pow(y,2)>=Math.pow(r,2));
}
/**
*确定当前活动离子是否有相邻的结晶离子
*@param是否为邻居
*/
私有布尔任意邻域(int x,int y)
{
x=xBathToModel(x);
y=yBathToModel(y);
布尔左=(x-1>=0)和(x-1=0)和(y=0)和(x+1=0)和(y=0)和(y-1=0)和(x=0)和(y+1=0)和(x
公共空心颜料组件(图形g)
{ 
而(!model.runExperiment(1))
{ 
对于(int y=0;y我试图修复您的代码(请参见下文)。问题的位置用TODO标记。不知道它打算如何工作,但现在它引出了一些要点

如前一个答案中所述,您无法获得这样的动画。仅调用一次
paintComponent()
方法来绘制组件。例如,在调整窗体大小时会发生这种情况。因此,您只能获得静态图像

CrystalModel.java

import java.awt.Point;
import javax.swing.JFrame;

public class CrystalModel
{
    private int radius;
    private int index;
    private boolean[][] crystal;
    private Point concludingPoint;
    private int escapeRadius;

    /**
     * Constructor. Initiates an electron bath of size 30x30.
     */
    public CrystalModel()
    {
        radius = 30;
        index = 30*2-1;
        start();
    }

    /**
     * Constructor. Initiates an electron bath of size r.
     * @param r bath radius
     */
    public CrystalModel(int r)
    {
        radius = r;
        index = r*2-1;
        start();
    }

    /**
     * Initiates the experiment
     */
    private void start()
    {
        crystal = new boolean[radius*2][radius*2];
        crystal[radius][radius] = true; //The width is always even (2*r), this is as close to the center as one gets
        escapeRadius = (int)(1.1*radius);
    }

    /**
     * Determines if a given xy-coordinate is within radius
     * @param x x-coordinate
     * @param y y-coordinate
     * @return whether the active ion is out of range
     */
    private boolean outsideCircle(int r, int x, int y)
    {
        return (Math.pow(x,2)+Math.pow(y,2) >= Math.pow(r, 2));
    }

    /**
     * Determines if the currently active ion has a neighbouring crystallized ion
     * @param whether the is a neighbour
     */
    private boolean anyNeighbours(int x, int y)
    {
            x = xBathToModel(x);
            y = yBathToModel(y);

            boolean left    = (x-1 >= 0) && (x-1 <= index) && (y >= 0) && (y <= index)  ? crystal[x-1][y] : false;
            boolean right   = (x+1 >= 0) && (x+1 <= index) && (y >= 0) && (y <= index)  ? crystal[x+1][y] : false;
            boolean up      = (y-1 >= 0) && (y-1 <= index) && (x >= 0) && (x <= index)  ? crystal[x][y-1] : false;
            boolean down    = (y+1 >= 0) && (y+1 <= index) && (x >= 0) && (x <= index)  ? crystal[x][y+1] : false;

            return ( left || right || up || down );
    }

    /**
     * Determines an xy-coordinate at radius distance from the center
     * @param radius radius of escape for ions
     * @return Point object encapsulating x, y
     */
    private Point dropNewIon()
    {
        double angle = (int)(Math.random()*2*Math.PI);
        return new Point( (int)( Math.cos(angle)*(index/2) ), (int)( Math.sin(angle)*(index/2) ) );
    }

    /**
     * Transform x-coordinate upon the moving of origo from center to top-left
     * @ x x-coordinate
     */
    public int xBathToModel(int x)
    {
        return radius+x;
    }

    /**
     * Transform y-coordinate upon the moving of origo from center to top-left
     * @param y y-coordinate
     */
    public int yBathToModel(int y)
    {
        return radius+y;
    }

    /**
     * Increments the number of ions in the crystal by one
     * @return boolean indicating whether the experiment is done or not
     */
    private Point crystallizeOneIon()
    {
        Point point = dropNewIon();
        for( ; ; )
        {
            switch((int)(Math.random()*4+1))
            {
                case 1: point.x+=1;
                    break;
                case 2: point.x-=1;
                    break;
                case 3: point.y+=1;
                    break;
                case 4: point.y-=1;
                    break;
            }

            if(outsideCircle(escapeRadius, point.x, point.y)) point = dropNewIon();

            if(anyNeighbours(point.x, point.y)) break;
            break;
        }

        try {
            // TODO The logic is wrong here - calculated points sometimes are out of array. See console output
            crystal[xBathToModel(point.x)][yBathToModel(point.y)] = true;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Oops, point (" + point.x + ", " + point.y +  ") is out of array");
        }
        return point;
    }

    /**
     * Let the algorithm (CrystalExperiment) simulate a number of steps
     * @param steps how many steps
     * @return boolean indiciating whether the experiment is concluded
     */
    public synchronized boolean runExperiment(int steps)
    {
        for(int i=0; i<steps; i++)
        {
            concludingPoint = crystallizeOneIon();

            if(outsideCircle((int)index/2, concludingPoint.x, concludingPoint.y))
            {
                concludingPoint.x = xBathToModel(concludingPoint.x);
                concludingPoint.y = yBathToModel(concludingPoint.y);
                return true;
            }
            else
            {
                concludingPoint.x = xBathToModel(concludingPoint.x);
                concludingPoint.y = yBathToModel(concludingPoint.y);
            }
        }

        return false;
    }

    /**
     * Return a textual representation of the crystal
     * @return String representing the crystal
     */
    public String toString()
    {
        String output = "";
        for(int y=-1; y<=index+1; y++)
        {
            for(int x=-1; x<=index+1; x++)
            {
                if(y == -1) output+="--";
                else if(y == index+1) output+="--";
                else
                {
                    if(x == -1) output+="|";
                    else if(x == index+1) output+="|";
                    else
                    {
                        if(concludingPoint.equals(new Point(x,y))) output+="# ";
                        else if(crystal[x][y] == true) output+="* ";
                        else output+="  ";
                    }
                }
            }
            output+="\n";
        }

        return output;
    }

    public int getIndexSize()
    {
        return index;
    }

    public boolean getMatrixValue(int x, int y)
    {
        return crystal[x][y];
    }

    private void drawCrystal()
    {
        JFrame frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setBounds(0, 0, 600, 600);

        CrystalView drawing = new CrystalView(this);
        frame.add(drawing);
        frame.validate();
    }

    public static void main(String[] args)
    {
        (new CrystalModel(200)).drawCrystal();
    }

}
导入java.awt.Point;
导入javax.swing.JFrame;
公共类晶体模型
{
私有整数半径;
私有整数索引;
私有布尔[][]晶体;
私人点总结点;
私家车;
/**
*建造商。启动尺寸为30x30的电子浴。
*/
公共水晶模型()
{
半径=30;
指数=30*2-1;
start();
}
/**
*建造商。启动尺寸为r的电子浴。
*@param r浴池半径
*/
公共水晶模型(INTR)
{
半径=r;
指数=r*2-1;
start();
}
/**
*开始实验
*/
私有void start()
{
crystal=新布尔值[radius*2][radius*2];
crystal[radius][radius]=true;//宽度始终为偶数(2*r),这是最接近中心的距离
逃逸半径=(int)(1.1*半径);
}
/**
*确定给定xy坐标是否在半径范围内
*@param x x坐标
*@param y坐标
*@return活动离子是否超出范围
*/
私有布尔外圆(int r,int x,int y)
{
return(Math.pow(x,2)+Math.pow(y,2)>=Math.pow(r,2));
}
/**
*确定当前活动离子是否有相邻的结晶离子
*@param是否为邻居
*/
私有布尔任意邻域(int x,int y)
{
x=xBathToModel(x);
y=yBathToModel(y);

布尔左=(x-1>=0)和&(x-1=0)和&(y=0)和&(x+1=0)和&(y-1=0)和&(x=0)和&(y+1=0)和&(x)“请运行程序,您将看到我的意思。”.不,我不会。如果您需要帮助,您需要付出一些努力来告诉我们问题是什么。问题非常简单。如果您查看for循环,它将循环通过1-200,并在该区域内填充像素(200x200).但是如果你画它,图形会变得非常小。如果它真的画了,也就是说。如果它的大小只有200px,它会完全冻结,所以我想我正在做一些事情来减慢它。另外,只需关注绘图部分,因为我已经验证了模型的工作。toString返回图形应该是什么样子的正确图像好的。基本上,我画的图片是递增的。每次我运行“RunExperience”矩阵得到了一个新的值。所以我必须再次做循环,画出所有的东西。因此,应该有一点动画,人们可以看到图像变大…但我不需要计时器或类似的东西。我几乎100%确定这是某种预期的解决方案。这个循环肯定不属于那里。repaint将导致再次调用paintComponent,等等。您需要的只是该循环的内容,以及一个重复调用
model.runExperiment(1)
repaint()
的计时器。paintComponent()方法用于绘制组件的当前状态。如果要更改组件的状态,则可以使用其他方法。也就是说,可以使用计时器或其他方法调用更改组件状态的方法,然后该方法调用repaint()@Calle,查看Walter Lan的示例,该示例演示了如何使用计时器通过调用“addPoint()”方法来更改组件的状态:感谢您的努力,我非常感谢。不过,请尝试将drawCrystal中的代码替换为while(this.runExperiment(1)){System.out.println(this.toString());}在主程序中调用它,如下所示:
public void paintComponent(Graphics g) 
{ 
    while(!model.runExperiment(1)) 
    { 
        for(int y=0; y<model.getIndexSize(); y++) 
        { 
            for(int x=0; x<model.getIndexSize(); x++) 
            { 
                if(model.getMatrixValue(x,y)) 
                g.drawOval(x, y, 1, 1); 
            } 
        } 
        this.repaint(); 
    } 
} 
import java.awt.Point;
import javax.swing.JFrame;

public class CrystalModel
{
    private int radius;
    private int index;
    private boolean[][] crystal;
    private Point concludingPoint;
    private int escapeRadius;

    /**
     * Constructor. Initiates an electron bath of size 30x30.
     */
    public CrystalModel()
    {
        radius = 30;
        index = 30*2-1;
        start();
    }

    /**
     * Constructor. Initiates an electron bath of size r.
     * @param r bath radius
     */
    public CrystalModel(int r)
    {
        radius = r;
        index = r*2-1;
        start();
    }

    /**
     * Initiates the experiment
     */
    private void start()
    {
        crystal = new boolean[radius*2][radius*2];
        crystal[radius][radius] = true; //The width is always even (2*r), this is as close to the center as one gets
        escapeRadius = (int)(1.1*radius);
    }

    /**
     * Determines if a given xy-coordinate is within radius
     * @param x x-coordinate
     * @param y y-coordinate
     * @return whether the active ion is out of range
     */
    private boolean outsideCircle(int r, int x, int y)
    {
        return (Math.pow(x,2)+Math.pow(y,2) >= Math.pow(r, 2));
    }

    /**
     * Determines if the currently active ion has a neighbouring crystallized ion
     * @param whether the is a neighbour
     */
    private boolean anyNeighbours(int x, int y)
    {
            x = xBathToModel(x);
            y = yBathToModel(y);

            boolean left    = (x-1 >= 0) && (x-1 <= index) && (y >= 0) && (y <= index)  ? crystal[x-1][y] : false;
            boolean right   = (x+1 >= 0) && (x+1 <= index) && (y >= 0) && (y <= index)  ? crystal[x+1][y] : false;
            boolean up      = (y-1 >= 0) && (y-1 <= index) && (x >= 0) && (x <= index)  ? crystal[x][y-1] : false;
            boolean down    = (y+1 >= 0) && (y+1 <= index) && (x >= 0) && (x <= index)  ? crystal[x][y+1] : false;

            return ( left || right || up || down );
    }

    /**
     * Determines an xy-coordinate at radius distance from the center
     * @param radius radius of escape for ions
     * @return Point object encapsulating x, y
     */
    private Point dropNewIon()
    {
        double angle = (int)(Math.random()*2*Math.PI);
        return new Point( (int)( Math.cos(angle)*(index/2) ), (int)( Math.sin(angle)*(index/2) ) );
    }

    /**
     * Transform x-coordinate upon the moving of origo from center to top-left
     * @ x x-coordinate
     */
    public int xBathToModel(int x)
    {
        return radius+x;
    }

    /**
     * Transform y-coordinate upon the moving of origo from center to top-left
     * @param y y-coordinate
     */
    public int yBathToModel(int y)
    {
        return radius+y;
    }

    /**
     * Increments the number of ions in the crystal by one
     * @return boolean indicating whether the experiment is done or not
     */
    private Point crystallizeOneIon()
    {
        Point point = dropNewIon();
        for( ; ; )
        {
            switch((int)(Math.random()*4+1))
            {
                case 1: point.x+=1;
                    break;
                case 2: point.x-=1;
                    break;
                case 3: point.y+=1;
                    break;
                case 4: point.y-=1;
                    break;
            }

            if(outsideCircle(escapeRadius, point.x, point.y)) point = dropNewIon();

            if(anyNeighbours(point.x, point.y)) break;
            break;
        }

        try {
            // TODO The logic is wrong here - calculated points sometimes are out of array. See console output
            crystal[xBathToModel(point.x)][yBathToModel(point.y)] = true;
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Oops, point (" + point.x + ", " + point.y +  ") is out of array");
        }
        return point;
    }

    /**
     * Let the algorithm (CrystalExperiment) simulate a number of steps
     * @param steps how many steps
     * @return boolean indiciating whether the experiment is concluded
     */
    public synchronized boolean runExperiment(int steps)
    {
        for(int i=0; i<steps; i++)
        {
            concludingPoint = crystallizeOneIon();

            if(outsideCircle((int)index/2, concludingPoint.x, concludingPoint.y))
            {
                concludingPoint.x = xBathToModel(concludingPoint.x);
                concludingPoint.y = yBathToModel(concludingPoint.y);
                return true;
            }
            else
            {
                concludingPoint.x = xBathToModel(concludingPoint.x);
                concludingPoint.y = yBathToModel(concludingPoint.y);
            }
        }

        return false;
    }

    /**
     * Return a textual representation of the crystal
     * @return String representing the crystal
     */
    public String toString()
    {
        String output = "";
        for(int y=-1; y<=index+1; y++)
        {
            for(int x=-1; x<=index+1; x++)
            {
                if(y == -1) output+="--";
                else if(y == index+1) output+="--";
                else
                {
                    if(x == -1) output+="|";
                    else if(x == index+1) output+="|";
                    else
                    {
                        if(concludingPoint.equals(new Point(x,y))) output+="# ";
                        else if(crystal[x][y] == true) output+="* ";
                        else output+="  ";
                    }
                }
            }
            output+="\n";
        }

        return output;
    }

    public int getIndexSize()
    {
        return index;
    }

    public boolean getMatrixValue(int x, int y)
    {
        return crystal[x][y];
    }

    private void drawCrystal()
    {
        JFrame frame = new JFrame("");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setBounds(0, 0, 600, 600);

        CrystalView drawing = new CrystalView(this);
        frame.add(drawing);
        frame.validate();
    }

    public static void main(String[] args)
    {
        (new CrystalModel(200)).drawCrystal();
    }

}
import java.awt.Graphics;

import javax.swing.JPanel;

public class CrystalView extends JPanel {
    private static final long serialVersionUID = 1L;

    CrystalModel model;

    public CrystalView(CrystalModel m) {
        model = m;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        while (!model.runExperiment(1)) {
            for (int y = 0; y < model.getIndexSize(); y++) {
                for (int x = 0; x < model.getIndexSize(); x++) {
                    if (model.getMatrixValue(x, y)) {
                        g.drawOval(x, y, 2, 2);
                    }
                }
            }
        }
    }
}