在一个扩展JMenu的类中,我创建了一个新的JPopupMenu.Separator对象并将其添加到菜单中:
if (separator == null)
{
separator = new JPopupMenu.Separator()
this.add(separator);
}
然后,在菜单中添加/删除内容的各个位置,我调用一个updateSeparatorVisibility
定义如下的方法:
private void updateSeparatorVisibility()
{
if (separator != null)
{
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
// vis is some public boolean
separator.setVisible(vis);
}
});
this.revalidate();
this.repaint();
}
}
这将在菜单关闭时调用,当我重新打开菜单时,我希望看到分隔符可见性的变化。
在Windows上,这工作得很好。在 Mac 上,分隔符将在需要时从不可见更改为可见,但之后不会更改回不可见。事实上,我之前看到可见性变化的概率约为 50%。在添加了invokeLater
、revalidate
和repaint
之后,情况似乎不再如此,所有这些都在其他各种 StackOverflow 帖子中被推荐,但尚未解决问题。
我已经投入了很多登录,代码肯定会在应该调用setVisible
并且vis
具有预期值时调用 - 我只是没有看到这反映在菜单的行为中。
我的代码有什么问题,为什么它依赖于平台?
您的boolean vis
字段可能public
,但是"只有当写入操作发生时,一个线程的写入结果才保证对另一个线程的读取可见 - 在读取操作之前。使字段volatile
,因为"对易失性字段的写入发生在每次后续读取同一字段之前。有关详细信息,请参阅内存一致性属性。