如何从自定义 JDialog return cod

How to return cod from custom JDialog

大家好,我是一名业余程序员(12 年级),我正在开发一个程序,通过自定义 JDialog(使用 eclipse WindowBuilder 创建)询问用户的用户名和密码

我遇到的问题是从 "popup" 检索数据,我编写了一个测试程序,但在我输入任何数据之前显示了值。

这是我的代码:

package winowbuilderstuff;
public class TestDialog {

/**
 * @param args
 */
public static void main(String[] args) {
    LoginDialog login = new LoginDialog ();


    login.setVisible(true);

    String username = login.getUser();
    String password = login.getPass();

    System.out.println("Username: " + username);
    System.out.println("Password: " + password);


}

}

package winowbuilderstuff;

import java.awt.BorderLayout;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JPasswordField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class LoginDialog extends JDialog {

private final JPanel contentPanel = new JPanel();
private JTextField txtfUsername;
private JPasswordField pswrdf;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    try {
        LoginDialog dialog = new LoginDialog();
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

/**
 * Create the dialog.
 */
public LoginDialog() {
    setTitle("Login");
    setBounds(100, 100, 478, 150);
    getContentPane().setLayout(new BorderLayout());
    contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
    getContentPane().add(contentPanel, BorderLayout.CENTER);
    contentPanel.setLayout(null);
    {
        JLabel lblUsername = new JLabel("Username");
        lblUsername.setBounds(25, 13, 68, 14);
        contentPanel.add(lblUsername);
    }
    {
        txtfUsername = new JTextField();
        txtfUsername.setToolTipText("Enter your username");
        txtfUsername.setBounds(137, 13, 287, 17);
        contentPanel.add(txtfUsername);
        txtfUsername.setColumns(10);
    }

    JLabel lblPassword = new JLabel("Password");
    lblPassword.setBounds(25, 52, 68, 14);
    contentPanel.add(lblPassword);

    pswrdf = new JPasswordField();
    pswrdf.setToolTipText("Enter your password");
    pswrdf.setBounds(137, 50, 287, 17);
    contentPanel.add(pswrdf);
    {
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
        getContentPane().add(buttonPane, BorderLayout.SOUTH);
        {
            JButton btnLogin = new JButton("Login");
            btnLogin.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    getUser();
                    getPass();
                    dispose();
                }
            });
            btnLogin.setActionCommand("OK");
            buttonPane.add(btnLogin);
            getRootPane().setDefaultButton(btnLogin);
        }
        {
            JButton btnCancel = new JButton("Cancel");
            btnCancel.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {

                    dispose();

                }
            });
            btnCancel.setActionCommand("Cancel");
            buttonPane.add(btnCancel);
        }
    }
}

public String getUser(){
    return txtfUsername.getText();
}

public String getPass(){
    return pswrdf.getText();
}


}
  1. 使您的 JDialog 模式化。这可以通过 super(...) 构造函数调用或简单的方法调用来完成。
  2. 如果您执行上述操作,则对话框将冻结您调用 setVisible(true) 站点上的调用代码,然后 return不再可见。
  3. 因此,在 setVisible(true) 之后立即通过调用 getUser()getPass() 方法来查询对话框对象的用户名和密码。
  4. 一些侧面建议:
    • 避免在 JPasswordField 上调用 getText(),因为那不是安全代码。而是通过 getPassword() 从中获取 char[] 并使用它,因为这 更安全。
    • 您应该避免使用空布局并使用 setBounds(...) 来放置组件,因为这会导致 GUI 非常不灵活,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很糟糕,而且很难更新和维护。

