我有一个非常基本的问题。我有一个GUI类,另一个做一些后台处理。通常我在后台类中有一些方法(由多个线程组成),它可以在调用时返回结果,我可以在GUI类中使用结果。
但是现在我有一个奇怪的问题,GUI必须显示一些东西,这需要后台类来调用外部进程,一旦连接到这个进程,连接将保持打开状态,因此我不能返回任何内容,除非流关闭了。但是,该过程不断发送需要在GUI上显示的数据
如果我把两者放在同一个班级,我可以这样做;通过简单的调用,例如JLabel.setText(在无限循环中来自外部prcess的东西)。但是,如果它在不同的类中,我无法访问此JLabel或来自其他类的任何此类组件。如果我将它们声明为静态,那么GUI会引发异常,无论如何我可以避免这种情况,或者只是在与GUI相同的类中编写代码的唯一选项
答案 0 :(得分:5)
您有两个问题需要解决。
首先,您需要一种方法从一个类到另一个类进行通信。有很多方法可以解决这个问题。例如,您可以让工作类发布GUI类订阅的事件。或者您可以向工作类传递对GUI对象的引用(可能作为接口类型)。
其次,您只需要从事件派发线程更新GUI。您可以使用SwingUtilities.invokeAndWait(Runnable)或SwingUtilities.invokeLater(Runnable)进行原始操作。或者您可以使用SwingWorker类提供的更高级别的框架。
答案 1 :(得分:2)
您将实施observer pattern。像这样:
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线程。
答案 2 :(得分:0)
您可以创建一个用于在GUI类中设置文本的函数,这样您就不需要将文本字段声明为公共全局变量。但至于从其他班级打电话,你有两个主要选择。一种是让另一个类传递GUI类的实例,然后可以使用它来调用方法来设置文本。另一个如果你希望它是静态的,那就是让你的GUI类成为一个单独的类,并使用一个静态方法来设置文本。
像这样,如果您的类被称为GUI,请将其设置为:
public class GUI {
private static GUI singleton = new GUI();
private GUI(){}
public GUI getInstance(){
return singleton;
}
}
或者代替getInstance并调用你可以拥有的函数:
public class GUI {
private static GUI singleton = new GUI();
private GUI(){}
public void setText(){
//your code
}
public static void setTheText(){
singleton.setText();
}
}
要小心这一点,如果将来你想要拥有该类的多个实例,使单例类对你的设计来说可能是危险的。