Использование отменить и повторить для JTextArea - PullRequest
11 голосов
/ 30 марта 2010

Я делаю текстовый редактор, используя Java Swing. Я использую JTextArea для того же. Я хочу знать, как я могу использовать функциональность Undo и Redo в JTextArea, поскольку я не могу ее использовать.

Ответы [ 5 ]

13 голосов
/ 30 марта 2010

Насколько я понимаю, JTextArea не имеет встроенной функциональности Undo / Redo, но поиск Google нашел эту статью , которая может быть полезной.

Очевидно, существует Менеджер отмены в javax.swing, который можно подключить к событиям изменения JTextArea.

5 голосов
/ 06 января 2015

Вы можете сделать это

UndoManager manager = new UndoManager();
textArea.getDocument().addUndoableEditListener(manager);

Как только менеджер прикреплен к документу JTextArea, он будет отслеживать все изменения к содержанию текстовой области.

После присоединения менеджера к текстовому компоненту вы должны предоставить некоторые средства, чтобы сообщить менеджер, чтобы отменить / повторить операцию.

При необходимости вызывайте открытый метод void undo () и открытый void redo () UndoManager (например, метод actionPerformed () для actionlistener)

Вы можете прикрепить объекты Action к кнопке следующим образом вместо вызова методов undo () и redo (), что упрощает задачу:

JButton undoButton = new JButton(UndoManagerHelper.getUndoAction(manager));
JButton redoButton = new JButton(UndoManagerHelper.getRedoAction(manager));
5 голосов
/ 30 марта 2010

Прошло много времени с тех пор, как я это сделал, и я не помню деталей, но вот ссылка с некоторой информацией: http://java.sun.com/docs/books/tutorial/uiswing/components/generaltext.html

Для начала прокрутите вниз до раздела «Прослушивание изменений в документе».

3 голосов
/ 27 декабря 2017

Мне пришлось пройти по нескольким ссылкам, чтобы получить достаточно помощи. Я добавляю сюда то, что успешно реализовал, чтобы помочь будущим посетителям. Я реализовал это с помощью JTextPane, но я предполагаю, что то же самое будет применяться для JTextArea

    JTextArea textArea = new JTextArea();
    JButton undo = new JButton("Undo");
    JButton redo = new JButton("Redo");
    KeyStroke undoKeyStroke = KeyStroke.getKeyStroke(
            KeyEvent.VK_Z, Event.CTRL_MASK);
    KeyStroke redoKeyStroke = KeyStroke.getKeyStroke(
            KeyEvent.VK_Y, Event.CTRL_MASK);

    UndoManager undoManager = new UndoManager();

    Document document = textArea.getDocument();
    document.addUndoableEditListener(new UndoableEditListener() {
        @Override
        public void undoableEditHappened(UndoableEditEvent e) {
            undoManager.addEdit(e.getEdit());
        }
    });

    // Add ActionListeners
    undo.addActionListener((ActionEvent e) -> {
        try {
            undoManager.undo();
        } catch (CannotUndoException cue) {}
    });
    redo.addActionListener((ActionEvent e) -> {
        try {
            undoManager.redo();
        } catch (CannotRedoException cre) {}
    });

    // Map undo action
    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
            .put(undoKeyStroke, "undoKeyStroke");
    textArea.getActionMap().put("undoKeyStroke", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                undoManager.undo();
             } catch (CannotUndoException cue) {}
        }
    });
    // Map redo action
    textArea.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
            .put(redoKeyStroke, "redoKeyStroke");
    textArea.getActionMap().put("redoKeyStroke", new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                undoManager.redo();
             } catch (CannotRedoException cre) {}
        }
    });
1 голос
/ 10 января 2019

Я создал простой класс, который может назначать функции отмены JTextcomponent (JTextField, JTextArea и т. Д.) Одним вызовом метода:

UndoTool.addUndoFunctionality(area);

или альтернативно создайте новую JTextArea с предварительно назначенной функцией отмены:

UndoTool.createJTextFieldWithUndo();

Вот реализация служебного класса:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...