首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 1.4 焦點子系統重構:FocusTraversalPolicy 深度解析與自定義實戰

     編輯:Java 相關知識

焦點管理演進史

早期 Java 依賴本地窗口管理器處理焦點,導致跨平台不一致。Java 1.4 (Merlin) 引入全新 AWT 級焦點子系統,核心是集中式 KeyboardFocusManager,統一管理活動窗口、焦點擁有者及遍歷策略,雖帶來不兼容風險,但解決了長期困擾開發者的平台差異問題。

FocusTraversalPolicy 核心架構

這是一個抽象類而非接口,控制焦點循環根內的遍歷順序。焦點循環根(focusCycleRoot=true 的容器)將焦點限制在內部組件循環中。默認窗口/框架為根,其他容器需顯式設置。

六大核心方法

方法用途抽象性
getDefaultComponent(Container)根獲取焦點時的默認組件(向下循環入口)抽象
getInitialComponent(Window)窗口首次顯示時的初始焦點組件具體(默認調用 getDefaultComponent)
getComponentBefore(Container, Component)Shift+Tab 反向遍歷抽象
getComponentAfter(Container, Component)Tab 正向遍歷抽象
getFirstComponent(Container)循環起始組件抽象
getLastComponent(Container)循環終止組件抽象

五大內建策略

  • ContainerOrderFocusTraversalPolicy:按組件添加順序(getComponents() 數組)
  • DefaultFocusTraversalPolicy:依賴 AWT 對等組件可聚焦性(平台相關)
  • InternalFrameFocusTraversalPolicy:專為 JInternalFrame 設計
  • SortingFocusTraversalPolicy:通過 Comparator 自定義排序邏輯
  • LayoutFocusTraversalPolicy:繼承 Sorting,按幾何位置(大小、座標、方向)排序

另有非公共的 LegacyGlueFocusTraversalPolicy 兼容舊版 setNextFocusableComponent()。

實戰:自定義順時針遍歷策略

import java.awt.*;
import javax.swing.*;
import java.util.Arrays;
import java.util.List;

public class BorderFocusDemo {
    public static void main(String[] args) {
        JFrame frame = new JFrame("焦點循環演示");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container cp = frame.getContentPane();
        
        // BorderLayout 五大區域按鈕
        JButton north = new JButton("North");
        JButton south = new JButton("South");
        JButton east = new JButton("East");
        JButton west = new JButton("West");
        JButton center = new JButton("Center");
        
        cp.add(north, BorderLayout.NORTH);
        cp.add(south, BorderLayout.SOUTH);
        cp.add(east, BorderLayout.EAST);
        cp.add(west, BorderLayout.WEST);
        cp.add(center, BorderLayout.CENTER);
        cp.setFocusable(false);  // 容器自身不可聚焦
        
        // 定義遍歷順序:北 → 東 → 南 → 西 → 中
        final Component[] order = {north, east, south, west, center};
        
        FocusTraversalPolicy policy = new FocusTraversalPolicy() {
            List list = Arrays.asList(order);
            
            public Component getFirstComponent(Container root) { return order[0]; }
            public Component getLastComponent(Container root) { return order[order.length - 1]; }
            
            public Component getComponentAfter(Container root, Component comp) {
                int idx = list.indexOf(comp);
                return order[(idx + 1) % order.length];
            }
            
            public Component getComponentBefore(Container root, Component comp) {
                int idx = list.indexOf(comp);
                return order[(idx - 1 + order.length) % order.length];
            }
            
            public Component getDefaultComponent(Container root) { return order[0]; }
        };
        
        frame.setFocusTraversalPolicy(policy);
        frame.pack();
        frame.setVisible(true);
    }
}

關鍵遷移提示

  • 舊代碼使用 requestFocus() 應改為 requestFocusInWindow()
  • 焦點遍歷鍵(Tab/Shift+Tab)可通過 setFocusTraversalKeys() 自定義
  • 閱讀官方 Focus Specification 了解完整規範
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved