【问题标题】:Getting the Component which has Focus in java在java中获取具有焦点的组件
【发布时间】:2012-07-21 16:23:00
【问题描述】:

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

【问题讨论】:

    标签: java swing


    【解决方案1】:

    您绝对应该按照@Robin 的建议考虑您的设计。通过工厂创建和配置应用程序的所有组件有助于使其对需求更改具有鲁棒性,因为只有一个位置可以更改,而不是分散在整个代码中。

    此外,每个组件都有一个单独的侦听器,使控件靠近发生焦点引起的属性更改的位置,因此不需要在全局侦听器中进行状态处理。

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

    一个快速的代码 sn-p(非常粗略的状态处理:-)

    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);
    

    【讨论】:

      【解决方案2】:

      我不想为所有组件编写 FocusListener

      所以你不想替换你的

      JTextField textField = new JTextField();
      

      JTextField textField = TextFieldFactory.createTextField();
      

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

      【讨论】:

        【解决方案3】:

        另一种方法是编写自己的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"));
                }
        
            }
        
        }
        

        【讨论】:

          【解决方案4】:

          您可以将ProperyChangeListener 附加到KeyboardFocusManager @ 监控适当的更改

          【讨论】:

          • 尚未回答的问题;),此外,应该始终欢迎不同的观点:P
          • afaics, ehhh .. 你只是简单地重复了我的回答 ;-)
          • @kleopatra 啊,我明白了,opps,对不起 :( 见 kleopatra 的帖子,有更多细节!!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-31
          • 1970-01-01
          相关资源
          最近更新 更多