Search code examples
javaswingjtextfieldcaretgetcaretpos

Deselect default selection on JTextfield


When using JTextFields i like to set a default text.

Then i run the program and this default text will automatically be selected (at least when you have only one field). In other words, if I type a letter right away, the default text will be deleted and replaced by the new one.

My question is how I can change the default settings in a way that allows me to type a letter without deleting the default text? I would like the letter to just be added at the end of the default text.

Here's my code:

    public class ButtonsNText extends JPanel implements ActionListener, KeyListener {

private JTextField TextLine;
private JToggleButton UpperCaseButton;
private JToggleButton LowerCaseButton;
private JCheckBox ContinuousButton;
private ButtonGroup myButtonGroup;

public ButtonsNText(){
    TextLine = new JTextField(10);
    add(TextLine); TextLine.setName("TextLine");
    TextLine.setText("default text"); 
    TextLine.setCaretPosition(TextLine.getText().length());
    TextLine.addKeyListener(this);
    myButtonGroup = new ButtonGroup();
    UpperCaseButton = new JToggleButton("Upper case");
    add(UpperCaseButton);UpperCaseButton.setName("UpperCaseButton");
    LowerCaseButton = new JToggleButton("Lower case");
    add(LowerCaseButton); LowerCaseButton.setName("LowerCaseButton");
    ContinuousButton = new JCheckBox("Continuous?");
    add(ContinuousButton); ContinuousButton.setName("ContinuousButton");
    myButtonGroup.add(UpperCaseButton); myButtonGroup.add(LowerCaseButton);
    UpperCaseButton.addActionListener(this);
    LowerCaseButton.addActionListener(this);
    ContinuousButton.addActionListener(this);

}
public static void main(String[] args) {
    JFrame frame = new JFrame("Hello world example");
    frame.add(new ButtonsNText());
    frame.pack();
    frame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == UpperCaseButton){
        TextLine.setText(TextLine.getText().toUpperCase());
    }
    else if(e.getSource() == LowerCaseButton){
        TextLine.setText(TextLine.getText().toLowerCase());
    }
}
@Override
public void keyReleased(KeyEvent k) {
    if(ContinuousButton.isSelected()){
        if(UpperCaseButton.isSelected()){
            int pos = TextLine.getCaretPosition();
            TextLine.setText(TextLine.getText().toUpperCase());
            TextLine.setCaretPosition(pos);
        }
        else if(LowerCaseButton.isSelected()){
            int pos = TextLine.getCaretPosition();
            TextLine.setText(TextLine.getText().toLowerCase());
            TextLine.setCaretPosition(pos);

        }
    }
    int key = k.getKeyCode();
    if(key == KeyEvent.VK_ENTER){
        if(UpperCaseButton.isSelected()){
            TextLine.setText(TextLine.getText().toUpperCase());
        }
        else if(LowerCaseButton.isSelected()){
            TextLine.setText(TextLine.getText().toLowerCase());
        }
    }
}

}

I have tried things like isFocusable(), setFocusable(), setCaterPosition() and other similar methods, but here I think I need a different approach.


Solution

  • for @Pete and will be deleted

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.text.DefaultCaret;
    import javax.swing.text.DefaultHighlighter;
    import javax.swing.text.Highlighter;
    
    public class TestTextComponents extends JFrame {
    
        private static final long serialVersionUID = 1L;
        private JTextField jTextField1;
        private JTextField jTextField2;
    
        public TestTextComponents() {
            initComponents();
        }
    
        private void initComponents() {
            jTextField1 = new JTextField();
            jTextField2 = new JTextField();
            getContentPane().setLayout(new FlowLayout());
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            setTitle("Text component persistent selection");
            setResizable(false);
            getContentPane().add(new JLabel(
                    "Please skip between text fields and watch persistent selection: "));
            jTextField1.setText("jTextField1");
            getContentPane().add(jTextField1);
            jTextField2.setText("jTextField2");
            getContentPane().add(jTextField2);
            jTextField1.setCaret(new HighlightCaret());
            jTextField2.setCaret(new HighlightCaret());
            //Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
           // setBounds((screenSize.width - 600) / 2, (screenSize.height - 70) / 2, 600, 70);
        }
    
        public static void main(String args[]) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TestTextComponents().setVisible(true);
                }
            });
        }
    }
    
    class HighlightCaret extends DefaultCaret {
    
        private static final Highlighter.HighlightPainter unfocusedPainter =
                new DefaultHighlighter.DefaultHighlightPainter(new Color(230, 230, 210));
        private static final long serialVersionUID = 1L;
        private boolean isFocused;
    
        @Override
        protected Highlighter.HighlightPainter getSelectionPainter() {
            return isFocused ? super.getSelectionPainter() : unfocusedPainter;
        }
    
        @Override
        public void setSelectionVisible(boolean hasFocus) {
            if (hasFocus != isFocused) {
                isFocused = hasFocus;
                super.setSelectionVisible(false);
                super.setSelectionVisible(true);
            }
        }
    }