我已经在听MenuListener.menuSelected()知道屏幕上显示JMenu的时间。最初,JMenu
有1 JMenuItem,表示“正在加载...”。操作缓慢后,我将JMenuItem
添加到JMenu
。 JMenu
继续显示“正在加载...”。如果我选择另一个JMenu
并返回,则JMenu会显示添加的JMenuItem
。如何使添加的JMenuItem
立即显示?
以下是重现正在发生的事情的代码。
public class AddMenuItem extends JFrame
{
private final JMenu m_menu = new JMenu("Edit");
public static void main(String args[])
{
new AddMenuItem().
setVisible(true);
}
public AddMenuItem()
{
JMenuBar bar;
bar = new JMenuBar();
bar.add(m_menu);
setJMenuBar(bar);
setSize(600, 400);
m_menu.addMenuListener(new MenuListener()
{
@Override
public void menuSelected(MenuEvent e)
{
JMenuItem loading;
loading = new JMenuItem("Loading...");
loading.setEnabled(false);
m_menu.removeAll();
m_menu.add(loading);
// This represents a long running task which updates the menu afterwards
new Timer(5 * 1000, event -> updateMenu()).start();
}
@Override
public void menuDeselected(MenuEvent e)
{
// nothing to do
}
@Override
public void menuCanceled(MenuEvent e)
{
// nothing to do
}
});
}
private void updateMenu()
{
m_menu.removeAll();
m_menu.add(new JMenuItem("1"));
m_menu.add(new JMenuItem("2"));
m_menu.add(new JMenuItem("3"));
m_menu.revalidate();
}
}
似乎这个code example完全符合我的要求,但我不确定他们在屏幕上重新绘制可见菜单是做什么的。
答案 0 :(得分:3)
最初,JMenu有1个JMenuItem,表示"正在加载..."。
从侦听器调用的代码在Event Dispatch Thread (EDT)
上执行。执行长时间运行的任务时,它会阻止EDT响应事件并重新绘制GUI。
因此,要解决该问题,该菜单项启动的任务需要在单独的线程中执行。您可能需要考虑使用SwingWorker
。有关EDT
和SwingWorker
的更多信息,请阅读Concurrency上的Swing教程中的部分。
编辑:
问题是,一旦我知道要添加到菜单中的内容,我就不知道如何让菜单显示添加的JMenuItems
您从JMenu
的{{1}}获得MenuEvent
:
MenuListener
编辑:
根据SSCCE,您可以执行以下操作:
JMenu menu = (JMenu)e.getSource();
menu.add( new JMenuItem( "Loading..." ) );
但请记住,因为您的长时间运行任务在一个单独的线程中执行,您需要使用SwingUtiltities.invokeLater调用上述代码,以便在EDT上执行代码。
看起来这个代码示例正是我想要的,但我不确定他们在屏幕上重新绘制可见菜单是做什么的。
我认为他们只是隐藏并再次显示菜单。
答案 1 :(得分:0)
不要执行EVP_DecryptFinal_ex()
,而是执行以下操作...
m_menu.revalidate()