树(三)

17.6 TreeModel接口

TreeModel接口描述了基本的JTree数据模型结构。他描述了父子聚合关系,允许任何的对象成为父节点或是子节点。树有一个根节点,而所有其他的节点都是这个节点的后代。除了返回关于不同节点的信息以外,模型要求实现类管理TreeModelListener对象列表,从而当模型中的节点发生变化时可以得到通知。其他的方法,valueForPathChanged(),用来提供修改特定位置节点内容的方法。

public interface TreeModel {
  // Properties
  public Object getRoot();
  // Listeners
  public void addTreeModelListener(TreeModelListener l);
  public void removeTreeModelListener(TreeModelListener l);
  // Instance methods
  public Object getChild(Object parent, int index);
  public int getChildCount(Object parent);
  public int getIndexOfChild(Object parent, Object child);
  public boolean isLeaf(Object node);
  public void valueForPathChanged(TreePath path, Object newValue);
}

17.6.1 DefaultTreeModel类

JTree自动创建一个DefaultTreeModel实例来存储其数据模型。DefaultTreeModel类提供了一个在每个节点上使用TreeNode实现的TreeModel接口的实现。

除了实现TreeModel接口的方法并且管理TreeModelListener对象的列表以外,DefaultTreeModel类还添加了一些有用的方法:

  • public void insertNodeInto(MutableTreeNode child, MutableParentNode parent, index int):将子节点添加到父节点的子节点集合中的索引位置。
  • public void removeNodeFromParent(MutableTreeNode node):使得节点由树中移除。
  • public void nodeChanged(TreeNode node):通知模型节点已经发生变化。
  • public void nodesChanged(TreeNode node, int childIndices[]):通知模型节点的子节点已经发生变化。
  • public void nodeStructureChanged(TreeNode node):如果节点及子节点已经发生变化则通知模型。
  • public void nodesWereInserted(TreeNode node, int childIndices[]):通知模型节点作为树节点的子节点被插入。
  • public void nodesWereRemoved(TreeNode node, int childIndices[], Object removedChildren[]):通知模型子节点已经被由树中移除并且在方法调用中包含节点作为参数。
  • public void reload()/public void reload(TreeNode node):通知模型节点已经发生了复杂的修改并且由根节点以下或是特定节点以下的模型应重新载入。

第一对方法用于直接由树中添加或是移除节点。其他的方法用于当树节点被修改时通知树模型。如果我们不使用前两个方法的一个由树模型中插入或是移除节点,则我们要负责调用第二个集合中的方法。

17.6.2 TreeModelListener接口与TreeModelEvent类

TreeModel使用TreeModelListener来报告模型的变化。当TreeModel发送一个TreeModelEvent,所注册的监听器就会得到通知。接口包括当节点被插入,移除或是修改时的通知方法,以及当这些操作中的一个或是全部依次完成时的捕获方法。

public interface TreeModelListener implements EventListener {
  public void treeNodesChanged(TreeModelEvent treeModelEvent);
  public void treeNodesInserted(TreeModelEvent treeModelEvent);
  public void treeNodesRemoved(TreeModelEvent treeModelEvent);
  public void treeStructureChanged(TreeModelEvent treeModelEvent);
}

17.7 TreeSelectionModel接口

除了所有的树支持用于排序节点的数据模型,用于显示节点的渲染器,以及用于编辑的编辑器以外,还有一个名为TreeSelectionModel的用于树元素选取操作的数据模型。TreeSelectionModel接口包含用来描述到选定节点的选定路径集合的方法。每一个路径存储在TreePath中,其中包含由根对象到选定节点的树节点的路径。我们会在稍后探讨TreePath类。

public interface TreeSelectionModel {
  // Constants
  public final static int CONTIGUOUS_TREE_SELECTION;
  public final static int DISCONTIGUOUS_TREE_SELECTION;
  public final static int SINGLE_TREE_SELECTION;
  // Properties
  public TreePath getLeadSelectionPath();
  public int getLeadSelectionRow();
  public int getMaxSelectionRow();
  public int getMinSelectionRow();
  public RowMapper getRowMapper();
  public void setRowMapper(RowMapper newMapper);
  public int getSelectionCount();
  public boolean isSelectionEmpty();
  public int getSelectionMode();
  public void setSelectionMode(int mode);
  public TreePath getSelectionPath();
  public void setSelectionPath(TreePath path);
  public TreePath[] getSelectionPaths();
  public void setSelectionPaths(TreePath paths[]);
  public int[] getSelectionRows();
  // Listeners
  public void addPropertyChangeListener(PropertyChangeListener listener);
  public void removePropertyChangeListener(PropertyChangeListener listener);
  public void addTreeSelectionListener(TreeSelectionListener listener);
  public void removeTreeSelectionListener(TreeSelectionListener listener);
  // Other methods
  public void addSelectionPath(TreePath path);
  public void addSelectionPaths(TreePath paths[]);
  public void clearSelection();
  public boolean isPathSelected(TreePath path);
  public boolean isRowSelected(int row);
  public void removeSelectionPath(TreePath path);
  public void removeSelectionPaths(TreePath paths[]);
  public void resetRowSelection();
}

