Question

I have a problem when a JButton on my interface, when pressed the button triggers this event listener:

if (event.getSource() == goButton)
{
    MainLauncher.doProgram(assetsField.getText(), FileFinder.completePath(String.format("%s\\%s", modDirectoryPath, modList.getSelectedValue())), databaseField.getText());
}

which runs the following code:

public static void doProgram(final String baseGamePath, final String modPath, final String databasePath)
{
    new Thread() 
    {
        public void run()
        {
            System.out.println("Running: " + modPath + "\n");

            reader = new MetaDataReader(databasePath);
            reader.formConnection();

            long start = System.currentTimeMillis();
            long temp;

            File cache = new File("RegisterCache.SC");
            if (!cache.exists())
            {
                temp = System.currentTimeMillis();

                start += System.currentTimeMillis() - temp;
                System.out.println("Calculating number of files");
                FileFinder baseGame = new FileFinder();
                baseGame.calculateNumFiles(baseGamePath);
                System.out.println(String.format("Loading %s base game files", baseGame.getNumFiles()));
                gui.doProgressBar();
                baseGame.findFiles(baseGamePath, true);
                gui.killProgressBar();
                System.out.println();

                 //load the base game assets, we want to move this to metadata later    
                System.out.println("Checking for base game reference errors");
                new ReferenceDetector(Table.getRegister()).findReferences(true);
                Table.serializeTable(cache); //write the database to cache, we can use it next time
            }
            else
            {
                System.out.println("Loading cache");
                Table.unserializeTable(cache);
            }

            gui.doCommands(); //calls reset()!!! be careful with the temporary excludes!

            System.out.println("Eliminating base game requires errors");
            RequiresWhere.executeRequires(true);

            temp = System.currentTimeMillis();

            start += System.currentTimeMillis() - temp;
            System.out.println("Calculating number of files");
            FileFinder mod = new FileFinder();
            mod.calculateNumFiles(modPath);
            System.out.println(String.format("Loading %s mod files", mod.getNumFiles()));
            gui.doProgressBar();
            mod.findFiles(modPath, false);
            gui.killProgressBar();

            System.out.println();
            System.out.println("Finding reference errors");
            new ReferenceDetector(Table.getRegister()).findReferences(false);

            System.out.println("Finding requires errors");
            RequiresWhere.executeRequires(false);

            System.out.println("Checks complete");
            reader.killConnection();

            System.out.println(String.format("Execution Time: %dms", System.currentTimeMillis() - start));
            Table.reset();
        }
    }.run();
}

The odd thing is this:

When testing I didn't have my button added to the interface, and so on main() I was calling goButton.doClick(); which triggered the doProgram(), and gives me the results I expected which is this:

a couple of things are printed out (to a JTextArea on the interface that receives from System.out.println()), a progress bar pops up above the console, and goes from 0% to 100% in around 10 seconds, disappears, a few more things are printed etc etc.

However when I added the button to the interface I clicked it and the behavior was not the same at all:

Nothing is printed. The progress Bar comes up, and stays at 0% for 10 seconds, then disappears, a few seconds later the doProgram finishes executing and all the information that should have been printed during runtime is suddenly printed all at once.

Can anybody tell me what is causing this strange behavior and how it can be fixed?

I would post a SSCCE, but it is a little difficult to do for this program as there are so many tasks and subprocesses. Note that, the progress bar I use it run on the GUI thread, the main code is done in it's own thread (as you can see)

EDIT: I added setEnabled(false); and true inside the listener surrounding the call to doProgram, and when the button is programatically pressed, the button is greyed out and this renabled as I expect, however if I click the button by hand it does not disable, and I can press it again

Was it helpful?

Solution

The code looks a bit confusing.

However, first of all: You are calling the run() method of the new Thread that you are creating there. This will cause the code from the run() method to be executed by the thread that calls doProgram, and not by the new Thread that you are creating there. In order to execute the code really in this new Thread, you have to call start() instead of run().

This explains probably most of the differences that you described. However, keep in mind that modifications to Swing components always have to be done on the Event Dispatch Thread. So whatever you are doing, for example, with gui.doCommands(), make sure that you don't violate this Single Thread Rule.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top