gpt4 book ai didi

java - 如何在调度更多事件之前等待 JOptionPane 关闭

转载 作者:行者123 更新时间:2023-11-29 05:58:31 24 4
gpt4 key购买 nike

我有几个文本字段,我在它们之间切换。在 focusLost() 上,我打开了一个 JOptionPane。我希望在 JOptionPane 关闭后执行 focusGained() 中的代码。即使对话框是模态的,focusGained() 也会在 JOptionPane 关闭之前被调用。有没有办法解决?

找到了这个类似的问题,不过好像也没有解决。 Postpone Event Queue after Focus Lost

这是一个代码示例。您会注意到在关闭 JOptionPane 之前打印了“Focus Gained”。

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);
}
}
}

最佳答案

也许您想要的不是焦点监听器(非常低级的结构),而是输入 validator (更高级别的结构)。这应该在焦点转移之前做出响应。例如,在下面的代码中,如果用户试图在文本字段中输入非数字数据, validator 会使用react。是的,这也可以使用 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();
}
});
}
}

编辑:
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();
}
}

顺便说一句,你的 SSCCE 1+!

关于java - 如何在调度更多事件之前等待 JOptionPane 关闭,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11091457/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com