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存储,以便在需要时执行,它们涉及主要代码。谢谢你的跑步提示,我明天会试试:)是的,这就是问题所在。接得好