使 JOptionPane 消息对话框在渲染后消失

Posted

技术标签:

【中文标题】使 JOptionPane 消息对话框在渲染后消失【英文标题】:Make JOptionPane message dialog box dissappear after rendering 【发布时间】:2013-09-21 09:52:19 【问题描述】:

我正在构建一个需要用户输入的简单 JFrame GUI。如果用户单击提交按钮,它会检查输入,然后呈现一条 JOptionPane 消息,告诉用户完全填写表单,或者告诉用户表单已提交并关闭程序。问题是,如果用户留下空白字段,则消息对话框会呈现,并且仅在您尝试关闭它时才会增加循环计数,并且不允许用户返回 JFrame 以将输入应用于表单。

import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.JOptionPane;
import java.awt.*;
import java.util.Scanner.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 *
 * @author joel.ramsey
 */
public class JRStarPhase5 extends JFrame

    public static void main (String [] args) throws IOException 

    JFrame window = new JRStarPhase5();

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.setVisible(true);

    //end main method
    private boolean validationError;
    private final JTextField fNameInput;
    private final JTextField miInput;
    private final JTextField lNameInput;
    private final JTextField productChoiceInput;
    private final JTextField licenseQuantityInput;
    private final JTextField streetAddressInput;
    private final JTextField cityInput;
    private final JTextField stateInput;
    private final JTextField zipInput;
    private final JTextField phoneInput;


    //constructor for JFrame
    public JRStarPhase5()
        setTitle("JRStar Star Gaze Order Processing");
        setSize (800,800);  
        Container pane = getContentPane();
        GridLayout grid = new GridLayout(0,2);
        pane.setLayout(grid);

        JLabel fNameLabel = new JLabel ("First name:");
        JLabel mi = new JLabel ("Middle initial:");
        JLabel lNameLabel = new JLabel ("Last name:");
        JLabel productChoice = new JLabel ("Star Gaze version:");
        JLabel licenseQuantity = new JLabel ("License quantity:");
        JLabel streetAddress = new JLabel ("Street address:");
        JLabel city = new JLabel ("City:");
        JLabel state = new JLabel ("State abbrev:");
        JLabel zip = new JLabel ("Zip code:");
        JLabel phone = new JLabel ("Phone Number:");
        this.fNameInput = new JTextField(15);
        this.miInput = new JTextField (1);
        this.lNameInput = new JTextField (15);
        this.productChoiceInput = new JTextField (1);
        this.licenseQuantityInput = new JTextField (2);
        this.streetAddressInput = new JTextField (20);
        this.cityInput = new JTextField (20);
        this.stateInput = new JTextField (2);
        this.zipInput = new JTextField (5);
        this.phoneInput = new JTextField (10);

        //add as last buttons
        JButton submit = new JButton("Submit");
        SubmitButtonHandler sbh = new SubmitButtonHandler();
        submit.addActionListener(sbh);

        JButton clear = new JButton("Clear");
        ClearButtonHandler cbh = new ClearButtonHandler();
        clear.addActionListener(cbh);

        pane.add(fNameLabel);
        pane.add(fNameInput);
        pane.add(mi);
        pane.add(miInput);
        pane.add(lNameLabel);
        pane.add(lNameInput);
        pane.add(productChoice);
        pane.add(productChoiceInput);
        pane.add(licenseQuantity);
        pane.add(licenseQuantityInput);
        pane.add(streetAddress);
        pane.add(streetAddressInput);
        pane.add(city);
        pane.add(cityInput);
        pane.add(state);
        pane.add(stateInput);
        pane.add(zip);
        pane.add(zipInput);
        pane.add(phone);
        pane.add(phoneInput);

        //add last
        pane.add(submit);
        pane.add(clear);

    //end constructor

    private class SubmitButtonHandler implements ActionListener


        public void actionPerformed(ActionEvent e)

            validationError = (fNameInput.getText().equals("")||  
            miInput.getText().equals("")||
            lNameInput.getText().equals("")||
            streetAddressInput.getText().equals("")||
            cityInput.getText().equals("")||
            stateInput.getText().equals("")||
            zipInput.getText().equals("")||
            phoneInput.getText().equals(""));

            for (int n=1; n<3; n++)

            if (validationError)

                if (n == 3)
                    System.exit(0);
                

            JOptionPane.showMessageDialog(null,"Please complete each field within the order form.");

            

            else break;

            

            if (validationError = false)

                JOptionPane.showMessageDialog(null,"Your order has been submitted!");
                System.exit(0); 
        

    //end submit

    private class ClearButtonHandler implements ActionListener

        public void actionPerformed(ActionEvent e)

            fNameInput.setText("");  
            miInput.setText("");
            lNameInput.setText("");
            productChoiceInput.setText("");
            licenseQuantityInput.setText("");
            streetAddressInput.setText("");
            cityInput.setText("");
            stateInput.setText("");
            zipInput.setText("");
            phoneInput.setText("");
        

    //end clear

//end main class

【问题讨论】:

【参考方案1】:

老实说,我不知道您还期望什么(无意冒犯)。

Swing 是一个事件驱动的环境。一个事件发生了,你对它做出反应……

循环将在 EDT 的上下文中开始执行,这意味着用户实际上无法关闭对话框、更正错误并尝试重新提交。

即使是这样,循环也不允许重新评估 validationError 变量的任何机会,这意味着它将始终是它最初在方法中设置的值(假设 true 为现在)...

for (int n = 1; n < 3; n++) 
    if (validationError) 
        if (n == 3) 
            System.exit(0);
        
        JOptionPane.showMessageDialog(null, "Please complete each field within the order form.");
     else 
        break;
    


if (validationError = false) 
    JOptionPane.showMessageDialog(null, "Your order has been submitted!");

System.exit(0);

所以基本上你有一个死亡陷阱,根本没有办法逃脱......

让我们采取另一种方法。我们可以创建一个软循环,而不是使用像forwhile 这样的硬循环,因此,每次执行该方法并且表单无效时,我们都会更新一个计数器,直到该计数器用完为止。 .

// How many times retries has the user used...
private int retries = 0;

/*...*/

public void actionPerformed(ActionEvent e) 

    validationError = (fNameInput.getText().equals("")
            || miInput.getText().equals("")
            || lNameInput.getText().equals("")
            || streetAddressInput.getText().equals("")
            || cityInput.getText().equals("")
            || stateInput.getText().equals("")
            || zipInput.getText().equals("")
            || phoneInput.getText().equals(""));

    if (validationError) 
        retries++;
        if (retries < 3) 
            JOptionPane.showMessageDialog(this, "Please complete each field within the order form.");
         else 
            JOptionPane.showMessageDialog(this, "You've used up all your tries...");
            System.exit(0);
        
     else 
        JOptionPane.showMessageDialog(this, "Your order has been submitted!");
        System.exit(0);
    

您可能还想阅读How to use the focus subsystem 教程中的Validating Input...

【讨论】:

以上是关于使 JOptionPane 消息对话框在渲染后消失的主要内容,如果未能解决你的问题,请参考以下文章

JFrame 使应用程序在关闭后仍保持运行

JOptionPane的经常使用4种对话框

调整具有固定宽度的长句的对话框消息(JOptionPane)

如何使 JOptionPane.showConfirmDialog 默认没有选中?

没有按钮的 JOptionPane

JOptionPane 中的文本换行?