2016-09-19 1 views
0

Как автоматически выполнить задачу (с использованием рабочего потока) сразу после отображения (расширения класса) JFrame, если возможно, поддерживая исходный код для этой задачи в классе, расширяющем JFrame?Как автоматически выполнить задачу после отображения JFrame изнутри?

Все примеры, которые я нахожу, и как я сам использовал его до сих пор, показывают только расширения 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() или другого метода инициализации компонента (компонентов, который иначе не был бы выполнен)?

И если возможно, как это сделать?


Bonus второстепенный вопрос: Предполагая, что это возможно, есть какая-либо рекомендация о том, где сделать это для GUI-строитель автоматически генерируемого кода Netbeans' или код подобной структуры?

ответ

2

Да, это возможно.


Несколько возможных решений приходят на ум, для работы с обоими; если вам нужна задача, которая должна выполняться только в первый раз (при запуске, например), или несколько раз (каждый раз, когда отображается окно или компонент):

  • Добавление WindowListener к JFrame изнутри он и инициирует действие/работника в пределах windowOpened(WindowEvent e), то есть «Вызывается сразу после первого прослушиваемого окна».
  • Добавление ComponentListener к JFrame из внутри него, и имеют, что инициировать действие/работника в пределах componentShown(ComponentEvent), который «Вызывается после того, как отслеживаемый компонент становится видимым, как результат SetVisible метода называют».

Аналогичных решений с other listeners также возможны, но они, вероятно, лучшими методами, и для любых нечетных случаев, из этих двух, вы должны получить представление о том, как реализовать другие варианты.


Bonus Ответ: Лучшее место для добавления слушателей будет после инициализации других компонентов. В NetBeans код инициализации автоматически генерируется, содержащийся в методе (initComponents()) и в основном заблокирован (возможно, чтобы избежать возиться, что нарушит работу, связанную с визуальным графическим дизайнером).

Поскольку слушатель не связан ни с одним компонентом (кроме самого кадра или компонента «базовый», который вы расширяете), на самом деле это хорошая идея отделить это дополнение слушателя от остальной части кода инициализации (включая других слушателей, ответственных за операции подкомпонентов графического интерфейса), и поэтому блокировка кодов инициализации 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(); // 
}