带有安全管理器的 Swing 应用程序导致奇怪的 GUI 刷新问题

Posted

技术标签:

【中文标题】带有安全管理器的 Swing 应用程序导致奇怪的 GUI 刷新问题【英文标题】:Swing app with security manager causing strange GUI-refresh issues 【发布时间】:2010-11-12 07:12:22 【问题描述】:

我有一个作为客户端的 Swing 应用程序(驻留在可执行的签名 jar 中)。该应用程序还连接到服务器。当满足某些条件时,我会刷新 GUI(更具体地说,删除 JTree 的所有节点,然后重新填充它)。当我按原样运行此客户端时(即,没有安全管理器,也没有驻留在可执行的签名 JAR 中),树刷新和更新没有任何问题。

但是,当我将客户端打包为已签名的 JAR(使用适当的策略文件)时,我会遇到刷新问题。当应用程序启动时,我的JTree 没有展开。当我单击它一次时,它看起来已经展开,但子节点不显示。之后我必须单击它两次才能显示节点。此外,当我执行刷新(删除所有节点然后重新填充)时,UI 不会正确刷新。我(再次)必须单击根节点两次才能刷新 GUI。

我尝试将 AWT 权限添加到策略文件,但这没有帮助(我一开始没有看到任何权限违规,但我想我会尝试)。我什至尝试为 JAR 授予所有权限。这似乎也没有帮助。这可能是什么原因造成的?

执行刷新的代码如下:

private void buildTree() throws IOException, ClassNotFoundException 
    setVisible(false);
    tree.removeTreeWillExpandListener(this);
    tree.removeTreeSelectionListener(this);

    DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
    DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();
    root.removeAllChildren();

    root.setUserObject(base);

    Book[] bookArray = remoteLibraryService.getAllBooks();
    TreeBuilderService.buildTree(root, bookArray);
    treeModel.reload();

    for(int i = 0; i < tree.getRowCount(); i++) 
        tree.expandRow(i);
    

    tree.addTreeSelectionListener(this);
    tree.addTreeWillExpandListener(this);
    setVisible(true);

填充树的代码(仅显示相关的 sn-p):

categoryNode = new DefaultMutableTreeNode(book.getGenre());
root.add(categoryNode);

就任务而言,这可能不会破坏交易,但它真的让我很困扰;我想弄清楚是什么原因造成的。

【问题讨论】:

【参考方案1】:

正如Initial Threads 中所讨论的,Swing GUI 组件必须在事件调度线程上创建。根据经验,JTree 在从另一个线程操作时特别容易失败。 SecurityManager 可能是偶然的;任何时间上的变化,甚至是平台的变化,都可能暴露出这个缺陷。

【讨论】:

谢谢!这很有趣。我没有意识到这一点。我试过这样做(用invokeAndWait 调用buildTree()),但我在LibraryClient$1 上得到一个NoClassDefFoundError 没关系。我从一个罐子里运行它,我忘了把内部类添加到罐子里。谢谢!这非常有效。【参考方案2】:

您在 GUI 刷新周期中执行 IO,因此 GUI 线程很可能因此被阻塞/停止。 而是考虑使用 SwingWorker 并通过其 API 异步填充 Tree。

【讨论】:

以上是关于带有安全管理器的 Swing 应用程序导致奇怪的 GUI 刷新问题的主要内容,如果未能解决你的问题,请参考以下文章

带有夏季注释编辑器的 Django 管理页面导致切换扩展使其看起来很奇怪

从类更新所有扩展视图会导致延迟?

带有属性选择器的组件导致子元素不渲染

想用JAVA做一个类似于WINDOWS资源管理器的界面

java 在有GridLayout布局管理器的情况下,怎么设置元件大小

JavaSE基础(十 二 )---<GUI>GUI概述,Swing,容器组件,窗口,面板,布局管理器