添加JFrame事件处理程序之前的滞后时间



我正在做一个简单的Java swing项目。这是主类的代码(名称已更改):

public class MainProg
{
    private static MainProg program; 
    //mainWin is a JFrame
    private MainWindow mainWin;
    //Event handler class which extends MouseAdapter
    private TrayManager trayMgr;

    public static void main(String[] args)
    {                
        program = new MainProg();
    }
    public MainProg()
    {
        mainWin = new MainWindow();
        trayMgr = new TrayManager();
        mainWin.startBtn.addMouseListener(trayMgr);
        mainWin.setVisible(true);
    }
}

很明显,当程序启动时,它会在main()中创建MainProg类的一个新实例,然后调用构造函数。在构造函数中,它创建JFrame mainWin的一个新实例。然后,它将一个事件处理程序附加到mainWin上的一个按钮上。

在事件处理程序类trayMgr中,唯一的方法是mouseClicked(),它什么都不做除了System.out.println('Clicked');

问题是,当我在Netbeans中运行这个程序时,JFrame会立即显示,但在控制台中打印消息之前,我似乎必须单击按钮2-3次。

这只是Netbeans特有的东西吗?还是我必须更改一些东西,以便在窗口可见之前设置事件处理程序?

您的线程问题不太可能是导致当前问题的原因,但理论上存在问题的可能性,我看到了一些与一些更敏感的外观和感觉相关的真实问题。很简单,您应该将启动GUI的代码排队到Swing事件线程上。你这样做:

public void main(String[] args) {
  SwingUtilities.invokeLater(new Runnable(
    public void run() {
      program = new MainProg();
    }
  ));
}

其他人建议使用invokeAndWait(...)而不是invokeLater(...),但这可能会有风险,尤其是当您无意中从Swing事件线程内部进行此调用时。对于您的情况,最好使用invokeLater(...)

但是,我再次认为,您所展示的代码的主要问题是在本应使用ActionListener的地方使用MouseListener不恰当。学习编写任何GUI库的代码可能非常棘手,因此,您不能假设任何内容。查看教程并向专家学习。此外,如果您正在考虑对Swing进行长期编码,请考虑放弃NetBean的代码生成实用程序,并首先学习手动编码Swing。你不会后悔这样做的。

既然你问了,我在这里发布的代码是关于另一个主题的Java SSCCE。invokeLater是在EDT上运行计算的一种方式。(还有invokeAndWait,它在这里可以正常工作,但在其他一些条件下可能会导致死锁。)

事实上,这个例子可能有点过于保守。一些引用说,您可以从主线程运行Swing,即对show()setVisible()的调用。然而,当我尝试Java 7时,我有一个程序在Java 7下表现不佳。

最新更新