看一下如图所T示的对话框,可以用来获得用户名和用户密码以便连接某些在线服务。
public void setUser(User u)
{
username.setText(u.getName());
}
一旦设置了默认值(如果需要 ),就可以调用setVisible(true)让对话框显示在屏幕上。
然后用户输入信息,点击0K或者Cancel按钮。这两个按钮的事件处理器都会调用 setVisible(false)终止对setVisible(true)的调用另外,用户也可以选择关闭对话框。如果没有为对话框安装窗口监听器,就会执行默认的窗口结束操作,即对话框变为不可见,这也中止广对setVisible(true)的调用。
重要的问题是在用户解除这个对话框之前,一直调用setVisible(true) 阻塞。这样易于实现模式对话框。
希望知道用户是接收对话框,还是取消对话框。示例代码中设置了〇K标志,在对话框显示之前是false。只有0K按钮的事件处理器可以将它设为true。这样,就可以获得对话框中的用户输入。
示例程序中还包含另外一个很有用的改进。在构造一个JDialog对象时,需耍指定拥有者框架。但是,在很多情况下,一个对话框可能会有多个拥有者框架,所以最好在准备显示对话框时再确定拥有者框架,而不是在构造PasswordChooser对象时。
有一个技巧是让PasswordChooser扩展JPanel,而不是扩展JDialog,在showDialog方法中动态建立JDialog对象:
public boolean showOialog(Frame owner, String title)
{
ok = false;
if (dialog == null || dialog.getOwner() != owner)
{
dialog = new JDialog(owner, true);
dialog.add (this);
di alog.pack();
}
dialog.setTitle(title);
dialog.setVisible(true);
return ok;
}
注意,让owner等于nul]是安全的。
可以再做进一少的改进有时,拥有者框架并不总是可用的。利用任意的parent组件可以很容易地得到它。如下所示:
Frame owner;
if (parent instanceof Frame)
owner = (Frame) parent;
else
oviner = (Frame) SwingUtilities.getAncestorOfClass(Fraiie.class, parent);
在示例程序中使用了改进的代码JOptionPane类也使j用了上面的机制。
很多对活框都有默认按钮。如果用按下—个触发器键(從大多数“观感”实现中是 ENTKR)就自动地选择了它。默认按钮通常用加粗的轮廓给予特别的标识/
可以在对话框的根窗格(mot pane)中设置默认按钮:
dialog.getRootPane().setOefaultButton(okButton);
如果按照前面的建议,在一个面板中布局对话框就必须特別小心在包装面板进人对话框后再设置默认按钮。面板本身没有根窗格。
下面是示例程序:
DateExhangeframe.java文件
package DataExchange; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Created by IBM on 2017/10/9. */ public class DateExchangeframe extends JFrame { public static final int TEXT_ROWS=20; public static final int TEXT_COLUMNS=20; private PasswordChooser dialog=null; private JTextArea textArea; public static void main(String[]args){ DateExchangeframe buttonFrame=new DateExchangeframe(); buttonFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); buttonFrame.setVisible(true); } public DateExchangeframe(){ JMenuBar mbar=new JMenuBar(); setJMenuBar(mbar); JMenu fileMenu=new JMenu("File"); mbar.add(fileMenu); JMenuItem connecItem=new JMenuItem("Connect"); connecItem.addActionListener(new ConnectAction()); fileMenu.add(connecItem); JMenuItem exitItem=new JMenuItem("Exit"); exitItem.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); fileMenu.add(exitItem); textArea=new JTextArea(TEXT_ROWS,TEXT_COLUMNS); add(new JScrollPane(textArea), BorderLayout.CENTER); pack(); } private class ConnectAction implements ActionListener{ public void actionPerformed(ActionEvent event){ if(dialog==null)dialog=new PasswordChooser(); dialog.setUser(new User("yourname",null)); if(dialog.showDialog(DateExchangeframe.this,"Connect")){ User u=dialog.getUser(); textArea.append("user name="+u.getName()+",password="+(new String(u.getPassword()))+"\n"); } } } }PasswordChooser.java文件
package DataExchange; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Created by IBM on 2017/10/9. */ public class PasswordChooser extends JPanel { private JTextField username; private JPasswordField password; private JButton okbutton; private boolean ok; private JDialog dialog; public PasswordChooser() { setLayout(new BorderLayout()); JPanel panel = new JPanel(); panel.setLayout(new GridLayout(2, 2)); panel.add(new JLabel("User name:")); panel.add(username = new JTextField("")); panel.add(new JLabel("Password:")); panel.add(password = new JPasswordField("")); add(panel, BorderLayout.CENTER); okbutton = new JButton("OK"); okbutton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { ok = true; dialog.setVisible(false); } }); JButton cancelButton = new JButton("Cancel"); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dialog.setVisible(false); } }); JPanel buttonPanel = new JPanel(); buttonPanel.add(okbutton); buttonPanel.add(cancelButton); add(buttonPanel, BorderLayout.SOUTH); } /** * set the dialog defaults */ public void setUser(User u) { username.setText(u.getName()); } public User getUser(){ return new User(username.getText(),password.getPassword()); } public boolean showDialog(Component parent,String title){ ok=false; Frame owner=null; if(parent instanceof Frame)owner=(Frame)parent; else owner=(Frame)SwingUtilities.getAncestorOfClass(Frame.class,parent); if(dialog==null||dialog.getOwner()!=owner){ dialog=new JDialog(owner,true); dialog.add(this); dialog.getRootPane().setDefaultButton(okbutton); dialog.pack(); } dialog.setTitle(title); dialog.setVisible(true); return ok; } } /** * A user has a name and password. For security reasons, the password is stored as a char[], not a * String. */ class User { public User(String aName, char[] aPassword) { name = aName; password = aPassword; } public String getName() { return name; } public char[] getPassword() { return password; } public void setName(String aName) { name = aName; } public void setPassword(char[] aPassword) { password = aPassword; } private String name; private char[] password; }
运行结果:
ContainergetAncestorOfClass(Class c, Component comp)
返回给定组件的最先的父容器。这个组件厲于给定的类或者其子类之一
JRootPane getRootPane()
获得最靠近这个组件的根窗格,如果这个组件的租先没有根窗格返回null
void setDefaultButton(JButton button)
设置根窗格的默认按钮。要想禁用默认按钮,需要将参数设置为null
boolean isDefaultButton()
如果这个按钮是它的根窗格的默认按钮,返冋true