有关执行操作和使用具有多个视图的单个模型的不确定性 [英] Uncertainties regarding Implementation of Actions and Usage of a single Model with multiple Views

查看:74
本文介绍了有关执行操作和使用具有多个视图的单个模型的不确定性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于GUI编程,我真是个新手,也许我的问题有 一个非常简单的解决方案. 我正在尝试实现一个Java Swing GUI,它可以用作 树状数据结构的编辑器. GUI分为三个 零件:

I'm a total newbee regarding GUI programming and maybe my problem has a quite simple solution. I'm trying to implement a Java Swing GUI that serves as an editor for a tree like data structure. The GUI is divided into three parts:

  1. 窗口左四分之一中的树查看器显示 树状结构数据.

  1. A tree viewer in the left quarter of the window displays the tree structured data.

右上方的大区域显示包含文本字段的编辑器, 桌子之类的.树中每种不同的对象 结构具有自己的编辑器,当在 树查看器.

The large upper right area displays editors containing text fields, tables and the like. Each different kind of object in the tree structure has its own editor which is shown when it is selected in the tree viewer.

右下方区域显示控制台查看器.用于显示 有关特定操作的消息.

The lower right area shows a console viewer. It is used to display messages about specific actions.

我正在努力服从模型与模型的严格分离 我程序中的树查看器/编辑器中的可视化.所以我 创建了DefaultTreeModel(MyTreeModel)子类的实例 存储对业务数据的引用和一个实例 JTree的子类,提供树的视觉表示 结构.

I'm trying hard to obey a strict separation of the model from its visualization in the tree viewers/editors in my program. Therefore I created an instance of a sub-class of DefaultTreeModel (MyTreeModel) which stores references to the business data and an instance of a sub-class of JTree that provides the visual representation of the tree structure.

我正在尝试实现使用以下功能修改数据的功能: 动作课.任何动作(例如CreateNode,RenameNode,DeleteNode) 在其自己的操作类(AbstractAction的子类)中实现. 这些操作用于树查看器的上下文菜单和 应用程序的编辑"菜单.但我也想在其中重用其中的一些 GUI的编辑器部分,例如RenameNode操作.我在这里 当前卡住了.

I'm attempting to implement functionality that modifies the data using Action classes. Any action (like CreateNode, RenameNode, DeleteNode) is implemented in it's own action class (sub-class of AbstractAction). The actions are used in the tree viewer's context menu and in the applications "Edit" menu. But I also want to reuse some of them in the editor parts of the GUI, e.g. the RenameNode action. And here I'm currently stuck.

树查看器会显示一个图标以及其中每个节点的名称 那个树.相应的编辑器除其他外还包含 东西,还有一个显示关联节点名称的JTextField.

The tree viewer displays an icon along with the name for every node in the tree. And the respective editor contains, among other stuff, also a JTextField that shows the associated node's name.

我知道我可以将动作对象附加到JMenu,JPopupMenu和 甚至使用setAction方法对JTextField对象也是如此.一世 这样做,现在我在程序的编辑"中有一个重命名"菜单项 菜单,在与表示以下项的JTree关联的弹出菜单中 树查看器和显示节点名称的JTextField也具有此功能 动作附在上面.

I know that I can attach action objects to JMenu, JPopupMenu and even to JTextField objects using the setAction method. I did so and now I have a "Rename" menue entry in the program's "Edit" menue, in the popup menue associated with the JTree that represents the tree viewer and the JTextField showing the node name also has this action attached to it.

要更改树节点的名称"属性,我创建了该类 RenameNode作为AbstractAction的子类.如前所述 名称将显示在树查看器中的每个节点上,并且操作 只需使该文本可编辑即可.这样做的代码如下所示 (在RenameNode类中):

To change the "Name" attribute of a tree node, I created the class RenameNode as a sub-class of AbstractAction. As already mentioned the name is displayed at each node in the tree viewer and the action simply makes this text editable. The code doing this looks as follows (in the class RenameNode):

