使JSpinner在聚焦时选择文本 [英] Make JSpinner Select Text When Focused

查看:139
本文介绍了使JSpinner在聚焦时选择文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想更改JSpinner的行为,以便在单击文本时选择它。这样可以更轻松地使用所需的值替换字段。不幸的是,我无法让行为起作用,相反,它只是将光标插入文本而不选择已经存在的内容。

I would like to change the behavior of a JSpinner so that when you click on the text, it selects it. This makes it easier to replace the field with the value that you want. Unfortunately, I can't get the behavior to work and instead, it just inserts the cursor in the text without selecting what is already there.

我尝试添加焦点通过((DefaultEditor)this.getEditor())。getTextField()监听JSpinner本身和文本区域本身,但这些似乎都没有影响。我的代码(对于JSpinner本身)如下:

I have tried adding a focus Listener to both the JSpinner itself and the text area itself, via ((DefaultEditor) this.getEditor()).getTextField(), yet neither of these seem to have the intended effect. My code (for the JSpinner itself) is as follows:

spinner.addFocusListener(new FocusAdapter(){
            @Override
            public void focusGained(FocusEvent e) {
                ((DefaultEditor) ((JSpinner) e.getSource()).getEditor()).getTextField().selectAll();
            }
        }); 

我不确定是什么问题。如果重要的话,我正在运行Mac OS 10.7.5和Java 6u43。

I'm not sure what the problem is. If it matters, I'm running Mac OS 10.7.5 and Java 6u43.

编辑:我放了一个 System.out.println 就在focusGained方法的开头,发现它从未被调用过。所以看起来焦点在于JSpinner没有注册。同样,我尝试将focusAdpater放在微调器和文本字段上(但不是同时)。

I put a System.out.println right at the beginning of the focusGained method and discovered that it was never called. So it looks like getting focus on the JSpinner isn't registering. Again, I tried putting the focusAdpater both on the spinner and on the text field (not at the same time though).

推荐答案

您遇到的大部分问题都与微调器在焦点事件(以及其他几个状态事件)之后验证旋转器中的任何值有关,这将绕过突出显示。

Much of the problem you are facing has to do with how the spinner validates any values within the spinner AFTER a focus event (and several other state events), which will circumvent the highlight.

MacOS更糟糕。

我最后做的是开始一个线程等待一个非常短时间段(约25毫秒),然后使用 SwingUtilities.invokeLater 来实际执行选择......

What I ended up doing was starting a Thread that waited a very short time period (around 25 milliseconds) and then used SwingUtilities.invokeLater to actually perform the selection...

更新了示例

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.JTextComponent;

public class AutoFocusSpinner {

    public static void main(String[] args) {
        new AutoFocusSpinner();
    }

    public static final SelectOnFocusGainedHandler SHARED_INSTANCE = new SelectOnFocusGainedHandler();

    public AutoFocusSpinner() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                JSpinner spinner = new JSpinner(new SpinnerNumberModel(1, 0, 100, 1));
                installFocusListener(spinner);

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(spinner);
                frame.add(new JButton("Here for testing"));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public void installFocusListener(JSpinner spinner) {

        JComponent spinnerEditor = spinner.getEditor();

        if (spinnerEditor != null) {

            // This is me spending a few days trying to make this work and 
            // eventually throwing a hissy fit and just grabbing all the 
            // JTextComponent components contained within the editor....
            List<JTextComponent> lstChildren = findAllChildren(spinner, JTextComponent.class);
            if (lstChildren != null && lstChildren.size() > 0) {

                JTextComponent editor = lstChildren.get(0);
                editor.addFocusListener(SHARED_INSTANCE);

            }

        }

    }

    public static <T extends Component> List<T> findAllChildren(JComponent component, Class<T> clazz) {

        List<T> lstChildren = new ArrayList<T>(5);
        for (Component comp : component.getComponents()) {

            if (clazz.isInstance(comp)) {

                lstChildren.add((T) comp);

            } else if (comp instanceof JComponent) {

                lstChildren.addAll(findAllChildren((JComponent) comp, clazz));

            }

        }

        return Collections.unmodifiableList(lstChildren);

    }

    public static class SelectOnFocusGainedHandler extends FocusAdapter {

        @Override
        public void focusGained(FocusEvent e) {

            Component comp = e.getComponent();
            if (comp instanceof JTextComponent) {
                final JTextComponent textComponent = (JTextComponent) comp;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(25);
                        } catch (InterruptedException ex) {
                        }
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                textComponent.selectAll();
                            }
                        });
                    }
                }).start();
            }            
        }        
    }
}

现在,现在,我正在祈祷一些非常好,简单,无证的财产,我们可以设置,这意味着我们不需要做所有这些:P

Now, right about now, I'm praying for some really nice, simple, undocumented property that we can set that will mean we don't need to do all this :P

这篇关于使JSpinner在聚焦时选择文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