问题描述:建立了一棵JTree树,在这棵树上我会添加自定义模型的节点,而且此节点必设为leaf。现在出现这个怪现象,当我选中节点模型,右键弹出操作菜单,进行修改--〉保存操作;然后再选中此节点,右键弹出操作菜单,进行删除,就报了数组越界错误。而如果我在进行修改操作后,把这棵树折叠再打开,再删除,就不会有这个问题。经调试发现,删除此节点对象本身的方法没有出错,出错在selectedNode.removeFromParent();这句话;
selectedNode=(DefaultIconTreeNode) tree.getLastSelectedPathComponent();经调试能够正确得到对象,没有问题。
百思不得其解。不知道有哪位高手可以相助?跟我使用了右键菜单有没有关系?
另附上出错信息
Hit uncaught exception java.lang.ArrayIndexOutOfBoundsException
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1 at java.util.Vector.elementAt(Vector.java:435) at javax.swing.tree.DefaultMutableTreeNode.getChildAt(DefaultMutableTreeNode.java:230) at javax.swing.tree.DefaultMutableTreeNode.remove(DefaultMutableTreeNode.java:191) at javax.swing.tree.DefaultMutableTreeNode.remove(DefaultMutableTreeNode.java:368) at com.bluestar.tmr.app.view.energybalance.EnergyBalanceQueryJFrame$deleteAction.actionPerformed(EnergyBalanceQueryJFrame.java:397) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1849) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2169) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258) at javax.swing.AbstractButton.doClick(AbstractButton.java:302) at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1051) at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1092) at java.awt.Component.processMouseEvent(Component.java:5517) at javax.swing.JComponent.processMouseEvent(JComponent.java:3135) at java.awt.Component.processEvent(Component.java:5282) at java.awt.Container.processEvent(Container.java:1966) at java.awt.Component.dispatchEventImpl(Component.java:3984) at java.awt.Container.dispatchEventImpl(Container.java:2024) at java.awt.Component.dispatchEvent(Component.java:3819) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4212) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3892) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3822) at java.awt.Container.dispatchEventImpl(Container.java:2010) at java.awt.Window.dispatchEventImpl(Window.java:1791) at java.awt.Component.dispatchEvent(Component.java:3819) at java.awt.EventQueue.dispatchEvent(EventQueue.java:463) at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:242) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149) at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

解决方案 »

  1.   

    估计是进行修改操作后,树上的节点丢失了,因为从错误信息来看,index=-1,这说明数组中没有元素。
    把这棵树折叠再打开,再删除,就不会有这个问题,估计是折叠时树对节点进行了重新加载。你可以重点观察一下修改操作为什么影响到了树
      

  2.   

    我想应该是删除后树的展现(view)跟模型(model)没有同步,我看了下你的删除方法selectedNode.removeFromParent();这是不够的,还需要通知模型这个节点被删除了,好象是这样tree.getModel().nodesWereDeleted();或者更简单的方式是直接通过模型来删除你这个节点:tree.getModel().removeFromParent();具体方法跟参数列表你看下api,我记不很清楚了....
      

  3.   

    回楼上的,我觉得错误的根本原因应该是二楼提到的修改那块,而只不过是表现在了删除这里,应该跟删除这里没有直接联系,因为我对节点进行操作后都会用           ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(seletedNode);来通知树的;折叠树后再修改就不出问题,说明重新加载后,删除动作能够得到正确的对象。
    而我调试的时候有个很明显的现象就是“修改”的时候这个通知好像没有起作用,节点的连线都变得模糊不清。目前还未调试出结果来;但是我想二楼说的是对的,要是能够再多给些提示就好了。
      

  4.   

    DefaultIconTreeNode selectedNode = (DefaultIconTreeNode) tree.getLastSelectedPathComponent();
     balanceModel = (EnergyBalanceModel)selectedNode.getUserObject();
               DefaultIconTreeNode tempNode = (DefaultIconTreeNode) selectedNode.getParent();           //...初始化修改面板                  StandardDialog dialog = new StandardDialog(JOptionPane.
                            getFrameForComponent(parent), UIRes.modifyButton, energyBalancePanel);//弹出修改对话框
               dialog.addValidData(energyBalancePanel);
               dialog.setVisible(true);
               if (!dialog.hasUserCancelled()) {//如果按下确定,表示确定修改结果               balanceModel = energyBalancePanel.getModel();//得到修改后的model
                   if(balanceDelegate.modifyEnergyBalance(balanceModel))//如果修改成功,则将选取节点的UserObject设置为当前的model
                       selectedNode.setUserObject((EnergyBalanceModel)balanceModel);
               }
      System.out.println(tree);
                ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(selectedNode);//通知树该节点改变了
    System.out.println(tree);黔驴技穷了,还是调试不出个所以然来,把代码发上来,两句打印语句的差别在于后者打印出来的一长串字符中多了一个“invalid”。我不知道为何通知无效?请达人帮忙。
      
      

  5.   

    nodeStructureChanged是通知节点的结构更改,不知道处理数据不...关键是这里吧...怎么不试我给的方法?
      

  6.   

    回楼上的,在运行到你给的那步程序之前已经出错了,在selectedNode.removeFromParent();这步。
    而这种现象仅出现在对节点修改后立刻删除。所以问题应该在于修改而不在于删除。但是我还是没有调试出问题所在,因为修改根本就不报错。
      

  7.   

    鼠标响应的是不是valuechanged事件???第二次删除时可能没有执行~