Using undo and redo for JTextArea

后端 未结 5 971
一向
一向 2021-01-04 12:33

I am making a text editor using Java swing. I am using JTextArea for the same. I want to know how I can use Undo and Redo functionality in JTextArea as I am not able to use

5条回答
  •  失恋的感觉
    2021-01-04 12:40

    I created a simple class that can assign undo functionality to a JTextcomponent (JTextField, JTextArea, etc.) with a single method call:

    UndoTool.addUndoFunctionality(area);
    

    or alternatively construct a new JTextArea with the undo functionality pre-assigned:

    UndoTool.createJTextFieldWithUndo();
    

    Here is the implementation of the utility class:

    public class UndoTool {
        private static final String REDO_KEY = "redo";
        private static final String UNDO_KEY = "undo";
    
        private JTextComponent component;
        private KeyStroke undo = KeyStroke.getKeyStroke("control Z");
        private KeyStroke redo = KeyStroke.getKeyStroke("control Y");
    
        public UndoTool(JTextComponent component) {
            this.component = component;
        }
    
        public void setUndo(KeyStroke undo) {
            this.undo = undo;
        }
    
        public void setRedo(KeyStroke redo) {
            this.redo = redo;
        }
    
        public static void addUndoFunctionality(JTextComponent component) {
            UndoTool tool = new UndoTool(component);
            UndoManager undo = tool.createAndBindUndoManager();
            tool.bindUndo(undo);
            tool.bindRedo(undo);
        }
    
        public static JTextArea createJTextAreaWithUndo() {
            JTextArea area = new JTextArea();
            addUndoFunctionality(area);
            return area;
        }
    
        public static JTextField createJTextFieldWithUndo() {
            JTextField field = new JTextField();
            addUndoFunctionality(field);
            return field;
        }
    
        public UndoManager createAndBindUndoManager() {
            Check.notNull(component);
    
            UndoManager manager = new UndoManager();
            Document document = component.getDocument();
            document.addUndoableEditListener(event -> manager.addEdit(event.getEdit()));
            return manager;
        }
    
        public void bindRedo(UndoManager manager) {
            component.getActionMap().put(REDO_KEY, new AbstractAction(REDO_KEY) {
                @Override
                public void actionPerformed(ActionEvent evt) {
                    try {
                        if (manager.canRedo()) {
                            manager.redo();
                        }
                    } catch (CannotRedoException ignore) {
                    }
                }
            });
            component.getInputMap().put(redo, REDO_KEY);
        }
    
        public void bindUndo(UndoManager manager) {
            component.getActionMap().put(UNDO_KEY, new AbstractAction(UNDO_KEY) {
                @Override
                public void actionPerformed(ActionEvent evt) {
                    try {
                        if (manager.canUndo()) {
                            manager.undo();
                        }
                    } catch (CannotUndoException ignore) {
                    }
                }
            });
            component.getInputMap().put(undo, UNDO_KEY);
        }
    }
    

提交回复
热议问题