How to retain selected text in JTextField when focus lost?

后端 未结 1 1762
逝去的感伤
逝去的感伤 2021-01-04 21:27

Now finishing my custom menu popup, but the problem is that if I select some text in JTextField and click mouse button to show popup menu, then focus is transfe

1条回答
  •  不知归路
    2021-01-04 21:46

    then focus is transferred to popup window, AND selected text before are no longer highlighted. When focus is back to JTextField - selected text become highlighted again. How to make the selected text stay highlighted on focus lost?

    • you can to override DefaultCaret for JTextComponents

    • you can to override Highlighter for JTextComponents

    code example from DefaultCaret

    class HighlightCaret extends DefaultCaret {
    
        private static final Highlighter.HighlightPainter unfocusedPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
        private static final Highlighter.HighlightPainter focusedPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
        private static final long serialVersionUID = 1L;
        private boolean isFocused;
    
        @Override
        protected Highlighter.HighlightPainter getSelectionPainter() {
            return isFocused ? focusedPainter/*super.getSelectionPainter()*/ : unfocusedPainter;
        }
    
        @Override
        public void setSelectionVisible(boolean hasFocus) {
            if (hasFocus != isFocused) {
                isFocused = hasFocus;
                super.setSelectionVisible(false);
                super.setSelectionVisible(true);
            }
        }
    }
    

    with output

    enter image description here

    from code

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.text.DefaultCaret;
    import javax.swing.text.DefaultHighlighter;
    import javax.swing.text.Highlighter;
    
    public class TestTextComponents {
    
        private static final long serialVersionUID = 1L;
        private JTextField jTextField1;
        private JTextField jTextField2;
        private JFrame frame = new JFrame("Default Caret");
    
        public TestTextComponents() {
            jTextField1 = new JTextField();
            jTextField2 = new JTextField();
            jTextField1.setText("jTextField1");
            jTextField2.setText("jTextField2");
            jTextField1.setCaret(new HighlightCaret());
            jTextField2.setCaret(new HighlightCaret());
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setResizable(false);
            frame.setLayout(new FlowLayout());
            frame.add(new JLabel("Please skip between text fields and watch persistent selection: "));
            frame.add(jTextField1);
            frame.add(jTextField2);
            frame.setTitle("Text component persistent selection");
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new TestTextComponents();
                }
            });
        }
    }
    
    class HighlightCaret extends DefaultCaret {
    
        private static final Highlighter.HighlightPainter unfocusedPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED);
        private static final Highlighter.HighlightPainter focusedPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
        private static final long serialVersionUID = 1L;
        private boolean isFocused;
    
        @Override
        protected Highlighter.HighlightPainter getSelectionPainter() {
            setBlinkRate(500); // otherwise is disabled, stopped
            return isFocused ? focusedPainter/*super.getSelectionPainter()*/ : unfocusedPainter;
        }
    
        @Override
        public void setSelectionVisible(boolean hasFocus) {
            if (hasFocus != isFocused) {
                isFocused = hasFocus;
                super.setSelectionVisible(false);
                super.setSelectionVisible(true);
            }
        }
    }
    

    EDIT have to restore Caret.setBlinkRate(500);

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