如何在JFrame显示后从其中自动执行任务



如何在显示(类扩展)JFrame后立即自动执行任务(使用工作线程),同时,如果可能的话,在扩展JFrame的类中维护该任务的启动代码?

我找到的所有例子,以及我自己到目前为止如何使用它,只显示GUI类扩展的代码,在启动和显示GUI后对输入作出反应,在启动和显示GUI的代码之外进行任何自动进一步的操作;换句话说,我(做/不做)看到的是如下面的示例代码所注释的:

public static void main(String args[]) {
    //Set the Look and Feel
    //...
    //Create and display the form
    java.awt.EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new MyFrame().setVisible(true); //<--- I never see automatic stuff happening
            //...within here (class). I realize it can be done overriding setVisible(), but
            //...that would be cheating in regards to the intent of this question.
        }
    });
    //In the examples I found, and the way I have done it myself, automatic
    //..."after GUI is displayed" actions, such as a starting a worker that will load
    //...something heavy on startup, while the GUI displays a progressar, are started here.
}

是否有可能在MyFrame (JFrame的任何扩展)中执行任务,例如触发事件,启动工作,或以其他方式执行一些不相关的代码片段,而不需要在setVisible()的覆盖或组件的其他初始化方法中执行(以一种否则不会做的方式)?

如果可能的话,怎么做?


附加小问题:假设这是可能的,对于NetBeans的gui构建器自动生成的代码或类似结构的代码,有什么建议吗?

是的,这是可能的。


我想到了两个可能的解决方案来处理这两个问题;如果您希望该任务仅在第一次执行(例如,在启动时)或多次执行(每次显示该窗口或组件时):

  • JFrame中添加WindowListener,并在windowOpened(WindowEvent e)中启动动作/worker,这是"在侦听窗口第一次显示后调用"
  • JFrame中添加一个ComponentListener,并在componentShown(ComponentEvent)中启动动作/worker,这是"在被监听的组件变得可见之后调用,因为setVisible方法被调用"

其他侦听器的类似解决方案也是可能的,但这些可能是最好的方法,对于任何奇怪的情况,从这两种方法中,您应该了解如何实现其他变体。


奖金答:添加侦听器的最佳位置是在其他组件初始化之后。在NetBeans中,初始化代码是自动生成的,包含在一个方法(initComponents())中,并且大部分是锁定的(可能是为了避免修补会破坏与可视化GUI构建器相关的东西)。

由于侦听器与任何组件(除了框架本身)无关;或者你正在扩展的"基础"组件),将这个侦听器添加与其他初始化代码(包括负责GUI子组件操作的其他侦听器)分开实际上是一个好主意,因此NetBeans锁定初始化代码是这种分离的方便实施,实际上有助于保持代码的干净和可读。

在这种情况下,我们仍然在初始化之后添加侦听器,但是在构造函数中而不是在initComponents()方法中;因为"addSomeListener()"方法是可重写的,至少在这个例子中,我们不想在扩展中意外地"忘记"这段代码,我们做类似于自动生成的代码,并将我们的自指向"addSomeListener()"方法(和其他动作,如果需要的话)包装在我们自己的initSomething()方法中!

下面是一个代码示例:
//Within -> public class MyFrame extends javax.swing.JFrame {
//This is a mockup worker to simulate some time-consiming loading task that would be performed at startup, with the GUI providing a loading screen...
SwingWorker<Integer, Integer> StartupLoader = new SwingWorker<Integer, Integer>() {
    @Override
    protected Integer doInBackground() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("Some time consuming task is at " + i + "%...");
        }
        return 100;
    }
};
//This method is used to avoid calling an overridable method ('addWindowListener()') from within the constructor.
private void initSelfListeners() {
    WindowListener taskStarterWindowListener = new WindowListener() {
        @Override
        public void windowOpened(WindowEvent e) {
            System.out.println("Performing task..."); //Perform task here. In this case, we are simulating a startup (only once) time-consuming task that would use a worker.
            StartupLoader.execute();
        }
        @Override
        public void windowClosing(WindowEvent e) {
            //Do nothing...Or something...You decide!
        }
        @Override
        public void windowClosed(WindowEvent e) {
            //Do nothing...Or drink coffee...NVM; always drink coffee!
        }
        @Override
        public void windowIconified(WindowEvent e) {
            //Do nothing...Or do EVERYTHING!
        }
        @Override
        public void windowDeiconified(WindowEvent e) {
            //Do nothing...Or break the law...
        }
        @Override
        public void windowActivated(WindowEvent e) {
            //Do nothing...Procrastinate like me!
        }
        @Override
        public void windowDeactivated(WindowEvent e) {
            //Do nothing...And please don't notice I have way too much free time today...
        }
    };
    //Here is where the magic happens! We make (a listener within) the frame start listening to the frame's own events!
    this.addWindowListener(taskStarterWindowListener);
}
//The method that adds the listeners that perform the tasks is added in the constructor,
//right after initializing the components (auto-generated method in NetBeans).
public MyFrame() {
    initComponents();
    initSelfListeners(); //
}

相关内容

  • 没有找到相关文章

最新更新