2011-10-30 50 views
1

我對ScalaSwing JTree組件(Java)之間的互操作性存在問題。未更新的JTree節點(在斯卡拉)

JTree不能正確更新,除非我停止顯示JOptionPane以提示用戶輸入新實體的名稱。該行標有[* * *]。正如你所看到的,我提供了靜態文本「xxx」,而不是註釋掉對JOptionPane方法的調用。在這種情況下,JTree正如預期的那樣正確更新。

我認爲這可能與Swing線程模型有關,但是將更新文本封裝到Runnable類中並未解決問題。另請參閱Why isn't my JTree updating when the TreeModel adds new nodes?

爲什麼JOptionPane會阻止JTree正確更新節點?

我這樣做是因爲Scala還沒有允許動態更新的Swing樹實現。請參閱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

的問題是所顯示的JOptionPane每一次,你要創建一個新的框架,而不是重用大型機上。請記住,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); 
+0

非常感謝......我不知道,我每次調用定義的方法,而不是使用存儲變量。 : - /乾杯! –