2

我有 JFrame,上面有多个面板。每个面板都有一些在此基础上设计的组件。我想在获得焦点时更改组件(JTextField)的背景颜色。我有很多 TextField,我不想为所有组件编写 FocusListener。有没有办法以聪明的方式做到这一点。

4

4 回答 4

10

正如@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);
于 2012-07-23T13:00:37.040 回答
6

我不想为所有组件编写 FocusListener

所以你不想更换你的

JTextField textField = new JTextField();

经过

JTextField textField = TextFieldFactory.createTextField();

whereTextFieldFactory#createTextField是一种实用方法,可以创建JTextField具有所需功能的 a。想详细说明一下吗?

于 2012-07-23T12:23:56.900 回答
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"));
        }

    }

}
于 2012-07-23T13:10:04.787 回答
1

您可以将 a 附加ProperyChangeListenerKeyboardFocusManager @ 监视适当的更改

于 2012-07-23T14:42:28.857 回答