4

我需要一个简单的 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。我希望主课等到框架关闭,但我不知道该怎么做。我是第一次使用swing。

4

6 回答 6

6

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

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

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

还可以看看这个主题:多个 JFrame 的使用,好/坏做法?

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

于 2013-11-19T13:20:24.687 回答
5

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

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

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

于 2013-11-19T13:02:45.053 回答
2

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

因为,gnFilePath是。JTextFieldnull

private JTextField gnFilePath;

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

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

  private JTextField gnFilePath=new JTextField();
  private JButton btnOK=new JButton()
于 2013-11-19T10:47:49.387 回答
1

试着把这个:

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

检查上面的代码。

于 2020-09-07T13:01:01.573 回答
0

使用 JDialog 可能是最简单的解决方案,但在某些情况下,最好使用 JFrame,例如在任务栏中显示窗口。使用 Octavio 建议的同步机制是实现此目的的一种方法,这是使用 CountDownLatch 阻塞主线程直到帧关闭的替代方法:

public static void main(String[] args) throws Exception {
    CountDownLatch latch = new CountDownLatch(1);

    SwingUtilities.invokeLater(() -> {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        frame.setSize(300, 200);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosed(WindowEvent e) {
                latch.countDown();
            }
        });
    });

    latch.await();
    System.out.println("Main thread released");
}
于 2021-11-13T00:33:37.967 回答
-3

您可以使用循环(最好是 do-while 循环)来暂停一个框架,直到另一个框架关闭或隐藏。确保在处理或隐藏另一帧时中断循环或将用于循环的变量增加特定量。这样你就可以让你的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在该类中创建了 a 并将相应的字段设置为private.

于 2014-11-15T04:26:57.033 回答