Home > Software engineering >  Command Backspace functionality in JTextArea
Command Backspace functionality in JTextArea

Time:01-13

I have a small text editor that I made in Java Swing with JTextArea.

enter image description here

I want to implement the following:
When the user presses Command Backspace I want to remove all the text from the beginning of the line up to the cursor. How to implement this? I tried using KeyListeners but it doesn't work.

For example (before user presses Command Backspace) ...

before

Result (after user presses Command Backspace) ...

after

My code (Not 100% exact compared to the image):

import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Main{
    static JFrame frame = new JFrame();
    static JTextArea textArea = new JTextArea();
    static JScrollPane scrollPane = new JScrollPane(textArea);

    public static void main(String[] args) throws BadLocationException {
        frame.setTitle("Untitled");
        addComponentsToFrame();
        textArea.addKeyListener(new KeyListener(){
            @Override
            public void keyTyped(KeyEvent e) {
                if(e.getKeyCode() == (Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx() | KeyEvent.VK_BACK_SPACE)){
                    System.out.println("Delete"); //Placeholder
                }
            }
            @Override
            public void keyPressed(KeyEvent e) {}
            @Override
            public void keyReleased(KeyEvent e) {}
        });
    }
    
    public static void addComponentsToFrame(){
        scrollPane.setAutoscrolls(true);
        frame.add(scrollPane);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

For now when I have placed a print Statement as a place holder, since I don't know how to delete all the words from the beginning of the line up to the cursor (i.e. the logic).

CodePudding user response:

Solution:

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import java.awt.Toolkit;
public class TestSamplePrograms {
    private JTextArea  textarea;

    private void buildAndShowGui() {
        JFrame frame = new JFrame("Untitled");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(createTextArea(), BorderLayout.CENTER);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JScrollPane createTextArea() {
        textarea = new JTextArea(20, 60);
        InputMap im = textarea.getInputMap();
        KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx());
        im.put(ks, "del2EoL");
        ActionMap am = textarea.getActionMap();
        am.put("del2EoL", new Delete2EOL());
        JScrollPane pane = new JScrollPane(textarea);
        return pane;
    }

    @SuppressWarnings("serial")
    private class Delete2EOL extends AbstractAction {

        @Override
        public void actionPerformed(ActionEvent e) {
            int caretOffset = textarea.getCaretPosition();
            int lineNumber = 0;
            try {
                lineNumber = textarea.getLineOfOffset(caretOffset);
                int startOffset = textarea.getLineStartOffset(lineNumber);
                int endOffset = textarea.getLineEndOffset(lineNumber);
                textarea.replaceRange("", startOffset, endOffset);
            } catch (BadLocationException ex) {
                throw new RuntimeException(ex);
            }
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new TestSamplePrograms().buildAndShowGui());
    }
}
  • Related