001package com.ganteater.ae.desktop.editor; 002 003import java.awt.event.KeyAdapter; 004import java.awt.event.KeyEvent; 005import java.lang.reflect.Constructor; 006 007import javax.swing.JTextArea; 008import javax.swing.text.Document; 009import javax.swing.undo.UndoManager; 010 011import org.apache.commons.lang.StringUtils; 012 013import com.ganteater.ae.CommandException; 014import com.ganteater.ae.util.xml.easyparser.Node; 015 016public class TextEditor extends JTextArea implements Editor { 017 018 private static final long serialVersionUID = -298735473495909314L; 019 private final UndoManager undo = new UndoManager(); 020 private TaskEditor recipePanel; 021 private Node editorNode; 022 023 public TextEditor() { 024 super(); 025 setTabSize(4); 026 Document doc = getDocument(); 027 doc.addUndoableEditListener((evt) -> undo.addEdit(evt.getEdit())); 028 addKeyListener(new KeyAdapter() { 029 @Override 030 public void keyPressed(KeyEvent e) { 031 if (e.getKeyCode() == KeyEvent.VK_Z && e.isControlDown()) { 032 undo(); 033 } else if (e.getKeyCode() == KeyEvent.VK_Y && e.isControlDown()) { 034 redo(); 035 } 036 } 037 }); 038 } 039 040 @Override 041 public void init(TaskEditor taskEditor) throws CommandException { 042 this.recipePanel = taskEditor; 043 setFont(TaskEditor.font); 044 045 String helper = null; 046 if (editorNode != null) { 047 helper = taskEditor.getTaskProcessor().attr(editorNode, "helper"); 048 } 049 if (helper == null) { 050 helper = CodeHelper.class.getName(); 051 } 052 if (!helper.startsWith(TaskEditor.EDITOR_STD_PACKAGE)) { 053 helper = TaskEditor.EDITOR_STD_PACKAGE + helper; 054 } 055 056 try { 057 @SuppressWarnings("unchecked") 058 Class<? extends CodeHelper> filterClass = (Class<? extends CodeHelper>) Class.forName(helper); 059 Constructor<? extends CodeHelper> constructor = filterClass.getConstructor(TextEditor.class); 060 CodeHelper codeHelper = constructor.newInstance(this); 061 codeHelper.applyListeners(this); 062 } catch (Exception e) { 063 throw new IllegalArgumentException(e); 064 } 065 } 066 067 public void redo() { 068 try { 069 int caretPosition = getCaretPosition(); 070 if (undo.canRedo()) { 071 undo.redo(); 072 if (getDocument().getLength() == 0) { 073 if (undo.canRedo()) { 074 undo.redo(); 075 } else if (undo.canUndo()) { 076 undo.undo(); 077 } 078 } 079 } 080 setCaretPosition(caretPosition); 081 } catch (Exception e) { 082 // no nothing. 083 } 084 } 085 086 public void undo() { 087 try { 088 int caretPosition = getCaretPosition(); 089 if (undo.canUndo()) { 090 undo.undo(); 091 if (getDocument().getLength() == 0) { 092 if (undo.canUndo()) { 093 undo.undo(); 094 } else if (undo.canRedo()) { 095 undo.redo(); 096 } 097 } 098 } 099 setCaretPosition(caretPosition); 100 } catch (Exception e) { 101 // no nothing. 102 } 103 } 104 105 public void removeLine() { 106 int caretPosition = getCaretPosition(); 107 String text = getText(); 108 int start = StringUtils.lastIndexOf(text, "\n", caretPosition - 1); 109 start = start < 0 ? 0 : start + 1; 110 int end = StringUtils.indexOf(text, "\n", caretPosition); 111 end = end < 0 ? text.length() - 1 : end + 1; 112 start = start < end ? start : end; 113 replaceRange("", start, end); 114 setCaretPosition(start == 0 ? 0 : start); 115 } 116 117 public void setOriginalText(String xmlText) { 118 setText(xmlText); 119 } 120 121 public TaskEditor getRecipePanel() { 122 return recipePanel; 123 } 124 125 public Node getEditorNode() { 126 return editorNode; 127 } 128 129 public void setEditorNode(Node editorNode) { 130 this.editorNode = editorNode; 131 } 132 133}