【问题标题】:Unexpected ArrayIndexOutOfBoundsException in JavaFX application, refering to no arrayJavaFX 应用程序中出现意外的 ArrayIndexOutOfBoundsException,指的是没有数组
【发布时间】:2013-11-04 14:28:51
【问题描述】:

我有以下代码:

 public void setContent(Importer3D importer) {
    if (DEBUG) {
        System.out.println("Initialization of Mesh's arrays");
    }
    coords = importer.getCoords();
    texCoords = importer.getTexCoords();
    faces = importer.getFaces();
    if (DEBUG) {
        System.out.println("Applying Mesh's arrays");
    }
    mesh = new TriangleMesh();
    mesh.getPoints().setAll(coords);
    mesh.getTexCoords().setAll(texCoords);
    mesh.getFaces().setAll(faces);
    if (DEBUG) {
        System.out.println("Initialization of the material");
    }
    initMaterial();
    if (DEBUG) {
        System.out.println("Setting the MeshView");
    }
    meshView.setMesh(mesh);
    meshView.setMaterial(material);
    meshView.setDrawMode(DrawMode.FILL);
    if (DEBUG) {
        System.out.println("Adding to 3D scene");
    }
    root3d.getChildren().clear();
    root3d.getChildren().add(meshView);
    if (DEBUG) {
        System.out.println("3D model is ready!");
    }
}

Imporeter3D 类部分:

  private void load(File file) {

    stlLoader = new STLLoader(file);
}

public float[] getCoords() {
    return stlLoader.getCoords();
}

public float[] getTexCoords() {
    return stlLoader.getTexCoords();
}

public int[] getFaces() {
    return stlLoader.getFaces();
}

STLLoader:

public class STLLoader{
public STLLoader(File file) {
    stlFile = new STLFile(file);
    loadManager = stlFile.loadManager;
    pointsArray = new PointsArray(stlFile);
    texCoordsArray = new TexCoordsArray();
}

public float[] getCoords() {
    return pointsArray.getPoints();
}

public float[] getTexCoords() {
    return texCoordsArray.getTexCoords();
}

public int[] getFaces() {
    return pointsArray.getFaces();
}

private STLFile stlFile;
private PointsArray pointsArray;
private TexCoordsArray texCoordsArray;
private FacesArray facesArray;
public  SimpleBooleanProperty finished = new SimpleBooleanProperty(false);
public LoadManager loadManager;}

PointsArray 文件:

public class PointsArray {
public PointsArray(STLFile stlFile) {
    this.stlFile = stlFile;
    initPoints();
}

private void initPoints() {
    ArrayList<Double> pointsList = stlFile.getPoints();
    ArrayList<Double> uPointsList = new ArrayList<>();


    faces = new int[pointsList.size()*2];
    int n = 0;
    for (Double d : pointsList) {
        if (uPointsList.indexOf(d) == -1) {
            uPointsList.add(d);
        }
        faces[n] = uPointsList.indexOf(d);
        faces[++n] = 0;
        n++;
    }
    int i = 0;

    points = new float[uPointsList.size()];
    for (Double d : uPointsList) {
        points[i] = d.floatValue();
        i++;
    }
}

public float[] getPoints() {
    return points;
}

public  int[] getFaces() {
    return faces;
}

private float[] points;
private int[] faces;
private STLFile stlFile;
public static boolean DEBUG = true;

}

还有 STLFile:

    ArrayList<Double> coords = new ArrayList<>();
double temp;
private void readV(STLParser parser) {
    for (int n = 0; n < 3; n++) {
        if(!(parser.ttype==STLParser.TT_WORD && parser.sval.equals("vertex"))) {
            System.err.println("Format Error:expecting 'vertex' on line " + parser.lineno());
        } else {
            if (parser.getNumber()) {
                temp = parser.nval;
                coords.add(temp);
                if(DEBUG) {
                    System.out.println("Vertex:");
                    System.out.print("X=" + temp + " ");
                }

                if (parser.getNumber()) {
                    temp = parser.nval;
                    coords.add(temp);
                    if(DEBUG) {
                        System.out.print("Y=" + temp + " ");
                    }

                    if (parser.getNumber()) {
                        temp = parser.nval;
                        coords.add(temp);
                        if(DEBUG) {
                            System.out.println("Z=" + temp + " ");
                        }


                        readEOL(parser);
                    } else System.err.println("Format Error: expecting coordinate on line " + parser.lineno());
                } else System.err.println("Format Error: expecting coordinate on line " + parser.lineno());
            } else System.err.println("Format Error: expecting coordinate on line " + parser.lineno());
        }
        if (n < 2) {
            try {
                parser.nextToken();
            } catch (IOException e) {
                System.err.println("IO Error on line " + parser.lineno() + ": " + e.getMessage());
            }
        }
    }

}

