package com.niklim.clicktrace.view;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import javax.swing.text.JTextComponent;
/**
* Provides support for undo/redo operation on {#link JTextComponent}.
*/
public class TextComponentHistory {
LinkedList<String> stack = new LinkedList<String>();
JTextComponent textcomponent;
int index = 0;
public static class DefaultKeyAdapter extends KeyAdapter {
private TextComponentHistory history;
public DefaultKeyAdapter(TextComponentHistory history) {
this.history = history;
}
@Override
public void keyReleased(KeyEvent event) {
if (Character.isWhitespace(event.getKeyChar())) {
history.store();
} else if (event.isControlDown() && event.getKeyCode() == KeyEvent.VK_Z) {
history.restorePrevious();
} else if (event.isControlDown() && event.getKeyCode() == KeyEvent.VK_Y) {
history.restoreForward();
}
}
}
public TextComponentHistory(JTextComponent textcomponent) {
this.textcomponent = textcomponent;
}
public void restoreForward() {
store();
textcomponent.setText(forward());
waitForEventPropagation();
}
public void restorePrevious() {
store();
textcomponent.setText(previous());
waitForEventPropagation();
}
// dirty hack to let the text modification event to propagate
private void waitForEventPropagation() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void reset(String description) {
stack.clear();
stack.add(description);
index = 0;
}
public void store() {
String text = textcomponent.getText().trim();
if (!text.equals(stack.get(index))) {
List<String> toRemove = new ArrayList<String>(stack.subList(0, index));
stack.removeAll(toRemove);
stack.push(text);
index = 0;
}
}
private String previous() {
index++;
if (index >= stack.size()) {
index = stack.size() - 1;
}
return stack.get(index);
}
private String forward() {
index--;
if (index < 0) {
index = 0;
}
return stack.get(index);
}
}