Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本中引入的改进,并且可能使用不再可用的技术。
请参阅Java语言更改以获取Java SE 9及后续版本中更新的语言特性摘要。
请参阅JDK发行说明,了解所有JDK版本的新功能、增强功能以及已删除或已弃用选项的信息。
焦点事件是在组件获得或失去键盘焦点时触发的。这是无论焦点的改变是通过鼠标、键盘还是编程方式进行的。要了解基本的焦点概念或获取关于焦点的详细信息,请参阅如何使用焦点子系统。
本节将解释如何通过在特定组件上注册FocusListener实例来获取焦点事件。要仅获取窗口的焦点,请实现WindowFocusListener实例。要获取多个组件的焦点状态,请考虑在KeyboardFocusManager类上实现PropertyChangeListener实例,如跟踪多个组件的焦点变化中所述,在如何使用焦点子系统中。
以下示例演示了焦点事件。窗口显示了各种组件。在每个组件上注册的焦点侦听器报告每个获得焦点和失去焦点的事件。对于每个事件,焦点改变的另一个组件,即“对方组件”,也会报告出来。例如,当焦点从按钮切换到文本字段时,按钮会触发焦点失去事件(对方组件为文本字段),然后文本字段会触发焦点获得事件(对方组件为按钮)。焦点失去和焦点获得事件都可以是临时的。例如,当窗口失去焦点时,会发生临时的焦点失去事件。弹出菜单会发生临时的焦点获得事件。

setRequestFocusEnabled(false)使文本区域无法点击。setRequestFocusEnabled(false)来禁用了点击获得焦点的功能,但仍保留了通过Tab键获得焦点的能力。演示还可以使用setFocusable(false)来真正将文本区域从焦点循环中移除,但这将导致那些使用辅助技术的用户无法使用该组件。这个演示的完整代码在 FocusEventDemo.java 文件中。以下代码片段代表了焦点事件处理机制:
public class FocusEventDemo ... implements FocusListener ... {
public FocusEventDemo() {
...
JTextField textField = new JTextField("A TextField");
textField.addFocusListener(this);
...
JLabel label = new JLabel("A Label");
label.addFocusListener(this);
...
JComboBox comboBox = new JComboBox(vector);
comboBox.addFocusListener(this);
...
JButton button = new JButton("A Button");
button.addFocusListener(this);
...
JList list = new JList(listVector);
list.setSelectedIndex(1); //如果选中一个项目,更容易看到焦点的变化
//list.addFocusListener(this);
JScrollPane listScrollPane = new JScrollPane(list);
...
//设置报告焦点获得和焦点丢失事件的区域。
display = new JTextArea();
display.setEditable(false);
//方法setRequestFocusEnabled可以防止
//组件被点击,但仍然可以通过键盘获得焦点 - 这确保了
//用户可访问性。
display.setRequestFocusEnabled(false);
display.addFocusListener(this);
JScrollPane displayScrollPane = new JScrollPane(display);
...
}
...
public void focusGained(FocusEvent e) {
displayMessage("获得焦点", e);
}
public void focusLost(FocusEvent e) {
displayMessage("失去焦点", e);
}
void displayMessage(String prefix, FocusEvent e) {
display.append(prefix
+ (e.isTemporary() ? " (临时):" : ":")
+ e.getComponent().getClass().getName()
+ "; 对应组件: "
+ (e.getOppositeComponent() != null ?
e.getOppositeComponent().getClass().getName() : "null")
+ newline);
}
...
}
相应的适配器类是 FocusAdapter。
| 方法 | 用途 |
|---|---|
| focusGained(FocusEvent) | 在监听的组件获得焦点后调用。 |
| focusLost(FocusEvent) | 在监听的组件失去焦点后调用。 |
| 方法 | 目的 |
|---|---|
| boolean isTemporary() | 如果焦点失去或获得事件是临时的,则返回true。 |
| Component getComponent() (在 java.awt.event.ComponentEvent 中) |
返回触发焦点事件的组件。 |
| Component getOppositeComponent() | 返回与焦点更改相关的另一个组件。对于FOCUS_GAINED事件,这是失去焦点的组件。对于FOCUS_LOST事件,这是获得焦点的组件。如果焦点更改涉及本机应用程序、不同VM或上下文的Java应用程序,或者没有其他组件,则返回null。 |
以下表格列出了使用焦点监听器的示例。
| 示例 | 描述位置 | 备注 |
|---|---|---|
FocusEventDemo |
本节 | 报告在几个组件上发生的所有焦点事件,以演示焦点事件触发的情况。 |
TrackFocusDemo |
使用焦点子系统 | 自定义组件Picture通过实现焦点监听器,在组件周围绘制红色边框。 |