You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX应用中StructureNode的x_index/y_index始终返回初始值问题

问题描述

我正在开发一个JavaFX应用,流程为:创建StructureNode对象→通过UI输入更新其数据→将该对象赋值给包含两个StructureNode实例的TrussMember→最终通过StructureSolver读取每个TrussMember中StructureNode的数据作为矩阵索引。

目前遇到的问题:除了private int x_index=0 , y_index=0这两个整数外,所有值都能成功读取,但无论初始值设为0、1还是100,它们始终返回初始值。尝试过使用其他线程、将其设为无初始值的final变量,结果都一致。

相关代码片段

StructureNode类(数据封装类)

public class StructureNode {
    // ...其他属性
    private int x_index=0 , y_index=0;
    // ...其他方法
    public int getX_index() {
        //System.out.println("x_index = " + x_index);
        return x_index;
    }

    public void setX_index(int nex_index) {
        x_index = nex_index;
        System.out.println("x_index changed to " + x_index);
    }

    public int getY_index() {
        //System.out.println("y_index = " +y_index);
        return y_index;
    }

    public void setY_index(int ney_index) {
        y_index = ney_index;
        System.out.println("y_index changed to " + y_index);
    }
}

TrussModelBuider类(模型构建类)

public class TrussModelBuider{
    private boolean isBuilt = false;
    private Truss structure;

    public TrussModelBuider(Truss truss){
        structure = truss;
    }

    @Deprecated
    public void addNode(double X, double Y){
        StructureNode n = new StructureNode();
        n.setCoordinates(new Coordinates(X, Y));
        structure.addJoint(n);
        System.out.println("+pt["+X+", "+Y+"]");
    }
    public void addNode(StructureNode n){
        structure.addJoint(n);
        System.out.println("+pt["+n.getCoordinates().getX_COO()+", "+n.getCoordinates().getY_COO()+"]");
    }

    public void removeNode(double X, double Y){
        structure.getJoints().remove(findNodeIndex(X,Y));
    }

    private int findNodeIndex(double X, double Y){
        int index = 0;
        for (int i = 0; i < structure.getJoints().size(); i++) {
            if (structure.getJoints().get(i).getCoordinates().getX_COO()==X
            && structure.getJoints().get(i).getCoordinates().getY_COO()==Y) {
                index = i;
                break;
            }
        }
        return index;
    }

    public void addMember(TrussMember member){
        structure.addMember(member);
        System.out.println("+mem "+member.getID()+": "+member.getStartJoint()+", "+member.getEndJoint());
    }
    public void removeMember(int ID){
        structure.getMembers().remove(findMember(ID));
    }
}

StructureSolver类(求解类)

public class StructureSolver {
    private Truss structure;
    // ...其他属性和构造方法
    public StructureSolver(Truss truss){
        structure = truss;
    }

    public void setStructure(Truss structure) {
        this.structure = structure;
    }

    private void createStructureStiffnessMatrix(){
        K = new StiffnessMatrix(structure.getJoints().size()*2);
        assignIds();

        for (TrussMember member: structure.getMembers()) {
            int Nx = member.getNx();
            int Ny = member.getNy();

            int Fx = member.getFx();
            int Fy = member.getFy();

            double lambdaX = calculateLambdaX(member);
            double lambdaY = calculateLambdaY(member);

            double lambdaXSq = lambdaX*lambdaX/ member.getLength();
            double lambdaYSq = lambdaY*lambdaY/ member.getLength();
            double lambdaXY = lambdaX*lambdaY/ member.getLength();
            // ...后续代码
        }
    }
}

TrussMember类(构件类)

public class TrussMember {
    private StructureNode startJoint, endJoint;
    // ...其他属性和构造方法
    public TrussMember() {
    }

    public TrussMember(StructureNode startJoint, StructureNode endJoint) {
        this.startJoint = startJoint;
        this.endJoint = endJoint;
    }

    public double getLength() {
        double calculatedLength = 0;
        Point2D p1 = new Point2D(startJoint.getCoordinates().getX_COO(),
                startJoint.getCoordinates().getY_COO());
        Point2D p2 = new Point2D(endJoint.getCoordinates().getX_COO(),
                endJoint.getCoordinates().getY_COO());
        calculatedLength = p1.distance(p2);
        return calculatedLength;
    }

    public StructureNode getStartJoint() {
        return startJoint;
    }

    public void setStartJoint(StructureNode startJoint) {
        this.startJoint = startJoint;
    }

    public StructureNode getEndJoint() {
        return endJoint;
    }

    public int getNx(){return getStartJoint().getX_index();}
    public int getNy(){return getStartJoint().getY_index();}

    public int getFx(){return getEndJoint().getX_index();}
    public int getFy(){return getEndJoint().getY_index();}
}

控制器类的onAction方法

StructureSolver solver = new StructureSolver();
solver.setStructure(truss);
solver.solve();
问题排查与解决方案

1. 确认对象引用一致性

检查UI中更新x_index/y_index的StructureNode实例和TrussMember中持有的StructureNode实例是否为同一个对象:

  • 如果UI更新时创建了新的StructureNode对象,而TrussMember仍持有旧实例,就会读取到旧实例的初始值。
  • 可通过打印对象哈希码验证:在UI更新节点时打印node.hashCode(),在TrussMember.getNx()中打印getStartJoint().hashCode(),对比两者是否一致。

2. 检查assignIds方法的实现

StructureSolver.createStructureStiffnessMatrix中调用了assignIds(),这个方法应该负责给每个StructureNode设置x_index和y_index:

  • 确认该方法是否正确遍历structure.getJoints()集合,并且调用了setX_index/setY_index赋值。
  • 如果方法逻辑错误(比如遍历了错误的集合、索引计算错误),会导致索引未被正确更新。

3. 解决线程可见性问题

如果在非JavaFX应用线程中更新索引,可能存在内存可见性问题:

  • 给x_index/y_index添加volatile关键字,保证多线程下的变量可见性:
private volatile int x_index=0 , y_index=0;
  • 确保所有更新StructureNode索引的操作都在JavaFX应用线程中执行(可通过Platform.runLater()包裹更新逻辑)。

4. 前置验证步骤

在调用solver.solve()前,打印truss.getJoints()中每个节点的x_index/y_index,确认索引是否已经被正确设置;如果此时值正确,再排查StructureSolver中读取逻辑是否存在问题。

内容的提问来源于stack exchange,提问作者Mohammed Yasser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 21:37:09