FocusListener & JOptionPane
FocusListener & JOptionPane
这是我的简单程序的代码。
有四个文本字段。
当光标位于第一个 textField JOptionPane 时,当我按确定时
光标移动到下一个字段并再次创建 OptionPane
等等
当光标位于第四个字段并且我在 OptionPane 上单击“确定”时,光标移动到第五个字段 "f"。
当光标在字段中时,我打印字段在数组中的位置:System.out.println("first or Second or Third or Fourth")
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Hello extends JFrame implements ActionListener, FocusListener {
public JTextField[] fields = new JTextField[4];
public JPanel panel = new JPanel();
public JTextField f = new JTextField(12);
public static void main(String[] args) {
new Hello();
}
public Hello() {
for (int i = 0; i < 4; i++) {
fields[i] = new JTextField(12);
fields[i].addFocusListener(this);
panel.add(fields[i]);
}
add(panel);
add(f);
setTitle("Hello World");
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(920, 420);
setLocation(100, 100);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ae) {
}
@Override
public void focusGained(FocusEvent fe) {
if (fe.getSource() == fields[0]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[1].requestFocus();
System.out.println("FIRST");
} else if (fe.getSource() == fields[1]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[2].requestFocus();
System.out.println("SECOND");
} else if (fe.getSource() == fields[2]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[3].requestFocus();
System.out.println("THIRD");
} else if (fe.getSource() == fields[3]) {
JOptionPane.showMessageDialog(null, "HELLO");
f.requestFocus();
System.out.println("FOURTH")
}
}
@Override
public void focusLost(FocusEvent fe) {
}
}
当没有OptionPane时,光标从第一个字段向前移动到第四个并打印:
FIRST
SECOND
THIRD
FOURTH
但是当有JOptionPane
输出是:
FIRST
SECOND
FIRST
SECOND
THIRD
SECOND
THIRD
FOURTH
THIRD
FOURTH
FOURTH
可以看到在第二场之后又回到了第一场,
第三场之后回到第二场,而不是去第四场
在第四场之后又回到了第三场。
我想知道为什么?我该如何解决这个问题
问题是每次单击 JOptionPane 上的“确定”时,焦点都会返回到显示 JOptionPane 之前最后一个活动的 JTextField,因此新的 requestFocus 事件会添加到该控件的事件队列中。实际上,当您在执行代码时第一次单击“确定”后,会触发几个对话框,您只是看不到它,因为您每次都显示相同的文本 (HELLO)。我已经更改了您的代码以使其工作。希望对您有所帮助!
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class testOptionPane extends JFrame implements ActionListener, FocusListener {
public ArrayList<JTextField> fields = new ArrayList<>();
public JPanel panel = new JPanel();
public JTextField f = new JTextField(12);
private int currentField = 0;
private boolean focusReturned = false;
public static void main(String[] args) {
new testOptionPane();
}
public testOptionPane() {
for (int i = 0; i < 4; i++) {
JTextField tf = new JTextField(12);
fields.add(tf);
tf.addFocusListener(this);
panel.add(tf);
}
add(panel);
fields.add(f);
add(f);
setTitle("Hello World");
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(920, 420);
setLocation(100, 100);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ae) {
}
@Override
public void focusGained(FocusEvent fe) {
if (fe.getSource() == fields.get(currentField)) {
if (!focusReturned) {
JOptionPane.showMessageDialog(this, "focus on field " + String.valueOf(currentField));
System.out.println(currentField);
focusReturned = true;
} else {
currentField++;
focusReturned = false;
if (currentField < fields.size()) {
fields.get(currentField).requestFocus();
}
}
}
}
@Override
public void focusLost(FocusEvent fe) {
}
}
这是我的简单程序的代码。 有四个文本字段。 当光标位于第一个 textField JOptionPane 时,当我按确定时 光标移动到下一个字段并再次创建 OptionPane 等等 当光标位于第四个字段并且我在 OptionPane 上单击“确定”时,光标移动到第五个字段 "f"。 当光标在字段中时,我打印字段在数组中的位置:System.out.println("first or Second or Third or Fourth")
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Hello extends JFrame implements ActionListener, FocusListener {
public JTextField[] fields = new JTextField[4];
public JPanel panel = new JPanel();
public JTextField f = new JTextField(12);
public static void main(String[] args) {
new Hello();
}
public Hello() {
for (int i = 0; i < 4; i++) {
fields[i] = new JTextField(12);
fields[i].addFocusListener(this);
panel.add(fields[i]);
}
add(panel);
add(f);
setTitle("Hello World");
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(920, 420);
setLocation(100, 100);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ae) {
}
@Override
public void focusGained(FocusEvent fe) {
if (fe.getSource() == fields[0]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[1].requestFocus();
System.out.println("FIRST");
} else if (fe.getSource() == fields[1]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[2].requestFocus();
System.out.println("SECOND");
} else if (fe.getSource() == fields[2]) {
JOptionPane.showMessageDialog(null, "HELLO");
fields[3].requestFocus();
System.out.println("THIRD");
} else if (fe.getSource() == fields[3]) {
JOptionPane.showMessageDialog(null, "HELLO");
f.requestFocus();
System.out.println("FOURTH")
}
}
@Override
public void focusLost(FocusEvent fe) {
}
}
当没有OptionPane时,光标从第一个字段向前移动到第四个并打印:
FIRST
SECOND
THIRD
FOURTH
但是当有JOptionPane 输出是:
FIRST
SECOND
FIRST
SECOND
THIRD
SECOND
THIRD
FOURTH
THIRD
FOURTH
FOURTH
可以看到在第二场之后又回到了第一场, 第三场之后回到第二场,而不是去第四场 在第四场之后又回到了第三场。
我想知道为什么?我该如何解决这个问题
问题是每次单击 JOptionPane 上的“确定”时,焦点都会返回到显示 JOptionPane 之前最后一个活动的 JTextField,因此新的 requestFocus 事件会添加到该控件的事件队列中。实际上,当您在执行代码时第一次单击“确定”后,会触发几个对话框,您只是看不到它,因为您每次都显示相同的文本 (HELLO)。我已经更改了您的代码以使其工作。希望对您有所帮助!
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class testOptionPane extends JFrame implements ActionListener, FocusListener {
public ArrayList<JTextField> fields = new ArrayList<>();
public JPanel panel = new JPanel();
public JTextField f = new JTextField(12);
private int currentField = 0;
private boolean focusReturned = false;
public static void main(String[] args) {
new testOptionPane();
}
public testOptionPane() {
for (int i = 0; i < 4; i++) {
JTextField tf = new JTextField(12);
fields.add(tf);
tf.addFocusListener(this);
panel.add(tf);
}
add(panel);
fields.add(f);
add(f);
setTitle("Hello World");
getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(920, 420);
setLocation(100, 100);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent ae) {
}
@Override
public void focusGained(FocusEvent fe) {
if (fe.getSource() == fields.get(currentField)) {
if (!focusReturned) {
JOptionPane.showMessageDialog(this, "focus on field " + String.valueOf(currentField));
System.out.println(currentField);
focusReturned = true;
} else {
currentField++;
focusReturned = false;
if (currentField < fields.size()) {
fields.get(currentField).requestFocus();
}
}
}
}
@Override
public void focusLost(FocusEvent fe) {
}
}