首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Swing:讓 JTextField 自動獲得焦點並鎖定焦點不被 JTextArea 奪取

     編輯:程式設計綜合問答

需求場景

視窗啟動時讓 JTextField 直接獲得輸入焦點(游標閃爍),且使用者點擊同視窗內的 JTextArea 時,焦點自動跳回 JTextField,實現「焦點鎖定」效果。

核心 API

  • Component.requestFocusInWindow():請求焦點,較 requestFocus() 更可靠。
  • Window.addWindowFocusListener / ComponentListener:視窗顯示後再請求焦點,避免視窗未顯示導致失效。
  • MouseListener:攔截 JTextArea 滑鼠點擊並轉移焦點。

完整可執行範例

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class FocusLockDemo {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("焦點鎖定示範");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout(10, 10));
            frame.setSize(400, 300);

            JTextField lockedField = new JTextField(20);
            lockedField.setName("lockedField");

            JTextArea freeArea = new JTextArea(5, 20);
            freeArea.setText("點擊這裡,焦點會跳回上方輸入框");
            freeArea.setLineWrap(true);
            freeArea.setWrapStyleWord(true);

            // 1. 視窗顯示後讓 lockedField 獲得焦點
            frame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowOpened(WindowEvent e) {
                    lockedField.requestFocusInWindow();
                }
            });

            // 2. 攔截 JTextArea 滑鼠點擊,強制焦點回到 lockedField
            freeArea.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    lockedField.requestFocusInWindow();
                }
            });

            frame.add(lockedField, BorderLayout.NORTH);
            frame.add(new JScrollPane(freeArea), BorderLayout.CENTER);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

進階:使用 FocusTraversalPolicy 完全禁用 JTextArea 焦點

若需更徹底禁止 JTextArea 獲得焦點(連 Tab 鍵也不行),可自訂 FocusTraversalPolicy:

frame.setFocusTraversalPolicy(new DefaultFocusTraversalPolicy() {
    @Override
    public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
        return lockedField; // 永遠回到 lockedField
    }
    @Override
    public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
        return lockedField;
    }
    @Override
    public Component getDefaultComponent(Container focusCycleRoot) {
        return lockedField;
    }
});

常見問題排查

現象原因解決
啟動時焦點不在 JTextField在構造元件時呼叫 requestFocus,視窗尚未顯示改用 WindowListener.windowOpened 或 invokeLater 延後執行
點擊 JTextArea 仍能輸入未消費滑鼠事件,焦點轉移後又被 JTextArea 取回在 mousePressed 呼叫 requestFocusInWindow,並可加上 e.consume()
Tab 鍵仍能切換到 JTextArea預設 FocusTraversalPolicy 允許自訂 FocusTraversalPolicy 或設定 freeArea.setFocusable(false)

總結

「啟動自動聚焦 + 滑鼠點擊攔截轉移」是最直觀的焦點鎖定做法;若需完全移除元件的焦點能力,配合 setFocusable(false) 或自訂 FocusTraversalPolicy 效果最佳。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved