Java Swing:主类等待 JFrame 关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20069374/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:51:33  来源:igfitidea点击:

Java Swing: main class wait until JFrame is closed

javaswinginputjframeinvokeandwait

提问by pips

I need some help with a simple java application which makes use of two jframe to get some input parameters. Here's a sketch of my code:

我需要一个简单的 java 应用程序的帮助,该应用程序使用两个 jframe 来获取一些输入参数。这是我的代码草图:

//second jframe, called when the button OK of the first frame is clicked
public class NewParamJFrame extends JFrame{
  ...
}

//first jframe
public class StartingJFrame extends JFrame{
  private static  NewParamJFrame newPFrame = null;
  private JTextField gnFilePath;
  private JButton btnOK;

  public StartingJFrame(){
            //..
    initComponents();
  }

  private void initComponents(){
     btnOK.addActionListener(new ActionListener(){
      public void actionPerformed(ActionEvent e){
        try{
        EventQueue.invokeAndWait(new Runnable(){
           public void run() {
               try {
               newPFrame = new NewParamJFrame();
               newPFrame.setVisible(true);
               } catch (Exception e) {
               e.printStackTrace();
               }
           }
         });
        }
        catch(InvocationTargetException e2) {} 
        catch(InterruptedException e1){}
        dispose();
      }
  }

  public String getText(){
       return gnFilePath.getText();
  }
}

public class Main {
  private static StartingJFrame begin = null;
  public static void main(String[] args) {
     try{
        EventQueue.invokeAndWait(new Runnable(){
            public void run() {
                try {
                    begin = new StartingJFrame();
                    begin.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    catch(InvocationTargetException e) {} 
    catch(InterruptedException e1){}

    String s= begin.getText();

    //...use s ...
  }
}

The call to getText() causes a NullPointerException. I want the main class to wait until the frames are closed but I don't know how to do. I'm using swing for the first time.

对 getText() 的调用导致 NullPointerException。我希望主类等到框架关闭,但我不知道该怎么做。我第一次使用swing。

采纳答案by dic19

I want the main class to wait until the frames are closed but I don't know how to do. I'm using swing for the first time.

我希望主类等到框架关闭,但我不知道该怎么做。我第一次使用swing。

If I understand your problem correctly, you need StartingJFrameto stay waiting until NewParamJFrameis closed and then continue its execution. If this is the case then it won't happen because JFramedoesn't support modality. But JDialogdoes, so you can have just one JFrameand do the parameters request in a JDialogwhose parent is this JFrame.

如果我正确理解您的问题,您需要StartingJFrame等待直到NewParamJFrame关闭然后继续执行。如果是这种情况,则不会发生,因为JFrame不支持模态。但是JDialog确实如此,因此您可以只有一个JFrame并在JDialog其父项是 this 中执行参数请求JFrame

For a better explanation about modality, take a read to How to Use Modality in Dialogs.

有关模态的更好解释,请阅读如何在对话框中使用

Also take a look to this topic: The Use of Multiple JFrames, Good/Bad Practice?

请参阅此主题:使用多个 JFrame,好/坏做法?

In any case you'll probably face a new problem: what should the JFramedo if the user closes/cancels the dialog withouth input any parameter? How could this JFrameknow what just happened in that dialog? One approach is described in this answer. You'll see the example is about a login dialog but the problem is similar to this one: How could a dialog notify to its parent frame on how the process went?

无论如何,您可能会面临一个新问题:JFrame如果用户在没有输入任何参数的情况下关闭/取消对话框该怎么办?这JFrame怎么知道在那个对话中刚刚发生了什么?此答案中描述了一种方法。您将看到该示例是关于登录对话框的,但问题与此类似:对话框如何通知其父框架进程如何进行?

回答by Masudul

The call to getText() causes a NullPointerException.

对 getText() 的调用导致 NullPointerException。

Because, gnFilePathof JTextFieldis null.

因为,gnFilePathJTextFieldnull

private JTextField gnFilePath;

public String getText(){
       return gnFilePath.getText();// NullPointerException is throw here.
}

To avoid NPE, you need to initialize JTextFieldand JButtonlike below.

为避免NPE,您需要初始化JTextFieldJButton如下所示。

  private JTextField gnFilePath=new JTextField();
  private JButton btnOK=new JButton()

回答by Holger

The easiest way to wait for close without modifying the code flow is to use a modal JDialog. So you have to change your StartingJFrameclass to make it a subclass of JDialoginstead of JFrame, and add the following to the begin of its constructor:

在不修改代码流的情况下等待关闭的最简单方法是使用 modal JDialog。因此,您必须更改您的StartingJFrame类以使其成为JDialog而不是的子类JFrame,并将以下内容添加到其构造函数的开头:

super((Window)null);
setModal(true);

Then the setVisible(true);invocation on the StartingJFrameinstance will wait until the dialog has been closed and hence the invokeAndWaitinvocation will wait too.

然后实例setVisible(true);上的调用StartingJFrame将等到对话框关闭,因此invokeAndWait调用也将等待。

回答by Ray3501

You can use a loop (preferably do-while loop) to put a frame on hold until the other frame closes or hides. Make sure to break the loop or increment the variable used for the loop by specific amount when the other frame is disposed or hidden. This way you can keep your StartingJFrameclass to remain as a subclass of JFrame.

您可以使用循环(最好是 do-while 循环)来保持一个框架,直到另一个框架关闭或隐藏。确保在处理或隐藏其他帧时中断循环或将用于循环的变量增加特定数量。通过这种方式,您可以将您的StartingJFrame类保留为JFrame.

    do {
        if (changeLog.isVisible()) {
        } else {
            changeLog.dispose();
            break;
        }
    } while (hold < 1);

or

或者

    do {
        if (changeLog.isActive()) {
        } else {
            break;
        }
    } while (hold < 1);

The first one would require the previous frame to be hidden (JFrame.HIDE_ON_EXITor Window.setVisible(false)) before the codes can be run. The last one would require the previous frame to be "disposed" (JFrame.DISPOSE_ON_EXITor (subclass of JFrame).dispose(). Add any of those codes on StartingJFrame, though, since you created a NewParamJFramein that class and have the corresponding field(s) set to private.

第一个要求在运行代码之前隐藏(JFrame.HIDE_ON_EXITWindow.setVisible(false))前一帧。最后一个将需要“处置”前一帧(JFrame.DISPOSE_ON_EXIT(subclass of JFrame).dispose()StartingJFrame不过,在 上添加任何这些代码,因为您NewParamJFrame在该类中创建了 a并将相应的字段设置为private