在java中获取具有Focus的Component

时间:2012-07-23 12:20:38

标签: java swing

我有JFrame,上面有多个面板。每个专家组都有一些基于此设计的组件。我想在获得焦点时更改组件的背景颜色(JTextField)。 我有很多TextFields,我不想为所有组件编写FocusListener。 是否有任何解决方案以智能方式完成。

4 个答案:

答案 0 :(得分:9)

你应该按照@Robin的建议来考虑你的设计。通过工厂创建和配置应用程序的所有组件有助于使其能够抵御需求更改,因为只需要更改一个位置而不是分散在整个代码中。

此外,每个组件的单个侦听器将控件保持在焦点引发属性发生变化的位置附近,因此不需要在全局侦听器中进行状态处理。

也就是说,全局focusListener的技术(如:小心使用!)解决方案是使用KeyboardFocusManager注册propertyChangeListener。

快速代码段(具有非常粗略的状态处理: - )

JComponent comp = new JPanel();
for (int i = 0; i < 10; i++) {
    comp.add(new JTextField(5));
}
PropertyChangeListener l = new PropertyChangeListener() {
    Component owner;
    Color background;
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        if (owner != null && evt.getOldValue() == owner) {
            owner.setBackground(background);
            owner = null;
        } 
        if (evt.getNewValue() != null) {
            owner = (Component) evt.getNewValue();
            background = owner.getBackground();
            owner.setBackground(Color.YELLOW);
        }
    }
};
KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener("permanentFocusOwner", l);

答案 1 :(得分:6)

  

我不想为所有组件编写FocusListener

所以你不想替换你的

JTextField textField = new JTextField();

通过

JTextField textField = TextFieldFactory.createTextField();

其中TextFieldFactory#createTextField是一种实用程序方法,可以创建具有所需功能的JTextField。要详细说明一下吗?

答案 2 :(得分:2)

另一种方法是编写自己的TextFieldUI来实现监听器。然而,工厂方法更优雅。

示例:

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalTextFieldUI;

public class CustomUI extends JFrame {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                UIManager.getDefaults().put("TextFieldUI", CustomTextFieldUI.class.getName());
                new CustomUI().setVisible(true);
            }

        });
    }

    public CustomUI() {
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLayout(new FlowLayout());
        add(new JTextField(10));
        add(new JTextField(10));
        pack();
    }

    public static class CustomTextFieldUI extends MetalTextFieldUI implements FocusListener {

        public static ComponentUI createUI(JComponent c) {
            return new CustomTextFieldUI();
        }

        @Override
        public void installUI(JComponent c) {
            super.installUI(c);
            c.addFocusListener(this);
        }

        public void focusGained(FocusEvent e) {
            getComponent().setBackground(Color.YELLOW.brighter());
        }

        public void focusLost(FocusEvent e) {
            getComponent().setBackground(UIManager.getColor("TextField.background"));
        }

    }

}

答案 3 :(得分:1)

您可以将ProperyChangeListener附加到KeyboardFocusManager @监控相应的更改