简体   繁体   English

Java Swing使用GUI分离核心

[英]Java Swing separate core with GUI

I don't understand how to separate the core of my program with the GUI part of my program. 我不明白如何将程序的核心与程序的GUI部分分开。 Indeed, all the examples on the web say that any GUI action must be executed with SwingUtilities.invokeLater() method. 实际上,Web上的所有示例都表示必须使用SwingUtilities.invokeLater()方法执行任何GUI操作。

The problem is I don't understand how can I use this method to handle only my GUI part and how the core and the GUI can communicate. 问题是我不明白如何使用此方法仅处理我的GUI部分以及核心和GUI如何通信。

For instance, I have a class which have the reponsability of the GUI display of some calculations : 例如,我有一个类具有一些计算的GUI显示的可重复性:

public class GUI {
  private JFrame window;

  public GUI() {
    window = null;
  }

  public void createWindow(int width, int height) {
    window = new JFrame();
    ...
    window.setVisible(true);
  }

  public void displayResults(Calcul results) {
    /* Some Swing actions. */
  }
}

and I have the core of my program : 我有我的计划的核心:

public class Core {
  public static void main(String[] args) {
    GUI gui = new GUI();
    Calcul calculs = new Calcul();

    while (true) {
      /* Make some calculations. */
      /* Put results into calcul. */
      displayResults(calculs);
    }
  }
}

I know that this architecture is not ideal, but I have to use it. 我知道这种架构并不理想,但我必须使用它。 My question is, have I to use the EDT to separate the GUI part and the Core part ? 我的问题是,我是否要使用EDT来分离GUI部分和核心部分? And, if the answer is yes, how can I do it ? 而且,如果答案是肯定的,我该怎么办呢?

If it is possible, I need that the EDT calls are transparent to the user which uses the GUI class. 如果可能,我需要EDT调用对使用GUI类的用户是透明的。

EDIT: 编辑:

Does the following transformation of the GUI class has the expected behavior ? GUI类的以下转换是否具有预期的行为?

public class GUI {
  private JFrame window;

  public GUI() {
    window = null;
  }

  public void createWindowEDT(final int width, final int height) {
    javax.swing.SwingUtilities.invokeLater(
      new Runnable() {
        public void run() {
          createWindow(width, height);
        }
      }
    );
  }

  private void createWindow(final int width, final int height) {
    window = new JFrame();
    ...
    window.setVisible(true);
  }

  public void displayResultsEDT(final Calcul results) {
    javax.swing.SwingUtilities.invokeLater(
      new Runnable() {
        public void run() {
          displayResultsEDT(results);
        }
      }
    );
  }

  private void displayResults(final Calcul results) {
    /* Some Swing actions. */
  }
}

To put your GUI code in EDT, use SwingUtilities class. 要将您的GUI代码放在EDT中,请使用SwingUtilities类。 You have to pass a Runnable instance to invokeLater() method. 您必须将Runnable实例传递给invokeLater()方法。

You should create your GUI (call GUI constructor) in the EDT too. 您也应该在EDT中创建GUI(调用GUI构造函数)。

public static void main(String[] args) {

    GUI gui = null;
    Calcul calculs = new Calcul();

    SwingUtilities.invokeLater(
        new Runnable() {
             public void run() {
               gui = new GUI();
             }});


    while (true) {
    /* Make some calculations. */
    /* Put results into calcul. */
    javax.swing.SwingUtilities.invokeLater(
        new Runnable() {
             public void run() {
                 gui.displayResults(calculs);
             }});
    }
  }

The problem is you cannot run your calculation and your GUI in the same thread. 问题是你无法在同一个线程中运行计算和GUI。 If you do this, your GUI will freeze while your code is doing the number crunching. 如果这样做,您的GUI将在代码执行数字运算时冻结。 One approach is to run your calculations in a separate thread, then from that thread using SwingUtilities.invokeLater() signal your GUI that it should update itself. 一种方法是在一个单独的线程中运行计算,然后使用SwingUtilities.invokeLater()从该线程运行您的GUI,它应该更新自己。 For example: 例如:

public static void main(String[] args) {
    final GUI myGUI = new GUI();

    Thread workThread = new Thread(new Runnable() {
        public void run() {
            // do calculations

            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    // update GUI
                    myGUI.updateMyResults();
                }
            });
        }
    });

    workThread.start();
}

You can hide the use of the Event Dispatch Thread (EDT) in your GUI class. 您可以在GUI类中隐藏事件调度线程(EDT)的使用。 Its only the interaction with the Swing components that needs to be on the EDT given it's the Swing components that aren't normally thread-safe. 它只是与需要在EDT上的Swing组件的交互,因为它是通常不是线程安全的Swing组件。

There's no need for any synchronization in the GUI class given there's only the main application thread going to call GUI.displayResults(Calcul) , though if this changes you may want to synchronize this method or take other steps to avoid threading errors. 由于只有主应用程序线程将调用GUI.displayResults(Calcul) ,因此不需要在GUI类中进行任何同步,但如果此更改,您可能希望同步此方法或采取其他步骤来避免线程错误。

public class GUI
{
  ...

  public void displayResults(Calcul results) 
  {
    SwingUtils.invokeLater(
      new Runnable()
      {
        public void run()
        {
          /* Some Swing actions. */
        }
      }
    );
  }
}

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

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