All,

I usually write console apps, but now I have to do a forms app. Hopefully that will explain the sillyness of the following question:

I created my project in NetBeans and NetBeans automatically generated a class with the project name, and this class has a main() method. Then I created a JFrame for my main panel and it also has a main() method.

So, which one of these main methods is the actual entry point of the program and which one do I throw away?

Thanks,
Bill

What code is in the two main() methods? Any class can have a main() method. The class used to start the execution of a program does not have to be named: Main.
I personally do not create a separate class to house a main() method that creates an instance of another class to execute the other class. I add the main() method to the class that I want the main() method to execute.

The IDE must do things its own way, so you should let it do what it wants or you'll probably have problems.

The class with project name is the Main class generated with project creation (you can disable main method checkbox on bottom of wizard), yeah you can clear the main method on auto generated class or copy the jFrame/Panel source code to the Main class.
In fact the main method place does not matter. The gui elements is just like console apps could be written from zero bit in empty file.
I like to place the main() method in the main form class (usually jFrame). after all if your project has multiple main() methods Netbeans will ask you on project running, which one class with main method is the execution file? and you can set it on project running.

Sorry for weak English

I would keep the main method in the project class and ignore/discard the one in the JFrame class.
My reason is that starting a program, in general, is more than just opening the main window. In real life you may need to create a database connection, start a server instance, get user/project preferences, open some files, load some shared resources, initialise a data model... all kinds of stuff that definitely does not belong in a JFrame. So in your project main you would call all that initialisation stuff, and only then create the new instance of the JFrame.

kamyarn, your answer was helpful, thank you.

James, you said "starting a program, in general, is more than just opening the main window. In real life you may need to create a database connection, start a server instance, get user/project preferences, open some files, load some shared resources, initialise a data model... all kinds of stuff that definitely does not belong in a JFrame."

I agree 100%. The problem is, I'm not sure how to get all the stuff in the JFrame main() into the main classes's main() and still have everything work correctly. Here's what's in the JFrame main():

public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Windows".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainPanel.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MainPanel().setVisible(true);
            }
        });
    }

Can I just copy that into my main class? What's with idea of running the GUI in a new thread? When the GUI calls a method in another class does that method execute in the GUI thread? Ideally I'd wnat to GUI running in a thread that's independant so that if something hangs at least the menus will still work.

Any thoughts?

Thanks,
Bill

  1. All that crud in main down to line 24 is just setting your L&F. Yes - its boilerplate and you can move that to your "real" main method so it just gets executed once at startup. Lines 26-31 go wherever/whenever you are ready to open the main form.
  2. Java runs all its Swing-related stuff in its own thread - the "swing thread" or "event dispatch thread" or "EDT" (google those terms) via a single event queue. This includes all the screen painting, updating Swing comnponents, and calling your listeners for events such as mouse clicks. That way swing does not need to be thread-safe, which makes it simpler and faster.
    When your code needs to do something with Swing it should also use that same thread, which is what invokeLater asks Swing to do.
    Its a big topic, but you'll find the info you need starting in the Oracle Java tutorials. http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Excellent reply, James. Thank you.

I read the tutorial (I'll have to go through it several times), but am I correct in understanding that Runnable is only for threads in console apps and SwingWorker is for any and all threads in a Swing app even if those threads don't interact with a Swing form?

Ex: Say my Swing form has a button called "Process File". Pushing this button reads a huge .csv file, filters out all the bad data, and then writes a new .csv file. This takes about 30 seconds. So, this has to run in a SwingWorker thread in order for the other buttons (e.g. the Cancel button) on my form to still work? It can't run in a class that merely extends Runnable?

Thanks,
Bill

Edited 4 Years Ago by WDrago

You can use any thread except the main Swing thread. SwingWorker is just a convenience class that helps organise and interact with a background thread, but yoyu don't ahve to use it.

Okay James. Thanks again., The more I read that tutorial the more sense it makes. I also learned quite a bit by looking at the sample code Flipper.java.

Best,
-Bill

Edited 4 Years Ago by WDrago

This question has already been answered. Start a new discussion instead.