java - 使JOptionPane消息对话框渲染后消失

标签 java swing

我正在构建一个需要用户输入的简单 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

最佳答案

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

Swing 是一个事件驱动的环境。事件发生,你对其使用react...

循环将在 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);
    }
}

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

关于java - 使JOptionPane消息对话框渲染后消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18931230/

相关文章:

java - 如何修复 Java 中的可调用重叠?

java - 哪个是最好的 Java datepicker..?

java - JPanel 和 JDesktopPane

java - 在 Wicket 6.0 RefreshingView 示例中更新行时出现问题

java - 将 GWT 与 IntelliJ 12 集成的问题

java - Android Facebook 登录弹出对话框

Java,比较3个整数,排列最大,中值和最小

java - 如何插入定时器来处理排序

java - 如何更新 jtable 模型

Java实现ActionListener的问题