【问题标题】:JTree nodes not updated (in Scala)JTree 节点未更新(在 Scala 中)
【发布时间】:2011-10-30 23:27:49
【问题描述】:

ScalaSwing JTree 组件 (Java) 之间的互操作性存在问题。

JTree 没有正确更新,除非我停止显示 JOptionPane 以提示用户输入新实体的名称。此行标有 [* * *]。如您所见,我提供了静态文本“xxx”,注释掉了对 JOptionPane 方法的调用。在这种情况下,JTree 按预期正确更新。

我认为这可能与 Swing 线程模型有关,但将更新文本包装在 Runnable 类中并不能解决问题。另见Why isn't my JTree updating when the TreeModel adds new nodes?

为什么 JOptionPane 会阻止 JTree 正确更新节点?

我这样做是因为 Scala 还没有允许动态更新的 Swing Tree 实现。见http://github.com/kenbot/ScalaSwingTreeWrapper

任何提示或指示将不胜感激。

干杯,

奈杰尔

    import scala.swing._
    import javax.swing.{JOptionPane,JTree,SwingUtilities}
    import javax.swing.tree.{DefaultTreeModel,DefaultMutableTreeNode,TreePath}

    object XApp extends SimpleSwingApplication {

        val APP_NAME: String = "AppName"

        def getNameDialog(q: String): String = 
        { 
            JOptionPane.showInputDialog(top.self, q, APP_NAME, JOptionPane.PLAIN_MESSAGE);
        }

        def menuProjectNewX = {
            // Get the name of the X
            var name = "xxx"; // getNameDialog ("Enter the name of the X:")  [***]

            def doUpdate = new Runnable() {
                def run() 
                {
                    pl ("Running");

                    // Get the root
                    var root = treeModel.getRoot().asInstanceOf[DefaultMutableTreeNode]

                    // Insert new object
                    var newNode = new DefaultMutableTreeNode(name)
                    treeModel.insertNodeInto(newNode, root, root.getChildCount())

                    // Expand the tree
                    var tp = new TreePath(newNode.getPath().asInstanceOf[Array[Object]])
                    tree.scrollPathToVisible(tp)
                }
            }

            SwingUtilities.invokeLater(doUpdate);
        }

        var tree: JTree = null
        var treeModel: DefaultTreeModel = null
        var flow: FlowPanel = null

        def top = new MainFrame {

            // Create the menu bar
            menuBar = new MenuBar() {
                contents += new Menu("Project") {
                    contents += new MenuItem(Action("New X...")     { menuProjectNewX })
                }
            }

            title = APP_NAME
            preferredSize = new Dimension (1000, 800)
            location = new Point(50,50)


            treeModel = new DefaultTreeModel(new DefaultMutableTreeNode("(root)"))
            tree = new JTree(treeModel)
            //flow = new FlowPanel

            var splitPane = new SplitPane (Orientation.Vertical, new Component {
                    override lazy val peer = tree
                }, new FlowPanel)   

            splitPane.dividerLocation = 250
            contents = splitPane

        }    

    }

【问题讨论】:

    标签: java swing scala jtree


    【解决方案1】:

    问题在于,每次显示 JOptionPane 时,您都在创建一个新框架,而不是重用 MainFrame。请记住top 是一种方法,当您引用“顶部”来显示JOptionPane 时,您正在创建一个new MainFrame。因此,最后,您要将节点添加到与正在显示的 MainFrame 不同的树中。

    解决这个问题的一种方法是将 MainFrame 简单地存储在一个变量中:

    var mainFrame: MainFrame = null
    
    def top = 
      {
        mainFrame = new MainFrame {
          // Rest of the code
        }
    
        mainFrame
      }
    }
    
    // To show the JOptionPane
    JOptionPane.showInputDialog(mainFrame.self, q, APP_NAME, JOptionPane.PLAIN_MESSAGE);
    

    【讨论】:

    • 非常感谢...我没有意识到我每次都调用定义的方法,而不是使用存储的变量。 :-/ 干杯!
    猜你喜欢
    • 1970-01-01
    • 2012-08-28
    • 1970-01-01
    • 2014-07-31
    • 2011-11-15
    • 1970-01-01
    • 2011-07-04
    • 2011-06-03
    • 2010-12-05
    相关资源
    最近更新 更多