JFrame问题

时间:2011-05-29 16:53:27

标签: java swing jframe

我正在创建一个弹出式JFrame,它会有一条消息和是/否按钮。我以两种方式使用这种方法。在1中,主程序调用此方法,而在另一个中,此方法在前一个JFrame关闭后直接调用。此方法在从主程序调用时起作用,但当另一个JFrame调用它时,在此方法中创建的JFrame显示为完全空白并且GUI冻结。我不能退出JFrame,但我可以移动它。冻结是Thread.yield的结果,因为响应始终为null,但在什么情况下JFrame无法正确创建?

注意:响应是一个静态变量。此外,当此JFrame由另一个JFrame创建时,原始JFrame无法正确退出。该JFrame具有JComboBox,并且下拉列表中将冻结所选选项。当它不调用此方法时,它会正确关闭。

public static String confirmPropertyPurchase(String message)
    {
        response = null;
        final JFrame confirmFrame = new JFrame("Confirm");
        confirmFrame.addWindowListener(new WindowAdapter(){
            public void windowClosing(WindowEvent ev){
                response = "No";
            }
            public void windowDeactivated(WindowEvent e) {
                confirmFrame.requestFocus();
            }
        });

        final JPanel confirmPanel = new JPanel();
        final JButton yes = new JButton();
        final JButton no = new JButton();
        yes.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                response = "Yes";
                confirmFrame.setVisible(false);
            }
        });
        no.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0){
                response = "No";
                confirmFrame.setVisible(false);
            }
        });

        final JLabel confirmLabel = new JLabel("      " + message);
        yes.setText("Yes");
        yes.setPreferredSize(new Dimension(100, 100));
        no.setText("No");
        no.setPreferredSize(new Dimension(100,100));
        confirmFrame.add(confirmLabel, BorderLayout.CENTER);
        confirmPanel.add(yes);
        confirmPanel.add(no);
        confirmFrame.add(confirmPanel, BorderLayout.AFTER_LAST_LINE);
        confirmFrame.setPreferredSize(new Dimension(520, 175
        ));

        confirmFrame.pack();
        confirmFrame.setVisible(true);

        while(response == null)
        {
            Thread.yield();
        }
        return response;
    }

2 个答案:

答案 0 :(得分:5)

同样,您不应该将JFrame用作对话框。实际上,您的整个代码可以用简单的JOptionPane替换。如,

  Component parent = null;  // non-null if being called by a GUI
  queryString = "Do you want fries with that?";
  int intResponse = JOptionPane.showConfirmDialog(parent, queryString,
           "Confirm", JOptionPane.YES_NO_OPTION);
  myResponse = (intResponse == JOptionPane.YES_OPTION) ? "Yes" : "No";
  System.out.println(myResponse);

而且:

    while(response == null)
    {
        Thread.yield();
    }
永远不应该在主Swing线程,EDT或事件派发线程上调用

。代码工作的原因是因为你在EDT之上调用了这一点,但是当你在EDT上调用它时它冻结了EDT,从而冻结了整个GUI。根本就不要这样做。

答案 1 :(得分:3)

你做不到这一点,简单明了。只有一个事件线程,当你坐在一个循环中等待有人点击你的JFrame时,你就会绑定那个线程,以便不能处理任何事件。

请勿尝试使用JFrame - 使用JOptionPaneJDialog创建自己的对话框,这些对话框旨在为您内部处理此情况。