Make JSpinner Select Text When Focused

前端 未结 2 1395
有刺的猬
有刺的猬 2021-01-12 00:00

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.

相关标签:
2条回答
  • 2021-01-12 00:05

    Don't know about a Mac but I've used this code on Windows:

    JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor)spinner.getEditor();
    JTextField textField = editor.getTextField();
    textField.addFocusListener( new FocusAdapter()
    {
        public void focusGained(final FocusEvent e)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                @Override
                public void run()
                {
                    JTextField tf = (JTextField)e.getSource();
                    tf.selectAll();
                }
            });
    
        }
    
    });
    

    I've also used this code for selecting text on a JFormattedTextField.

    0 讨论(0)
  • 2021-01-12 00:18

    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.

    The MacOS is even worse.

    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...

    Updated with a example

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

    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

    0 讨论(0)
提交回复
热议问题