Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 手动按下JButton会给doClick()带来不同的结果?_Java_Swing_Jbutton_Event Listener - Fatal编程技术网

Java 手动按下JButton会给doClick()带来不同的结果?

Java 手动按下JButton会给doClick()带来不同的结果?,java,swing,jbutton,event-listener,Java,Swing,Jbutton,Event Listener,当我的界面上有一个JButton按钮时,我有一个问题,当按下该按钮时,会触发此事件侦听器: if (event.getSource() == goButton) { MainLauncher.doProgram(assetsField.getText(), FileFinder.completePath(String.format("%s\\%s", modDirectoryPath, modList.getSelectedValue())), databaseField.getText

当我的界面上有一个
JButton
按钮时,我有一个问题,当按下该按钮时,会触发此事件侦听器:

if (event.getSource() == goButton)
{
    MainLauncher.doProgram(assetsField.getText(), FileFinder.completePath(String.format("%s\\%s", modDirectoryPath, modList.getSelectedValue())), databaseField.getText());
}
它运行以下代码:

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();
}
奇怪的是:

测试时,我没有将我的按钮添加到界面中,等等,我调用的是
goButton.doClick()
触发了doProgram(),并给出了我预期的结果,如下所示:

一些东西被打印出来(在从
System.out.println()
接收的界面上的
JTextArea
),控制台上方弹出一个进度条,在大约10秒内从0%变为100%,然后消失,再打印一些东西等等

但是,当我将按钮添加到界面时,我单击了它,其行为完全不同:

没有打印任何内容。进度条出现,并保持在0%10秒钟,然后消失,几秒钟后doProgram完成执行,所有在运行时应打印的信息突然同时打印

有人能告诉我是什么导致了这种奇怪的行为,以及如何修复它吗

我会发布一个SSCCE,但这是一个有点难做的程序,因为有这么多的任务和子流程。注意,我使用的进度条在GUI线程上运行,主代码在它自己的线程中完成(如您所见)


编辑:我添加了
setEnabled(false)doProgram
的侦听器中,code>和true,当按编程按钮时,按钮变灰,并按照我的预期重新激活,但是如果我手动单击按钮,它不会禁用,并且可以再次按下它,代码看起来有点混乱

但是,首先:您要调用在那里创建的新线程的
run()
方法。这将导致调用
doProgram
的线程执行
run()
方法中的代码,而在那里创建的新线程执行而不是。为了在这个新线程中真正执行代码,您必须调用
start()
,而不是
run()


这可能解释了您描述的大部分差异。但是,请记住,对Swing组件的修改始终必须在事件调度线程上完成。因此,无论您在做什么,例如,使用
gui.doCommands()
,请确保您没有违反此单线程规则

代码看起来有点混乱

但是,首先:您要调用在那里创建的新线程的
run()
方法。这将导致调用
doProgram
的线程执行
run()
方法中的代码,而在那里创建的新线程执行而不是。为了在这个新线程中真正执行代码,您必须调用
start()
,而不是
run()


这可能解释了您描述的大部分差异。但是,请记住,对Swing组件的修改始终必须在事件调度线程上完成。因此,无论您在做什么,例如,使用
gui.doCommands()
,请确保您没有违反此单线程规则

“我会发布一个SSCCE,但是对于这个程序来说有点困难,因为有太多的任务和子进程。”删掉那些不相关的代码。这就是SSCCE的想法!是的,我明白你的意思,我明天回到电脑前会把它清理一下!“我会发布一个SSCCE,但是对于这个程序来说有点困难,因为有太多的任务和子进程。”删掉那些不相关的代码。这就是SSCCE的想法!是的,我明白你的意思,我明天回到电脑前会把它清理一下!doCommands方法与GUI本身无关,在按下to go按钮之前,用户可以打开编辑器并为基于域的语言编写命令脚本,输入的命令由GUI存储,以便在需要时执行,它们涉及主要代码。谢谢你的跑步提示,我明天会试试:)是的,这就是问题所在。注意:doCommands方法与GUI本身无关,在按下to go按钮之前,用户可以打开编辑器并为基于域的语言编写命令脚本,输入的命令由GUI存储,以便在需要时执行,它们涉及主要代码。谢谢你的跑步提示,我明天会试试:)是的,这就是问题所在。接得好