Java Swing:主类等到JFrame关闭

时间:2013-11-19 10:45:51

标签: java swing input jframe invokeandwait

我需要一些简单的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 ...
  }
}

对getText()的调用会导致NullPointerException。我希望主类等到帧关闭但我不知道该怎么做。我是第一次使用秋千。

5 个答案:

答案 0 :(得分:5)

  

我希望主类等到帧关闭但我没有   知道该怎么做。我是第一次使用秋千。

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

要获得有关模态的更好解释,请阅读How to Use Modality in Dialogs

另请参阅此主题:The Use of Multiple JFrames, Good/Bad Practice?

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

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:2)

  

对getText()的调用会导致NullPointerException。

因为gnFilePath的{​​{1}}是JTextField

null

要避免private JTextField gnFilePath; public String getText(){ return gnFilePath.getText();// NullPointerException is throw here. } ,您需要初始化NPEJTextField,如下所示。

JButton

答案 3 :(得分:0)

尝试将其放置:

import java.awt.event.*;
import javax.swing.*;

public class MyWindow extends JFrame{
    MyWindow(){
        setSize(300, 200);
        setLayout(null);    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        JButton b = new JButton("Close");
        b.setBounds((300-80)/2, (200-30)/2, 80, 30);
        //
        final MyWindow frame = this;
        b.addActionListener(
            new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent ev){
                    synchronized(frame){
                        frame.notify();
                    }
                
                    frame.setVisible(false);
                    frame.dispose();
                }
            }
        );
        //
        getContentPane().add(b);
        
        setVisible(true);
        
        synchronized(this){
            try{ 
                this.wait();
            }
            catch(InterruptedException ex){ }
        }
    }


    public static void main(String args[]) {
        new MyWindow();
        System.out.println("You are here");
    }
}

上面的代码已检查。

答案 4 :(得分:-2)

您可以使用循环(最好是执行循环)将帧置于保持状态,直到另一帧关闭或隐藏。当处理或隐藏另一帧时,确保打破循环或将用于循环的变量增加特定量。这样,您可以将StartingJFrame类保留为JFrame的子类。

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

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

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