TreeSelectiomModel接口支持三种选择模式,每一种模型由一个类常量指定:CONTIGUOUS_TREE_SELECTION, DISCONTIGUOUS_TREE_SELECTION或是SINGLE_TREE_SELECTION。当选择模式是CONTIGUOUS_TREE_SELECTION时,只有彼此相连的节点才会被同时选中。DISCONTIGUOUS_TREE_SELECTION模式意味着并没有同时选中的限制。而另一种选择模式,SIGNLE_TREE_SELECTION,每次只能选中一个节点。如果我们不希望任何内容被选中,可以使用null设置。这会使用受保护的JTree.EmptySelectionModel类。

注意,用于选择多个节点的按键是特定于观感类型的。尝试使用Ctrl或中Shift键组合来选择多个节点。

除了修改选择模式以外,其他的方法允许我们监视选择牟属性。有些这些方法会使用行数,而有时这些方法会使用TreePath对象。选择模型使用RowMapper来为我们将行映射到路径。抽象的AbstractLayoutCache类提供了一个RowMapper接口的基本实现,并且由FixedHeightLayoutCache与VariableHeightLayoutCache类进行特例化。我们并不需要访问或是修改RowMapper或是其实现。要将行映射到路径(或是将路径映射到行),我们仅需要请求树即可。

17.7.1 DefaultTreeSelectionModel类

DefaultTreeSelectionModel类提供了TreeSelectionModel接口的实现,这个实现初始时使用DISCONTIGUOUS_TREE_SELECTION模式并且支持所有三种选择模式。这个类引入了一些自己的方法用来获取监听器列表;其他的方法仅是实现了所有的TreeSelectionModel接口方法,包括访问表17-6中所列的11个属性的方法。另外,DefaultTreeSelectionModel重写了Object的clone()方法,从而可以Cloneable。


使用TreeSelectionModel的主要原因在于修改模型的选择模式。例如,下面的两行代码将模式修改为单选模式:

TreeSelectionModel selectionModel = tree.getSelectionModel();
selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

如果我们对找出选定路径感兴趣,我们可以直接请求JTree。我们并不需要由模型获取选定路径。

17.7.2 TreeSelectionListener接口与TreeSelectionEvent类

当树中的选定节点集合变化时,就会生成一个TreeSelectionEvent并且TreeSelectionModel所注册的TreeSelectionListener对象会得到通知。TreeSelectionListener可以注册到JTree或是直接注册到TreeSelectionModel。该接口定义如下:

public interface TreeSelectionListener implements EventListener {
  public void valueChanged(TreeSelectionEvent treeSelectionEvent);
}

17.7.3 TreePath类

我们要探讨的最后一个类就是TreePath。在本章前面的例子中我们已经多次使用这个类。他描述了一个由根节点到另一个节点映射路径的只读节点集合,这里的根可以是一个子树的根也可以是整棵树的根。尽管有两个构造函数可以用来创建TreePath对象,我们通常仅其作为方法的返回值进行处理。我们也可以通过使用public TreePath pathByAddingChild(Object child)方法向已存在的TreePath添加元素来创建新的路径。

TreePath可以作为是一个Object数组,其中数组的第一个元素是树的根,而最后一个元素被最后的路径组件。在这两者之间是连接他们的组件。通常情况下,数组的元素是TreeNode类型。然而,因为TreeModel支持任意类型的对象,TreePath的path属性被定义为Object节点数组。表17-7列出了四个TreePath属性。


为了更好的理解TreePath,我们重用图17-18所示的树遍历示例,如图17-20所示。


17.8 Additional Expansion Events

还有两个可以注册到JTree监听器需要探讨:一个TreeExpansionListner与一个TreeWillExapndListener。

17.8.1 TreeExpansionaListener接口与TreeExpansionEvent类

如果我们对确定一个树节点何时展开与折叠,我们可以向树注册一个TreeExpansionListner。在父节点被展开或是折叠之后所注册的监听器就会得到通知。

public interface TreeExpansionListener implements EventListener {
  public void treeCollapse(TreeExpansionEvent treeExpansionEvent);
  public void treeExpand(TreeExpansionEvent treeExpansionEvent);
}

每一个方法都有一个TreeExpansionEvent作为其参数。TreeExapnsionEvent类只有一个用于获取到展开或是折叠节点路径的方法:public TreePath getPath()。

17.8.2 TreeWillExpandListener接口与ExpandVetoException类

JTree支持TreeWillExpandListener的注册,其定义如下:

public interface TreeWillExpandListener implements EventListener {
  public void treeWillCollapse(TreeExpansionEvent treeExpansionEvent)
    throws ExpandVetoException;
  public void treeWillExpand(TreeExpansionEvent treeExpansionEvent)
    throws ExpandVetoException;
}