public ArrayList<Double> getPoints() {
    return coords;
}

由于所有这些代码,我希望在 MeshView 中获得 3d 模型。但是现在的结果很奇怪:一切正常,在DEBUG 模式下,我从setContent() 得到3d model is ready!,然后是意想不到的ArrayIndexOutOfBoundsException

File readed
Initialization of Mesh's arrays
Applying Mesh's arrays
Initialization of the material
Setting the MeshView
Adding to 3D scene
3D model is ready!
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 32252
    at com.sun.javafx.collections.ObservableFloatArrayImpl.rangeCheck(ObservableFloatArrayImpl.java:276)
    at com.sun.javafx.collections.ObservableFloatArrayImpl.get(ObservableFloatArrayImpl.java:184)
    at javafx.scene.shape.TriangleMesh.computeBounds(TriangleMesh.java:262)
    at javafx.scene.shape.MeshView.impl_computeGeomBounds(MeshView.java:151)
    at javafx.scene.Node.updateGeomBounds(Node.java:3497)
    at javafx.scene.Node.getGeomBounds(Node.java:3450)
    at javafx.scene.Node.getLocalBounds(Node.java:3432)
    at javafx.scene.Node.updateTxBounds(Node.java:3510)
    at javafx.scene.Node.getTransformedBounds(Node.java:3350)
    at javafx.scene.Node.updateBounds(Node.java:516)
    at javafx.scene.Parent.updateBounds(Parent.java:1668)
    at javafx.scene.SubScene.updateBounds(SubScene.java:556)
    at javafx.scene.Parent.updateBounds(Parent.java:1668)
    at javafx.scene.Parent.updateBounds(Parent.java:1668)
    at javafx.scene.Parent.updateBounds(Parent.java:1668)
    at javafx.scene.Parent.updateBounds(Parent.java:1668)
    at javafx.scene.Parent.updateBounds(Parent.java:1668)
    at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2309)
    at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:329)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:479)
    at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:459)
    at com.sun.javafx.tk.quantum.QuantumToolkit$13.run(QuantumToolkit.java:326)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
    at com.sun.glass.ui.win.WinApplication$3$1.run(WinApplication.java:101)
    at java.lang.Thread.run(Thread.java:724)
Exception in thread "JavaFX Application Thread" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 32252
    at com.sun.javafx.collections.ObservableFloatArrayImpl.rangeCheck(ObservableFloatArrayImpl.java:276)
    at com.sun.javafx.collections.ObservableFloatArrayImpl.get(ObservableFloatArrayImpl.java:184)

奇怪的是,这个堆栈直到我关闭程序才停止。而且它不指向任何我的数组。这是什么?为什么会这样?

【问题讨论】:

  • 看来你有一个cords.length % 3 > 0的点坐标数组。你能在“mesh.getPoints().setAll(coords)之前检查“coords”的大小吗;" ?
  • @user987339 在这种情况下(我的意思是这个 STL 文件) - 32252。但我不明白这个数组的大小如何影响程序的行为。所有面都是由int[] faces数组创建的,该数组将顶点与纹理坐标连接起来。

标签: java arrays exception javafx-8


【解决方案1】:

TriangleMesh 将此数组视为点坐标(x,y,z,因为它是 3D),因此数组总长度应为cords.length % 3 == 0

【讨论】:

  • 如果这个数组包含重复项,是否需要删除它们?
  • 我不知道你用例的细节。尽量不要删除它。如果结果不正确,则将其删除:-)
  • 好吧,我刚刚将数组更改为另一个数组,其中包含重复项和 size%3 == 0,但我有:ноя 04, 2013 8:10:13 PM com.sun.prism.impl.BaseMesh computeTBNormal WARNING: Dead face [0, 0, 0] @ face group 0; nEmptyFaces = 1 ноя 04, 2013 8:10:13 PM com.sun.prism.impl.BaseMesh computeTBNormal WARNING: Dead face [0, 0, 0] @ face group 1; nEmptyFaces = 2 ноя 04, 2013 8:10:13 PM com.sun.prism.impl.BaseMesh computeTBNormal WARNING: Dead face [0, 0, 0] @ face group 2; nEmptyFaces = 3...。你知道它是什么吗?
  • 如果点具有以下特征,则会警告点 (x,y,z) 的死面:x == y || y == z || z == x;
猜你喜欢
  • 1970-01-01
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 1970-01-01
相关资源
最近更新 更多