Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 从外部类和线程调用Jframe中的方法以设置标签值_Java_Multithreading_Swing_Jframe_Thread Synchronization - Fatal编程技术网

Java 从外部类和线程调用Jframe中的方法以设置标签值

Java 从外部类和线程调用Jframe中的方法以设置标签值,java,multithreading,swing,jframe,thread-synchronization,Java,Multithreading,Swing,Jframe,Thread Synchronization,我有两个类,一个JFrame和一个实现runnable的外部类。我希望在自己的线程中运行外部类,直到发出停止命令为止。我还希望它通过在其类中实现的方法在自己的线程中在后台更新JFrame上的值(或者我认为最优雅的方法就是这样) 我已经做了一个简单的程序来说明我想做什么,并表明它不起作用。据我所知,当从EDT外部调用JFrame时,JFrame的值不会更新。我一直在寻找修复方法,即在invokelater()调用中包装您希望更改文本值的代码部分。然而,这仍然不起作用。我真的很为难,我相信这很简单,

我有两个类,一个JFrame和一个实现runnable的外部类。我希望在自己的线程中运行外部类,直到发出停止命令为止。我还希望它通过在其类中实现的方法在自己的线程中在后台更新JFrame上的值(或者我认为最优雅的方法就是这样)

我已经做了一个简单的程序来说明我想做什么,并表明它不起作用。据我所知,当从EDT外部调用JFrame时,JFrame的值不会更新。我一直在寻找修复方法,即在
invokelater()
调用中包装您希望更改文本值的代码部分。然而,这仍然不起作用。我真的很为难,我相信这很简单,我只是不明白为什么这不起作用

在这个简单的示例中,我在JFrame中有一个开始按钮和输出。我实例化了我的外部类,并在按下start按钮时将其作为JFrame类中的线程启动。线程位于外部类中,并更新输出,直到达到5。它通过在JFrame中调用一个方法来实现这一点,该方法调用输出标签上的
setText()

JFrame(我将省略自动生成的部分):

我的外部课程:

package javaapplicationtest;

import java.util.logging.Level;
import java.util.logging.Logger;

public class JavaExternClass implements Runnable {    
    public void run() {
        gui = new JavaTestForm();
        for (int i = 0; i < 4; i++) {
            gui.setLabel(i); // Call method to set form output
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(JavaTestForm.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    private JavaTestForm gui;
}
包javaapplicationtest;
导入java.util.logging.Level;
导入java.util.logging.Logger;
公共类JavaExternClass实现可运行{
公开募捐{
gui=新的JavaTestForm();
对于(int i=0;i<4;i++){
setLabel(i);//调用方法设置表单输出
试一试{
睡眠(1000);
}捕获(中断异常例外){
Logger.getLogger(JavaTestForm.class.getName()).log(Level.SEVERE,null,ex);
}
}
}
私有JavaTestFormGUI;
}

在创建
JavaExternClass
的新实例时,您正在创建一个新实例
JavaTestForm
…我现在无法理解这是如何在
StackOverflowException中结束的,但“其他”问题是,
JavaExternClass
中的
JavaTestForm
实例与在
main
中创建的实例无关,后者实际上是屏幕上的UI

与其让
JavaExternClass
创建
JavaTestForm
的新实例,不如将
JavaTestForm
的引用传递给它

public class JavaExternClass implements Runnable {   
    private JavaTestForm gui;
    public JavaExternClass(JavaTestForm gui) {
        this.gui = gui;
现在,在这些事情上,我是一个墨守成规的人,但是,我不想把类传递给其他类,这些类具有收件人不应该知道或访问的其他功能,没有比删除所有组件的类更糟糕的了

相反,我将创建一个
接口
,它描述了
JavaExternClass
希望在
JavaTestForm
上执行和实现此类的操作,从而只公开
JavaExternClass
所期望的功能,而不公开其他功能


您可能还想查看和

“(我将省略自动生成的部分):“为了更快地获得更好的帮助,请发布一个(最小完整可验证示例)或(简短、自包含、正确的示例)<代码>线程睡眠(1000)不要在Swing/AWT GUI中使用它。而是使用Swing
定时器。
计时器内的动作(
actionPerformed(…)
)在EDT上自动执行。我看了你的简历后,明白了你为什么提到SSCCE和MCVE。我写了SSCCE并帮助创建MCVE的原因与我经常链接到它们(并写了很多)的原因相同。因为准备MCVE/SSCCE既是一种很好的调试技术,也是将问题传达给他人的一种很好的方式。目前,我有2位代码正在使用,其中一位包含一个“钢琴键盘”,允许用户选择一种乐器,单击一个键,然后听到该乐器在该音调下的声音。但我试图添加加载和播放MIDI音乐的功能,并显示正在播放的键,但遇到了问题。所以我创建了一个MCVE来测试。。。。思想。它根本没有GUI(因为GUI与问题无关),只关注播放MIDI序列,同时尝试检测音符开/关控制代码(这是我还没有设法解决的问题)。我将检查这些参考,但在本例中,正如您所指出的,它只是一个非常好的糟糕代码示例,以及对基本oo原则/语义的误用/误解。我在这个问题上做得太多了,我想我的大脑已经崩溃了。你对安德鲁·汤普森对我最初问题的评论有什么看法吗?我更喜欢这个实现,而不是使用
定时器
s(这些类有很多,它们与外部设备执行相当复杂的通信/操作)。但是我对Java相对不熟悉,所以我真的不知道。如果您打算定期修改UI的状态,那么是的,Swing
计时器将是更好的选择,因为它在事件调度线程的上下文中执行tick回调。但是,如果您需要等待某些信息/执行长时间运行的流程,则
SwingWorker
可能更好,它允许您在EDT之外执行操作,但支持通过
发布
/
流程
方法将更新同步回EDT。。。
public class JavaExternClass implements Runnable {   
    private JavaTestForm gui;
    public JavaExternClass(JavaTestForm gui) {
        this.gui = gui;