/***************************************************************** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. ****************************************************************/ package org.apache.cayenne.modeler.undo; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import javax.swing.event.DocumentEvent; import javax.swing.event.UndoableEditEvent; import javax.swing.event.UndoableEditListener; import javax.swing.text.AbstractDocument; import javax.swing.text.JTextComponent; import javax.swing.undo.CompoundEdit; import javax.swing.undo.UndoableEdit; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.util.TextAdapter; public class JTextFieldUndoListener implements UndoableEditListener { public CompoundEdit compoundEdit; private TextAdapter adapter; private JTextComponent editor; private int lastOffset; private int lastLength; public JTextFieldUndoListener(TextAdapter adapter) { this(adapter.getComponent()); this.adapter = adapter; } public JTextFieldUndoListener(JTextComponent editor) { this.editor = editor; this.editor.addFocusListener(new FocusAdapter() { @Override public void focusLost(FocusEvent e) { finishCurrentEdit(); } }); } public void undoableEditHappened(UndoableEditEvent e) { if (compoundEdit == null || !compoundEdit.canUndo()) { compoundEdit = startCompoundEdit(e.getEdit()); lastLength = editor.getDocument().getLength(); return; } AbstractDocument.DefaultDocumentEvent event = (AbstractDocument.DefaultDocumentEvent) e .getEdit(); if (event.getType().equals(DocumentEvent.EventType.CHANGE)) { compoundEdit.addEdit(e.getEdit()); return; } int offsetChange = editor.getCaretPosition() - lastOffset; int lengthChange = editor.getDocument().getLength() - lastLength; if (Math.abs(offsetChange) == 1 && Math.abs(lengthChange) == 1) { compoundEdit.addEdit(e.getEdit()); lastOffset = editor.getCaretPosition(); lastLength = editor.getDocument().getLength(); return; } compoundEdit.end(); compoundEdit = startCompoundEdit(e.getEdit()); } private CompoundEdit startCompoundEdit(UndoableEdit anEdit) { lastOffset = editor.getCaretPosition(); lastLength = editor.getDocument().getLength(); compoundEdit = (this.adapter != null) ? new TextCompoundEdit(adapter, this) : new TextCompoundEdit(editor, this); compoundEdit.addEdit(anEdit); Application.getInstance().getUndoManager().addEdit(compoundEdit); return compoundEdit; } public void finishCurrentEdit() { if (compoundEdit != null) { compoundEdit.end(); compoundEdit = null; } } }