这两个方法签名类似于TreeExpansionListener,并且他们都抛出ExpandVetoException。在父节点展开或是折叠之前所注册的监听器会得到通知。如果监听器不希望展开或是折叠发生,监听器可以抛出异常拒绝请求,阻止节点打开或是关闭。

为了演示TreeWillExpandListneer,下面的代码不会允许sports节点在默认的数据模型中展开或是colors节点折叠。

TreeWillExpandListener treeWillExpandListener = new TreeWillExpandListener() {
  public void treeWillCollapse(TreeExpansionEvent treeExpansionEvent)
      throws ExpandVetoException {
    TreePath path = treeExpansionEvent.getPath();
    DefaultMutableTreeNode node =
      (DefaultMutableTreeNode)path.getLastPathComponent();
    String data = node.getUserObject().toString();
    if (data.equals("colors")) {
      throw new ExpandVetoException(treeExpansionEvent);
    }
  }
  public void treeWillExpand(TreeExpansionEvent treeExpansionEvent)
      throws ExpandVetoException {
    TreePath path = treeExpansionEvent.getPath();
    DefaultMutableTreeNode node =
      (DefaultMutableTreeNode)path.getLastPathComponent();
    String data = node.getUserObject().toString();
    if (data.equals("sports")) {
      throw new ExpandVetoException(treeExpansionEvent);
    }
  }
};

不要忘记使用类似下面的代码将监听器注册到树中:

tree.addTreeWillExpandListener(treeWillExpandListener)

17.9 小结

在本章中,我们了解了与JTree组件使用相关的多个类。我们了解了使用TreeCellRenderer接口与DefaultTreeCellRenderer实现的树节点渲染。我们深入了使用TreeCellEditor接口,DefaultCellEditor与DefaultTreeCellEditor实现的树节点编辑。

在审视了如何显示与编辑树之后,我们了解了用于手动创建树对象的TreeNode接口,MutableTreeNode接口,与DefaultMutableTreeNode类。我们探讨了用于存储树数据模型的的TreeModel接口与DefaultTreeModel实现,以及用于存储树选择模型的TreeSelectionModel接口与DefaultTreeSelectionModel实现。

另外,我们了解了用于各种树类的事件相关类以及用于描述节点连接路径的TreePath。

在第18章,我们将会探讨javax.swing.table包及其用于JTable组件的多个类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 维点云数据txt文件是一种文本文件格式,用于存储木模型的点云数据。它包含了每个点的坐标和颜色信息,可以通过读取该文件来可视化木模型并进行分析。 该文件格式通常包含一系列行,每行代表一个点的数据,用逗号分隔各维度坐标和颜色信息。通常,一行点云数据的格式是:x坐标,y坐标,z坐标,R,G,B。其中x、y、z坐标为该点在3D空间中的位置,R、G、B代表该点的颜色信息。 在使用该文件进行木模型的处理时,常将其导入到维建模软件中进行处理和可视化。此外,该文件还常用于计算木的体积、分析的生长情况等研究工作。 需要注意的是,由于点云数据量大,该文件格式大小会比较庞大,因此在文件的存储和传输过程中,需要考虑到数据压缩和优化等问题,以减少资源消耗和提高处理效率。 ### 回答2: 维点云数据txt文件是指木的维点云数据以txt文件的方式保存。点云数据通常由大量的维坐标点组成,可以用于描述真实世界中的各种物体。在木研究领域中,点云数据可以用来描述木的形态特征,并提供基础数据用于木模型的构建。通常可以通过 3D 扫描仪或无人机等技术获取木的点云数据,再将其保存为txt格式文件。在实际应用中,维点云数据txt文件可用于木成长情况的分析、数字森林建设、林业生态环境监测等领域。由于点云数据较为庞大,处理复杂,需要专业的点云数据处理软件来进行处理和分析。目前常用的维点云数据软件有CloudCompare、Meshlab等。在未来,随着技术的进步以及应用需求的不断增加,维点云数据txt文件的应用前景将会更加广泛。 ### 回答3: 维点云数据txt文件,是指用文本格式记录的维模型的点云数据。 是一种常见的自然植物,它的分支、干和叶子等组成了复杂的维结构。为了方便对的形态进行数字化建模和分析,可以使用点云数据来描述的形态。点云数据是一组由离散点组成的几何数据,可以精确地描述物体表面的形态。 在维点云数据txt文件中,每个点都记录了其在维空间中的坐标以及可能的其他属性,如颜色、法线等。这些点可以通过维重构算法来构建维模型。同时,点云数据可以通过数据处理和分析来获取的参数,如冠体积、叶子面积等。 维点云数据txt文件的制作过程通常包括野外数据采集、点云数据预处理、点云数据格式转换等步骤。野外数据采集可以使用激光测距仪、数字相机等设备,将的形态信息记录下来。点云数据预处理可以包括点云滤波、采样、配准等步骤,以提高点云数据的质量和准确性。最后,可以将处理后的点云数据转换成txt格式保存,以便后续的数据处理和分析。 总之,维点云数据txt文件是对的形态信息进行数字化记录和分析的重要手段,对于生态学、林业学等领域的研究具有重要意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值