简体   繁体   English

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

[英]Java passing values between two classes seamlessly

i have rather very basic question. 我有一个非常基本的问题。 I have one GUI class and another which does some background processing. 我有一个GUI类,另一个有一些后台处理。 Normally i have some methods in background class (which consist of multiple threads), which can return the result when called and i can use the result in GUI class. 通常,我在后台类(包含多个线程)中有一些方法,这些方法在调用时可以返回结果,并且我可以在GUI类中使用结果。

But now i have this strange problem that the GUI has to display something, which requires background class to call external process and once connected to this process, the connection will remain open, and as such i can not return anything unless the stream is closed. 但是现在我有一个奇怪的问题,GUI必须显示某些内容,这需要背景类来调用外部进程,并且一旦连接到该进程,连接将保持打开状态,因此除非关闭流,否则我将无法返回任何内容。 However the process keeps sending data which needs to be displayed on GUI 但是,该过程不断发送需要在GUI上显示的数据

If i put both in the same class, i can do so; 如果我把两者放在同一个班级,我可以这样做; by simple calling eg JLabel.setText(what ever coming from external prcess in infinite while loop). 通过简单的调用,例如JLabel.setText(在无限while循环中来自外部进程的任何东西)。 However if it is in a different class, i can not access this JLabel or any such component from another class. 但是,如果它在不同的类中,则无法从另一个类访问此JLabel或任何此类组件。 If i declare them static, the GUI throws exception, is there anyway i can avoid this, or the only option to write the code together in the same class with the GUI 如果我声明它们为静态,则GUI会引发异常,无论如何我都可以避免这种情况,或者是将代码与GUI一起写在同一类中的唯一选择

You have two problems to solve. 您有两个要解决的问题。

First, you need a means to communicate from one class to the other. 首先,您需要一种从一个班级与另一个班级进行交流的方法。 There are many ways to solve this problem. 有很多方法可以解决此问题。 For example, you could have the worker class publish events subscribed to by the GUI class. 例如,您可以让工作类发布GUI类订阅的事件。 Or you could pass to the worker class a reference to the GUI object (possibly as an interface type). 或者,您可以将对GUI对象的引用(可能作为接口类型)传递给worker类。

Second, you need to update the GUI only from the event-dispatch thread. 其次,您只需要从事件调度线程更新GUI。 You can do this primitively with SwingUtilities.invokeAndWait(Runnable) or SwingUtilities.invokeLater(Runnable) . 您可以使用SwingUtilities.invokeAndWait(Runnable)SwingUtilities.invokeLater(Runnable)进行原始操作。 Or you can use the higher-level framework provided by the SwingWorker class. 或者,您可以使用SwingWorker类提供的更高级别的框架。

You would implement the observer pattern . 您将实现观察者模式 Something like this: 像这样的东西:

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);
        }
    }
}

This way your background class will notify you GUI class about new data coming from the external process. 这样,您的后台类将通知GUI类有关来自外部进程的新数据。 But you should be careful with GUI updates and GUI thread. 但是您应该小心使用GUI更新和GUI线程。

Well you could create a function for setting the text in the GUI class so that you don't need to declare the text field as a public global var. 好吧,您可以创建一个用于在GUI类中设置文本的函数,这样就无需将文本字段声明为公共全局变量。 But as for calling from the other class you have two main options. 但是,从另一个类进行调用时,您有两个主要选择。 One is to have the other class passed the instance of your GUI class which it can then use to call the method to set the text. 一种是让另一个类传递您的GUI类的实例,然后它可以用来调用该方法来设置文本。 The other if you want it to be static is to make your GUI class a singlton class and have a static method that uses it to set the text. 如果您希望它是静态的,则另一种方法是使GUI类成为singlton类,并具有使用它设置文本的静态方法。

Like this, if your class is called GUI set it up like this: 像这样,如果您的类称为GUI,则按如下所示进行设置:

public class GUI {
     private static GUI singleton = new GUI();
     private GUI(){}
     public GUI getInstance(){
          return singleton;
     }
}

or instead of getInstance and calling the function you could have: 或者代替getInstance并调用您可能拥有的函数:

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

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

Be careful with this though, making singleton classes can be dangerous for your design if in the future you ever want to have multiple instances of the class. 但是请务必谨慎,如果将来您想拥有该类的多个实例,那么创建单例类对于您的设计可能会很危险。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM