Java 如何等待JOptionPane关闭,然后再发送更多事件
我有两个文本字段,在它们之间切换。在Java 如何等待JOptionPane关闭,然后再发送更多事件,java,swing,overriding,joptionpane,event-dispatch-thread,Java,Swing,Overriding,Joptionpane,Event Dispatch Thread,我有两个文本字段,在它们之间切换。在focusLost()上,我正在打开一个JOptionPane。我希望在关闭JOptionPane后执行focusgound()中的代码。即使对话框是模态的,focusgoven()也会在关闭JOptionPane之前被调用。这有什么办法吗 发现了类似的问题,但似乎也没有解决。 这是一个代码示例。您会注意到,在关闭JOptionPane之前会打印“获得焦点” import java.awt.event.FocusEvent; import java.awt.
focusLost()
上,我正在打开一个JOptionPane
。我希望在关闭JOptionPane
后执行focusgound()
中的代码。即使对话框是模态的,focusgoven()
也会在关闭JOptionPane
之前被调用。这有什么办法吗
发现了类似的问题,但似乎也没有解决。
这是一个代码示例。您会注意到,在关闭JOptionPane之前会打印“获得焦点”
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ShortTest implements FocusListener
{
private void go()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
JTextField text1 = new JTextField();
text1.setName("text1");
text1.addFocusListener(this);
JTextField text2 = new JTextField();
text2.setName("text2");
text2.addFocusListener(this);
panel.add(new JLabel("tex1"));
panel.add(text1);
panel.add(new JLabel("text2"));
panel.add(text2);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String [] args)
{
ShortTest test = new ShortTest();
test.go();
}
@Override
public void focusGained(FocusEvent e)
{
if (!e.isTemporary() && (e.getSource() instanceof JTextField))
{
System.out.println("Focus Gained: " + ((JTextField)e.getSource()).getName());
}
}
@Override
public void focusLost(FocusEvent e)
{
if (!e.isTemporary() && (e.getSource() instanceof JTextField))
{
JOptionPane.showOptionDialog(null, ((JTextField)e.getSource()).getName() + " lost focus", "Title", JOptionPane.DEFAULT_OPTION, 0, null, null, null);
}
}
}
也许您想要的不是焦点侦听器(一个非常低级的构造),而是一个输入验证器(一个更高级的构造)。这应该在焦点转移之前做出反应。例如,在下面的代码中,如果用户试图在文本字段中输入非数字数据,验证器会做出反应。是,这也可以使用DocumentFilter完成
import javax.swing.*;
public class VerifierEg extends JPanel {
private static final int FIELD_COUNT = 3;
public VerifierEg() {
InputVerifier inputVerifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
final JTextField textField = (JTextField) input;
String text = textField.getText();
for (char c : text.toCharArray()) {
if (!Character.isDigit(c)) {
textField.setText("");
JOptionPane.showMessageDialog(VerifierEg.this, "Text: \""
+ text + "\" must hold only digits", "Text Field Error",
JOptionPane.ERROR_MESSAGE);
return false;
}
}
return true;
}
};
for (int i = 0; i < FIELD_COUNT; i++) {
JTextField field = new JTextField(6);
field.setInputVerifier(inputVerifier);
add(field);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Enter Numbers");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new VerifierEg());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
import javax.swing.*;
公共类VerifierEg扩展了JPanel{
私有静态最终整型字段\ u计数=3;
公开核实{
InputVerifier InputVerifier=新的InputVerifier(){
@凌驾
公共布尔验证(JComponent输入){
最终JTextField textField=(JTextField)输入;
String text=textField.getText();
for(char c:text.toCharArray()){
如果(!Character.isDigit(c)){
textField.setText(“”);
JOptionPane.showMessageDialog(验证例如,“文本:\”)
+text+“\”只能包含数字“,”文本字段错误“,
JOptionPane.ERROR\u消息);
返回false;
}
}
返回true;
}
};
对于(int i=0;i
编辑:InputVerifier可以为您的目的工作,即使您没有以任何特定的方式验证输入。例如,要修改代码,请执行以下操作:
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BoxLayout;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ShortTest2 {
private void go() {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
InputVerifier inputVerifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
JOptionPane.showMessageDialog(frame,
"Focus Lost on " + input.getName());
return true;
}
};
FocusListener focusListener = new FocusListener() {
@Override
public void focusLost(FocusEvent e) {
String name = ((JComponent)e.getSource()).getName();
System.out.println("Focus Lost: " + name );
}
@Override
public void focusGained(FocusEvent e) {
String name = ((JComponent)e.getSource()).getName();
System.out.println("Focus Gained: " + name );
}
};
JTextField[] textFields = new JTextField[2];
for (int i = 0; i < textFields.length; i++) {
JTextField textField = new JTextField(10);
String name = "text " + (i + 1);
textField.setName(name);
textField.setInputVerifier(inputVerifier);
textField.addFocusListener(focusListener);
panel.add(new JLabel(name));
panel.add(textField);
}
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
ShortTest2 test = new ShortTest2();
test.go();
}
}
import java.awt.event.FocusEvent;
导入java.awt.event.FocusListener;
导入javax.swing.BoxLayout;
导入javax.swing.InputVerifier;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JOptionPane;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
公共类短测试2{
私人空间{
最终JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel面板=新的JPanel();
panel.setLayout(新的BoxLayout(panel,BoxLayout.Y_轴));
InputVerifier InputVerifier=新的InputVerifier(){
@凌驾
公共布尔验证(JComponent输入){
JOptionPane.showMessageDialog(框架,
“焦点丢失在”+input.getName());
返回true;
}
};
FocusListener FocusListener=新FocusListener(){
@凌驾
公共无效焦点丢失(焦点事件e){
字符串名称=((JComponent)e.getSource()).getName();
System.out.println(“焦点丢失:+name”);
}
@凌驾
获得公共无效焦点(焦点事件e){
字符串名称=((JComponent)e.getSource()).getName();
System.out.println(“获得焦点:+名称);
}
};
JTextField[]textFields=新的JTextField[2];
for(int i=0;i
顺便说一句,为您的SSCCE提供1+服务 请考虑创建并发布一个我们可以运行和修改的,并演示您的问题的。请参阅编辑我的答案。1+用于发布sscce——非常令人印象深刻!谢谢你的帮助和建议。虽然我确实需要在焦点事件(以及鼠标事件和EDT上的其他时间)期间使用JOptionPane,但这可能会帮助其他人。简而言之,FocusGain()和focusLost()都在修改同一个变量,但我不希望FocusGain()在focusLost()返回之前更改它。我最初认为解决方案是确保在输入focusgain()之前返回focusLost,但最终我只是在focusgain()的开头保存了变量的一个副本,并在focusgain()完成时将该副本放回原处。