例如,只需进行此更改:

 public LoginDialog() {
     super(null, ModalityType.APPLICATION_MODAL);  // add this line

例如:

import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Window;
import javax.swing.*;

public class TestDialog2 {
   private static void createAndShowGui() {
      int result = MyLoginPanel.showDialog();
      if (result == JOptionPane.OK_OPTION) {
         String userName = MyLoginPanel.getUserName();
         char[] password = MyLoginPanel.getPassword();

         System.out.println("User Name: " + userName);
         System.out.println("Password:  " + new String(password));
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class MyLoginPanel extends JPanel {
   private static MyLoginPanel myLoginPanel = new MyLoginPanel();
   private static JDialog myDialog;
   public static final String RETURN_STATE = "return state";
   private static final int COLUMNS = 20;
   private JTextField userNameField = new JTextField(COLUMNS);
   private JPasswordField passField = new JPasswordField(COLUMNS);
   private int returnState = Integer.MIN_VALUE;

   private MyLoginPanel() {
      setLayout(new GridBagLayout());
      add(new JLabel("User Name:"), createGbc(0, 0, 1));
      add(userNameField, createGbc(1, 0, 2));
      add(new JLabel("Password:"), createGbc(0, 1, 1));
      add(passField, createGbc(1, 1, 2));
      add(new JLabel(""), createGbc(0, 2, 1));

      JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));

      buttonPanel.add(new JButton(new LoginAction("Login")));
      buttonPanel.add(new JButton(new CancelAction("Cancel")));

      add(buttonPanel, createGbc(1, 2, 2));
   }

   private GridBagConstraints createGbc(int x, int y, int width) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = width;
      gbc.gridheight = 1;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      int right = x == 0 ? 15 : 5;
      gbc.insets = new Insets(5, 5, 5, right);
      gbc.anchor = x == 0 ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
      return gbc;
   }

   public void setReturnState(int returnState) {
      this.returnState = returnState;
      firePropertyChange(RETURN_STATE, Integer.MIN_VALUE, returnState);
   }

   public int getReturnState() {
      return returnState;
   }

   private class LoginAction extends AbstractAction {
      public LoginAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         returnState = JOptionPane.OK_OPTION;
         Window win = SwingUtilities.getWindowAncestor(MyLoginPanel.this);
         win.dispose();
      }
   }

   private String _getUserName() {
      return userNameField.getText();
   }

   private char[] _getPassword() {
      return passField.getPassword();
   }

   public static String getUserName() {
      return myLoginPanel._getUserName();
   }

   public static char[] getPassword() {
      return myLoginPanel._getPassword();
   }

   private class CancelAction extends AbstractAction {
      public CancelAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         returnState = JOptionPane.CANCEL_OPTION;
         Window win = SwingUtilities.getWindowAncestor(MyLoginPanel.this);
         win.dispose();
      }
   }

   public static int showDialog() {
      if (myDialog == null) {
         myDialog = new JDialog(null, "Test", ModalityType.APPLICATION_MODAL);
         myDialog.add(myLoginPanel);
         myDialog.pack();
      }
      myDialog.setVisible(true);
      return myLoginPanel.getReturnState();
   }

}

或者更简单,只需使用 JOptionPane 作为模式对话框。您可以轻松地将 JPanel 传递给它。

例如:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TestDialog3 {
   private static void createAndShowGui() {
      MyLoginPanel3 myLoginPanel3 = new MyLoginPanel3();
      int result = JOptionPane.showConfirmDialog(null, myLoginPanel3, "Log On", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
      if (result == JOptionPane.OK_OPTION) {
         String userName = myLoginPanel3.getUserName();
         char[] password = myLoginPanel3.getPassword();

         System.out.println("User Name: " + userName);
         System.out.println("Password:  " + new String(password));
      }
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class MyLoginPanel3 extends JPanel {
   private static final int COLUMNS = 20;
   private JTextField userNameField = new JTextField(COLUMNS);
   private JPasswordField passField = new JPasswordField(COLUMNS);

   public MyLoginPanel3() {
      setLayout(new GridBagLayout());
      add(new JLabel("User Name:"), createGbc(0, 0, 1));
      add(userNameField, createGbc(1, 0, 2));
      add(new JLabel("Password:"), createGbc(0, 1, 1));
      add(passField, createGbc(1, 1, 2));
      add(new JLabel(""), createGbc(0, 2, 1));

   }

   private GridBagConstraints createGbc(int x, int y, int width) {
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.gridx = x;
      gbc.gridy = y;
      gbc.gridwidth = width;
      gbc.gridheight = 1;
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.fill = GridBagConstraints.HORIZONTAL;
      int right = x == 0 ? 15 : 5;
      gbc.insets = new Insets(5, 5, 5, right);
      gbc.anchor = x == 0 ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
      return gbc;
   }


   public String getUserName() {
      return userNameField.getText();
   }

   public char[] getPassword() {
      return passField.getPassword();
   }

}