Create FTextEditor to encapsulate a plain text editor with undo/redo support

This commit is contained in:
drdev
2013-11-17 21:17:14 +00:00
parent b1ba8f0aa2
commit 9242f3439c
4 changed files with 175 additions and 27 deletions

View File

@@ -0,0 +1,161 @@
package forge.gui.toolbox;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.DocumentListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
@SuppressWarnings("serial")
public class FTextEditor extends JScrollPane {
private final JTextArea tarEditor;
public FTextEditor() {
tarEditor = new JTextArea();
FSkin.JTextComponentSkin<JTextArea> skin = FSkin.get(tarEditor);
skin.setFont(FSkin.getFixedFont(16));
skin.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
skin.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
skin.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT));
tarEditor.setMargin(new Insets(3, 3, 3, 3));
tarEditor.getDocument().addUndoableEditListener(new MyUndoableEditListener());
tarEditor.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.isControlDown() && !e.isMetaDown()) {
switch (e.getKeyCode()) {
case KeyEvent.VK_Z:
if (e.isShiftDown()) {
redoAction.actionPerformed(null);
}
else {
undoAction.actionPerformed(null);
}
break;
case KeyEvent.VK_Y:
if (!e.isShiftDown()) {
redoAction.actionPerformed(null);
}
break;
}
}
}
});
this.setViewportView(tarEditor);
this.setBorder(null);
this.setOpaque(false);
}
//Mapped functions to JTextArea
@Override
public boolean isEnabled() {
return tarEditor.isEnabled();
}
@Override
public void setEnabled(boolean enabled) {
tarEditor.setEnabled(enabled);
}
public String getText() {
return tarEditor.getText();
}
public void setText(String t) {
tarEditor.setText(t);
undoManager.discardAllEdits();
}
public boolean isEditable() {
return tarEditor.isEditable();
}
public void setEditable(boolean b) {
tarEditor.setEditable(b);
}
public int getCaretPosition() {
return tarEditor.getCaretPosition();
}
public void setCaretPosition(int position) {
tarEditor.setCaretPosition(position);
}
public void addDocumentListener(DocumentListener listener) {
tarEditor.getDocument().addDocumentListener(listener);
}
//Undo/Redo
private UndoAction undoAction = new UndoAction();
private RedoAction redoAction = new RedoAction();
private UndoManager undoManager = new UndoManager();
private class MyUndoableEditListener implements UndoableEditListener {
public void undoableEditHappened(UndoableEditEvent e) {
undoManager.addEdit(e.getEdit());
undoAction.updateUndoState();
redoAction.updateRedoState();
}
}
private class UndoAction extends AbstractAction {
public UndoAction() {
super("Undo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
try {
undoManager.undo();
} catch (CannotUndoException ex) {
System.out.println("Unable to undo: " + ex);
ex.printStackTrace();
}
updateUndoState();
redoAction.updateRedoState();
}
protected void updateUndoState() {
if (undoManager.canUndo()) {
setEnabled(true);
putValue(Action.NAME, undoManager.getUndoPresentationName());
} else {
setEnabled(false);
putValue(Action.NAME, "Undo");
}
}
}
private class RedoAction extends AbstractAction {
public RedoAction() {
super("Redo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
try {
undoManager.redo();
} catch (CannotRedoException ex) {
System.out.println("Unable to redo: " + ex);
ex.printStackTrace();
}
updateRedoState();
undoAction.updateUndoState();
}
protected void updateRedoState() {
if (undoManager.canRedo()) {
setEnabled(true);
putValue(Action.NAME, undoManager.getRedoPresentationName());
} else {
setEnabled(false);
putValue(Action.NAME, "Redo");
}
}
}
}

View File

@@ -12,6 +12,7 @@ import forge.Command;
import forge.Singletons;
import forge.gui.framework.FScreen;
import forge.gui.framework.ICDoc;
import forge.gui.toolbox.FTextEditor;
import forge.gui.workshop.menus.WorkshopFileMenu;
import forge.gui.workshop.views.VCardDesigner;
import forge.gui.workshop.views.VCardScript;
@@ -35,7 +36,7 @@ public enum CCardScript implements ICDoc {
private boolean isTextDirty;
private CCardScript() {
VCardScript.SINGLETON_INSTANCE.getTarScript().getDocument().addDocumentListener(new DocumentListener() {
VCardScript.SINGLETON_INSTANCE.getTxtScript().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent arg0) {
updateDirtyFlag();
@@ -54,7 +55,7 @@ public enum CCardScript implements ICDoc {
}
private void updateDirtyFlag() {
boolean isTextNowDirty = !VCardScript.SINGLETON_INSTANCE.getTarScript().getText().equals(baseText);
boolean isTextNowDirty = !VCardScript.SINGLETON_INSTANCE.getTxtScript().getText().equals(baseText);
if (this.isTextDirty == isTextNowDirty) { return; }
this.isTextDirty = isTextNowDirty;
VCardDesigner.SINGLETON_INSTANCE.getBtnSaveCard().setEnabled(isTextNowDirty);
@@ -94,10 +95,10 @@ public enum CCardScript implements ICDoc {
}
this.baseText = text;
JTextArea tarScript = VCardScript.SINGLETON_INSTANCE.getTarScript();
tarScript.setText(text);
tarScript.setEditable(editable);
tarScript.setCaretPosition(0); //keep scrolled to top
FTextEditor txtScript = VCardScript.SINGLETON_INSTANCE.getTxtScript();
txtScript.setText(text);
txtScript.setEditable(editable);
txtScript.setCaretPosition(0); //keep scrolled to top
}
public boolean hasChanges() {
@@ -131,7 +132,7 @@ public enum CCardScript implements ICDoc {
if (sourceFile == null) { return true; }
try {
String text = VCardScript.SINGLETON_INSTANCE.getTarScript().getText();
String text = VCardScript.SINGLETON_INSTANCE.getTxtScript().getText();
PrintWriter p = new PrintWriter(sourceFile);
p.print(text);

View File

@@ -1,16 +1,12 @@
package forge.gui.workshop.views;
import java.awt.Insets;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import net.miginfocom.swing.MigLayout;
import forge.gui.framework.DragCell;
import forge.gui.framework.DragTab;
import forge.gui.framework.EDocID;
import forge.gui.framework.IVDoc;
import forge.gui.toolbox.FSkin;
import forge.gui.toolbox.FTextEditor;
import forge.gui.workshop.controllers.CCardScript;
/**
@@ -26,25 +22,14 @@ public enum VCardScript implements IVDoc<CCardScript> {
private DragCell parentCell;
private final DragTab tab = new DragTab("Card Script");
private final JTextArea tarScript = new JTextArea();
private final JScrollPane scroller;
private final FTextEditor txtScript = new FTextEditor();
//========== Constructor
private VCardScript() {
FSkin.JTextComponentSkin<JTextArea> txtScriptSkin = FSkin.get(tarScript);
txtScriptSkin.setFont(FSkin.getFixedFont(16));
txtScriptSkin.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT));
txtScriptSkin.setBackground(FSkin.getColor(FSkin.Colors.CLR_THEME2));
txtScriptSkin.setCaretColor(FSkin.getColor(FSkin.Colors.CLR_TEXT));
tarScript.setMargin(new Insets(3, 3, 3, 3));
scroller = new JScrollPane(tarScript);
scroller.setBorder(null);
scroller.setOpaque(false);
}
public JTextArea getTarScript() {
return tarScript;
public FTextEditor getTxtScript() {
return txtScript;
}
//========== Overridden methods
@@ -96,6 +81,6 @@ public enum VCardScript implements IVDoc<CCardScript> {
public void populate() {
JPanel body = parentCell.getBody();
body.setLayout(new MigLayout("insets 1, gap 0, wrap"));
body.add(scroller, "w 100%, h 100%");
body.add(txtScript, "w 100%, h 100%");
}
}