Узлы JTree не обновляются (в Scala) - PullRequest
1 голос
/ 31 октября 2011

У меня проблема с совместимостью между Scala и Swing JTree (Java).

JTree не обновляется правильно, за исключением случаев, когда я останавливаюсьотображение панели JOptionPane, запрашивающей у пользователя имя новой сущности.Эта строка отмечена [* * *].Как видите, вместо этого я предоставил статический текст «xxx», комментируя вызов метода JOptionPane.В этом случае JTree корректно обновляется, как и ожидалось.

Я подумал, что это может быть связано с моделью потоков Swing, но перенос текста обновления в класс Runnable не решает проблему.См. Также Почему мое JTree не обновляется, когда TreeModel добавляет новые узлы?

Почему 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

        }    

    }

1 Ответ

1 голос
/ 31 октября 2011

Проблема в том, что каждый раз, когда отображается JOptionPane, вы создаете новый фрейм, а не повторно используете мейнфрейм.Помните, что top - это метод, и когда вы ссылаетесь на «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);
...