我对 Scala 和 Swing 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
}
}
最佳答案
问题是,每次显示 JOptionPane
时,您都会创建一个新的 Frame,而不是重用 MainFrame。请记住,top
是一个方法,当您引用“top”来显示 JOptionPane
时,您正在创建一个新的 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);
关于java - JTree 节点未更新(在 Scala 中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7948664/