public void actionPerformed(ActionEvent ev) {
    // "mouseOverPath" is the Treepath were the mouse was placed on
    // when the popup menu was opened
    if (tree.existsMouseOverPath()) {
        tree.startEditingAtPath(tree.mouseOverPath);
    } else if (tree.getSelectionCount() != 0) {
        tree.startEditingAtPath(tree.getSelectionPath());
    }
}

需要以下if语句才能使操作正常进行:

These if statements are needed to make the action work properly from:

-弹出菜单(第一个if语句;这里是下一个对象 弹出菜单打开时的鼠标可编辑)

-- the popup menu (first if statement; here the object which was under the mouse when the popup menu is opened is made editable)

-应用程序的菜单(第二个if语句;这里是树节点 当前选择的代码(如果有的话)变为可编辑状态.

-- the application's menu (second if statement; here the tree node that is currently selected -- if any -- is made editable).

嗯,从原理上讲,这很好,但实际上重命名了 节点不是通过RenameAction类的代码完成的 actionPerformed(ActionEvent ev)方法.节点的真正变化 名称在方法的树的MyTreeModel类中执行 valueForPathChanged()如下重写:

Well, this works fine, in principle but in fact the renaming of the node is not done through the code in the RenameAction class's actionPerformed(ActionEvent ev) method. The real change of the node's name is executed in the tree's MyTreeModel class in the method valueForPathChanged() which is overridden as follows:

public class MyTreeModel extends DefaultTreeModel {


[...]

    @Override
    public void valueForPathChanged(TreePath path, Object newValue) {
    final MyTreeNode aNode = (MyTreeNode)path.getLastPathComponent();
    if (newValue instanceof String) {
        ((MyNode) aNode.getUserObject()).setName((String) newValue);
    } else {
        aNode.setUserObject(newValue);
    }
        nodeChanged(aNode);
    }

[...]

}

我完全不知道如何正确地定义行动的概念 在这里应用. 更糟的是重命名操作的情况 执行了更改JTextField对象中的文本的操作.此刻我 不知道如何以一种干净的方式实现它. JTextField应该 与树模型结构中的单个节点关联 模型和附加的操作应修改该模型,以及何时修改 模型已更改,树查看器将需要通知以进行更新 树查看器中各个节点的名称.

I have absolutely no clue how the concept of actions could properly be applied here. Even worse is the situation with the rename operation when it is performed changing the text in the JTextField object. At the moment I don't know how to implement that in a clean way. The JTextField should get associated with a single node from the tree model structure as its model and the attached action should modify that model and when this model is changed the tree viewer would need to get notified to update the respective node's name in the tree viewer.

我假设MyNode类(它是AlNode的子类 DefaultMutableTreeNode)必须实现接口Document 并且RenameAction类必须先对其进行修改,然后再进行一个事件 将必须发出以通知显示 节点已更改.

I assume that the MyNode class (which is alrady a sub-class of DefaultMutableTreeNode) would have to implement the interface Document and the RenameAction class would have to modify it and then an event would have to be issued to notify the tree viewer that displays the changed node.

底线:我必须承认我还没有完全理解 正确实施要在多个地方使用的动作 在GUI中,但我不完全了解如何实现模型 可以被多个GUI对象使用(在我的情况下是JTree和 JTextField).可能所有这些都非常简单...

Bottom line: I must admit that I did not yet completely understand how to properly implement an action that is to be used in multiple places in a GUI and I don't completely understand how to implement a model that can be used by multiple GUI objects (in my case a JTree and a JTextField). Possibly all that is quite simple ...

在此先感谢您的帮助!

给出的答案对于解释动作如何非常有帮助 可以与JTrees一起使用.但是,我还有一点要讨论. 在我的GUI中,我有一个合并的业务数据的树形表示 带有用于数据的编辑器(树位于窗口的左四分之一处,并且在其旁边是特定于节点类型的编辑器).所有节点的名称都可以更改.并且,编辑器包含一个文本字段(使用JTextField实现),在其中显示节点名称,也可以对其进行编辑.我的不确定性如下: JTextField允许分配一个动作对象以及一个 模仿它.实际上,模型将是已经在JTree中查看的节点对象.我认为应该有一种方法可以将JTree中使用的相同模型对象用作编辑器中JTextField的模型,并在那里重新使用Action类.关于模型的重用,我认为我的模型类MyTreeNode也必须实现Document接口,对吗?当启动特定于节点的编辑器时,我必须使用其setDocument()方法将当前在JTree中选择的节点与JTextField对象相关联. 最后,我的RenameNodeAction必须执行更改 JTextField的节点名称. 因此,我的中心思想是:使一个模型在多个视图中显示,并且在要重命名节点的任何地方仅重用一个RenameAction.这有意义吗?我的想法是如何做到这一点可行吗?

Well the answers given were quite helpful in explaining how actions can be used together with JTrees. But there is one more point I'd like to discuss. In my GUI I have a tree representation of my business data combined with editors for the data (the tree located in the left quarter of the window and aside of it a node type specific editor). All the nodes have names that can be changed. And, the editors contain a text field (implemented with a JTextField) in which the node's name is displayed and which can be edited too. My uncertainty here is as follows: A JTextField allows to assign an action object as well as a model to it. Actually the model would be a node object already viewed in the JTree. I think there should be a way to use the same model object used in the JTree also as a model for the JTextField in the editor and also reuse the Action class there. Regarding the reuse of the model I think my model class MyTreeNode will have to implement the Document interface too, correct? And when bringing up the node specific editor I'd have to associate the node currently selected in the JTree with the JTextField object using its setDocument() method. Finally my RenameNodeAction would have to perform the change of the JTextField's node's name. So my central point is: making one model being displayd in multiple views and the reuse of just one RenameAction everywhere where a node is to be renamed. Does this make sense and is my idea how this must be accomplished feasible?

推荐答案

超出Stackoverflow范围的应用程序设计的完整指南.而是从 如何使用树木 .注意如何将TreeSelectionListener添加到tree以更新附近的JEditorPane.现在,将另一个TreeSelectionListener添加到另一个视图中,以查看如何更新新视图.您可能还会从与此相关的 answer 中获得一些见识.

A complete guide to application design in beyond the scope of Stackoverflow. Instead, start with the example TreeIconDemo shown in How to Use Trees. Notice how it adds a TreeSelectionListener to the tree in order to update a nearby JEditorPane. Now, add another TreeSelectionListener to a different view to see how you could update the new view, too. You might also get some insight from this related answer.

附录:从此示例开始,您可以执行以下操作.更改选择会更新textField以显示所选节点的名称.编辑节点(通常是 F2 )或textField都会更改所选节点的名称.

Addendum: Starting from this example, you can do something like the following. Changing the selection updates the textField to show the selected node's name. Editing either the node (typically F2) or the textField changes the selected node's name.

private JTextField textField = new JTextField(10);
...
final DefaultTreeModel treeModel = new DefaultTreeModel(root);
tree = new JTree(treeModel);
tree.addTreeSelectionListener(new TreeSelectionListener() {

    @Override
    public void valueChanged(TreeSelectionEvent e) {
        TreePath path = e.getNewLeadSelectionPath();
        if (path != null) {
            DefaultMutableTreeNode node =
                (DefaultMutableTreeNode) path.getLastPathComponent();
            if (node.isLeaf()) {
                Resource user = (Resource) node.getUserObject();
                textField.setText(user.toString());
            } else {
                textField.setText("");
            }
        }
    }
});
textField.addActionListener(new AbstractAction("edit") {

    @Override
    public void actionPerformed(ActionEvent e) {
        TreePath path = tree.getSelectionPath();
        if (path != null) {
            DefaultMutableTreeNode node =
                (DefaultMutableTreeNode) path.getLastPathComponent();
            if (node.isLeaf()) {
                String s = textField.getText();
                Resource user = (Resource) node.getUserObject();
                user.setName(s);
                treeModel.reload(node);
            }
        }
    }
});

这篇关于有关执行操作和使用具有多个视图的单个模型的不确定性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