如果用户按下确认后对话框将消失:
- 如果您希望对话框表现为模态 JDialog,则很容易,因为一旦用户完成处理对话框,您就知道程序在代码中的位置——它将恰好位于您在对话框上调用
setVisible(true)
后的代码行之后。因此,在您在对话框上调用 setVisible(true)
后的代码行中,您只需查询对话框对象的状态即可。
- 如果您需要处理非模态对话框,则需要向对话框添加 WindowListener,以在对话框窗口变为不可见时收到通知。
如果用户按下确认后对话框将保持打开状态:
- 那么您应该使用一个 PropertyChangeListener,如上所建议。或者将对话框对象提供一个公共方法,允许外部类能够将 ActionListener 添加到确认按钮上。
欲了解更多详情,请向我们展示相关代码片段,或者更好的是,一个SSCCE。
例如,要使 JDialog 类接受外部监听器,您可以给它一个 JTextField 和一个 JButton:
class MyDialog extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
并提供一种方法,允许外部类将ActionListener添加到按钮:
public void addConfirmListener(ActionListener listener) {
confirmBtn.addActionListener(listener);
}
此时,外部类只需要调用 `addConfirmListener(...)` 方法将其 ActionListener 添加到 confirmBtn 上。
例如:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OutsideListener extends JFrame {
private JTextField textField = new JTextField(10);
private JButton showDialogBtn = new JButton("Show Dialog");
private MyDialog myDialog = new MyDialog(this, "My Dialog");
public OutsideListener(String title) {
super(title);
textField.setEditable(false);
showDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!myDialog.isVisible()) {
myDialog.setVisible(true);
}
}
});
myDialog.addConfirmListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text = myDialog.getTextFieldText();
textField.setText(text);
}
});
JPanel panel = new JPanel();
panel.add(textField);
panel.add(showDialogBtn);
add(panel);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static void createAndShowGui() {
JFrame frame = new OutsideListener("OutsideListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDialog extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
public MyDialog(JFrame frame, String title) {
super(frame, title, false);
JPanel panel = new JPanel();
panel.add(textfield);
panel.add(confirmBtn);
add(panel);
pack();
setLocationRelativeTo(frame);
}
public String getTextFieldText() {
return textfield.getText();
}
public void addConfirmListener(ActionListener listener) {
confirmBtn.addActionListener(listener);
}
}
注意:我不建议除非绝对必要否则不要子类化JFrame或JDialog。这里为简洁起见而这样做。我个人更喜欢使用模态对话框来解决这个问题,并在需要时重新打开对话框。
编辑2
一个使用模态对话框的示例:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class OutsideListener2 extends JFrame {
private JTextField textField = new JTextField(10);
private JButton showDialogBtn = new JButton("Show Dialog");
private MyDialog2 myDialog = new MyDialog2(this, "My Dialog");
public OutsideListener2(String title) {
super(title);
textField.setEditable(false);
showDialogBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (!myDialog.isVisible()) {
myDialog.setVisible(true);
textField.setText(myDialog.getTextFieldText());
}
}
});
JPanel panel = new JPanel();
panel.add(textField);
panel.add(showDialogBtn);
add(panel);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
private static void createAndShowGui() {
JFrame frame = new OutsideListener2("OutsideListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class MyDialog2 extends JDialog {
private JTextField textfield = new JTextField(10);
private JButton confirmBtn = new JButton("Confirm");
public MyDialog2(JFrame frame, String title) {
super(frame, title, true);
JPanel panel = new JPanel();
panel.add(new JLabel("Please enter a number between 1 and 100:"));
panel.add(textfield);
panel.add(confirmBtn);
add(panel);
pack();
setLocationRelativeTo(frame);
ActionListener confirmListener = new ConfirmListener();
confirmBtn.addActionListener(confirmListener);
textfield.addActionListener(confirmListener );
}
public String getTextFieldText() {
return textfield.getText();
}
private class ConfirmListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String text = textfield.getText();
if (isTextValid(text)) {
MyDialog2.this.setVisible(false);
} else {
String warning = "Data entered, \"" + text +
"\", is invalid. Please enter a number between 1 and 100";
JOptionPane.showMessageDialog(confirmBtn,
warning,
"Invalid Input", JOptionPane.ERROR_MESSAGE);
textfield.setText("");
textfield.requestFocusInWindow();
}
}
}
public boolean isTextValid(String text) {
try {
int number = Integer.parseInt(text);
if (number > 0 && number <= 100) {
return true;
}
} catch (NumberFormatException e) {
}
return false;
}
}
JDialog
类吗?如果可以的话,你可以将ActionEvent
转发到另一个实现了ActionListener
接口的类中,那个类可以执行你想要的操作。 - mreJDialog
实例注册一个PropertyChangeListener
,并让JDialog
实例使用一个PropertyChangeSupport
实例来触发属性更改事件,指示确认按钮已被按下。 - mresetModel()
方法)。顺便说一句,为了更快地获得更好的帮助,请发布一个SSCCE。 - Andrew ThompsonaddISDialog.setLocationRelativeTo(null);
应该 可能 改为addISDialog.setLocationRelativeTo(mainApplication);
。 - Andrew Thompson