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
相关产品推荐
相关产品推荐

