Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.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在两个类之间无缝地传递值_Java_Swing_Static Methods - Fatal编程技术网

Java在两个类之间无缝地传递值

Java在两个类之间无缝地传递值,java,swing,static-methods,Java,Swing,Static Methods,我有一个相当基本的问题。我有一个GUI类,另一个做一些后台处理。通常,我在后台类中有一些方法(由多个线程组成),这些方法可以在调用时返回结果,并且我可以在GUI类中使用结果 但现在我遇到了一个奇怪的问题,GUI必须显示一些东西,这需要后台类调用外部进程,一旦连接到这个进程,连接将保持打开状态,因此,除非关闭流,否则我无法返回任何内容。但是,该过程不断发送需要在GUI上显示的数据 如果我把两者放在同一个班上,我就能做到;通过简单的调用,例如JLabel.setText(无限while循环中来自外部

我有一个相当基本的问题。我有一个GUI类,另一个做一些后台处理。通常,我在后台类中有一些方法(由多个线程组成),这些方法可以在调用时返回结果,并且我可以在GUI类中使用结果

但现在我遇到了一个奇怪的问题,GUI必须显示一些东西,这需要后台类调用外部进程,一旦连接到这个进程,连接将保持打开状态,因此,除非关闭流,否则我无法返回任何内容。但是,该过程不断发送需要在GUI上显示的数据


如果我把两者放在同一个班上,我就能做到;通过简单的调用,例如JLabel.setText(无限while循环中来自外部进程的内容)。但是,如果它位于不同的类中,我无法从其他类访问此JLabel或任何此类组件。如果我将它们声明为静态,GUI会抛出异常,我是否可以避免这种情况,或者使用GUI在同一个类中一起编写代码的唯一选项。您可以创建一个函数来设置GUI类中的文本,这样您就不需要将文本字段声明为公共全局变量。但是,对于从另一个类调用,您有两个主要选项。一种是让另一个类传递GUI类的实例,然后它可以使用该实例调用方法来设置文本。如果希望它是静态的,另一个方法是将GUI类设置为singlton类,并使用一个静态方法来设置文本

如下图所示,如果您的类被称为GUI,请将其设置为:

public class GUI {
     private static GUI singleton = new GUI();
     private GUI(){}
     public GUI getInstance(){
          return singleton;
     }
}
public interface DataObserver {
   void newDataCame(String someData);
}

public class GUIclass {
    public void method() {
       bgClass.callInBg( new DataObserver() {
           public void newDataCame(String someData) {
               JLabel.setText(someData);
           }
       } );
    }
}

public class BGClass {
    public void callInBg(DataObserver observer) {
        while(true) {
            String data = null;
            // read some data;
            observer.newDataCame(data);
        }
    }
}
或者代替getInstance并调用您可以拥有的函数:

public class GUI {
     private static GUI singleton = new GUI();
     private GUI(){}
     public void setText(){
          //your code
     }

     public static void setTheText(){
          singleton.setText();
     }
}

但是要小心,如果将来您想要有多个类实例,那么创建单例类可能会对您的设计造成危险。

您有两个问题需要解决

首先,您需要一种从一个类到另一个类进行通信的方法。有很多方法可以解决这个问题。例如,您可以让工作类发布事件由GUI类订阅。或者您可以将对GUI对象的引用(可能作为接口类型)传递给worker类

其次,您只需要从事件分派线程更新GUI。您可以使用或基本完成此操作。或者您可以使用类提供的更高级别的框架。

您可以实现。大概是这样的:

public class GUI {
     private static GUI singleton = new GUI();
     private GUI(){}
     public GUI getInstance(){
          return singleton;
     }
}
public interface DataObserver {
   void newDataCame(String someData);
}

public class GUIclass {
    public void method() {
       bgClass.callInBg( new DataObserver() {
           public void newDataCame(String someData) {
               JLabel.setText(someData);
           }
       } );
    }
}

public class BGClass {
    public void callInBg(DataObserver observer) {
        while(true) {
            String data = null;
            // read some data;
            observer.newDataCame(data);
        }
    }
}

这样,后台类将通知GUI类来自外部进程的新数据。但是,在GUI更新和GUI线程方面,您应该小心。

为什么选择单例?将GUI传递给backgroundworker不是更容易吗?这样用户就可以在没有singleton(anti)模式的情况下正常访问它了?因此,我的第一部分答案是传递GUI类。但是我包括了singleton部分,因为他可能不想把它显式地传递给线程,并且提到了静态访问。是的,在这种情况下,最好通过GUI。然而,在某些情况下,确实需要使用单例设计模式,这是非常合适的。1+投票:我会选择这里的最后一个rec,使用SwingWorker,特别是它的publish/process method duo,听起来似乎非常适合OP的需要。