Java 如何为swt文本编辑器执行撤消和重做功能
我创建了一个swt文本框,并尝试执行撤消和重做功能,但当我按“ctrl+z”时,侦听器本身不工作。因此,我们如何执行撤消和重做操作。实现撤消和重做的代码如下Java 如何为swt文本编辑器执行撤消和重做功能,java,swt,keylistener,e4,undo-redo,Java,Swt,Keylistener,E4,Undo Redo,我创建了一个swt文本框,并尝试执行撤消和重做功能,但当我按“ctrl+z”时,侦听器本身不工作。因此,我们如何执行撤消和重做操作。实现撤消和重做的代码如下 private static class CTabItemControl extends Composite { private static class UndoRedoStack<T> { private Stack<T> undo; private Sta
private static class CTabItemControl extends Composite {
private static class UndoRedoStack<T> {
private Stack<T> undo;
private Stack<T> redo;
public UndoRedoStack() {
undo = new Stack<T>();
redo = new Stack<T>();
}
public void pushUndo(T delta) {
undo.add(delta);
}
public void pushRedo(T delta) {
redo.add(delta);
}
public T popUndo() {
T res = undo.pop();
return res;
}
public T popRedo() {
T res = redo.pop();
return res;
}
public T peekUndo() {
T res = undo.peek();
return res;
}
public void clearRedo() {
redo.clear();
}
public void clearUndo() {
undo.clear();
}
public boolean hasUndo() {
return !undo.isEmpty();
}
public boolean hasRedo() {
return !redo.isEmpty();
}
}
//private StyledText editor;
private UndoRedoStack<ExtendedModifyEvent> stack;
private boolean isUndo;
private boolean isRedo;
public CTabItemControl(Composite parentComposite,final CTabItem tabitem){
super(parentComposite, SWT.NONE);
setLayout(new GridLayout(1, false));
editor = new StyledText(this, SWT.MULTI | SWT.V_SCROLL);
editor.setLayoutData(new GridData(GridData.FILL_BOTH));
editor.setFont(new Font(Display.getDefault(),"Cambria", 10, SWT.NORMAL));
editor.addListener(SWT.KeyDown, new Listener(){
public void handleEvent(Event event) {
event.doit = true;
if(!tabitem.getText().contains("*"))
{
tabitem.setText('*'+tabitem.getText());
System.out.println("inserted *");
}
}
});
editor.addExtendedModifyListener(new ExtendedModifyListener(){
//editor.addKeyListener(this);
public void modifyText(ExtendedModifyEvent event) {
if (isUndo) {
stack.pushRedo(event);
} else { // is Redo or a normal user action
stack.pushUndo(event);
if (!isRedo) {
stack.clearRedo();
}
}
}
});
editor.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
// Listen to CTRL+Z for Undo, to CTRL+Y or CTRL+SHIFT+Z for Redo
boolean isCtrl = (e.stateMask & SWT.CTRL) > 0;
boolean isAlt = (e.stateMask & SWT.ALT) > 0;
if (isCtrl && !isAlt) {
boolean isShift = (e.stateMask & SWT.SHIFT) > 0;
if (!isShift && e.keyCode == 'z') {
{
System.out.println("call undo");
undo();
}
} else if (!isShift && e.keyCode == 'y' || isShift
&& e.keyCode == 'z') {
redo();
}
}
if(e.stateMask == SWT.CTRL && e.keyCode == 'a'){
editor.selectAll();
}
}
public void keyReleased(KeyEvent e) {
// ignore
}
});
//this.editor = editor;
stack = new UndoRedoStack<ExtendedModifyEvent>();
}
private void revertEvent(ExtendedModifyEvent event) {
System.out.println("calling revertevent");
editor.replaceTextRange(event.start, event.length, event.replacedText);
// (causes the modifyText() listener method to be called)
editor.setSelectionRange(event.start, event.replacedText.length());
}
private void undo() {
System.out.println("calling undo");
if (stack.hasUndo()) {
isUndo = true;
revertEvent(stack.popUndo());
isUndo = false;
}
}
private void redo() {
if (stack.hasRedo()) {
isRedo = true;
revertEvent(stack.popRedo());
isRedo = false;
}
}
public void clearUndoRedo() {
stack.clearUndo();
stack.clearRedo();
}
public boolean hasUndo() {
return stack.hasUndo();
}
public String peekUndo() {
return stack.peekUndo().toString();
}
}
私有静态类CTabItemControl扩展了复合{
私有静态类UndoRedoStack{
私有堆栈撤消;
私有堆栈重做;
public UndoRedoStack(){
撤消=新堆栈();
redo=新堆栈();
}
公共空间pushUndo(T delta){
撤消。添加(增量);
}
公共空间pushRedo(T delta){
重做。添加(增量);
}
公共T popUndo(){
T res=undo.pop();
返回res;
}
公共T popRedo(){
T res=redo.pop();
返回res;
}
公共T peekUndo(){
T res=undo.peek();
返回res;
}
public void clearedo(){
重做。清除();
}
public void clearUndo(){
撤销。清除();
}
公共布尔值hasUndo(){
return!undo.isEmpty();
}
公共布尔hasRedo(){
return!redo.isEmpty();
}
}
//私有样式文本编辑器;
私有堆栈;
私有布尔isUndo;
私人布尔伊斯雷多;
公共CTabItem控件(复合父复合,最终CTabItem选项卡项){
super(parentComposite,SWT.NONE);
setLayout(新的GridLayout(1,false));
编辑器=新样式文本(这是SWT.MULTI | SWT.V|u滚动);
setLayoutData(新的GridData(GridData.FILL_BOTH));
setFont(新字体(Display.getDefault(),“Cambria”,10,SWT.NORMAL));
addListener(SWT.KeyDown,newlistener()){
公共无效handleEvent(事件){
event.doit=true;
如果(!tabitem.getText()包含(“*”)
{
tabitem.setText('*'+tabitem.getText());
System.out.println(“插入*”;
}
}
});
addExtendedModifyListener(新的ExtendedModifyListener(){
//addKeyListener(this);
public void modifyText(ExtendedModifyEvent事件){
如果(isUndo){
stack.pushRedo(事件);
}else{//是重做或正常的用户操作
stack.pushUndo(事件);
如果(!isRedo){
stack.clearedo();
}
}
}
});
addKeyListener(新的KeyListener(){
按下公共无效键(键事件e){
//按CTRL+Z键可撤消,按CTRL+Y键或CTRL+SHIFT+Z键可重做
布尔值isCtrl=(e.stateMask&SWT.CTRL)>0;
布尔值isAlt=(e.stateMask&SWT.ALT)>0;
如果(isCtrl&&!isAlt){
布尔isShift=(e.statemack和SWT.SHIFT)>0;
如果(!isShift&&e.keyCode=='z'){
{
System.out.println(“调用撤销”);
撤消();
}
}如果(!isShift&&e.keyCode='y'| | isShift,则为else
&&e.keyCode=='z'){
重做();
}
}
如果(e.stateMask==SWT.CTRL&&e.keyCode=='a'){
editor.selectAll();
}
}
公开无效密钥已释放(密钥事件e){
//忽略
}
});
//this.editor=editor;
堆栈=新的UndoRedoStack();
}
私有void revertEvent(ExtendedModifyEvent事件){
System.out.println(“调用事件”);
editor.replaceTextRange(event.start、event.length、event.replaceText);
//(导致调用modifyText()侦听器方法)
editor.setSelectionRange(event.start,event.replacedText.length());
}
私有void undo(){
System.out.println(“调用撤销”);
if(stack.hasUndo()){
isUndo=true;
revertEvent(stack.popUndo());
isUndo=false;
}
}
私有无效重做(){
if(stack.hasRedo()){
伊斯雷多=真;
revertEvent(stack.popRedo());
伊斯雷多=假;
}
}
public void clearUndoRedo(){
stack.clearUndo();
stack.clearedo();
}
公共布尔值hasUndo(){
返回stack.hasUndo();
}
公共字符串peekUndo(){
返回stack.peekendo().toString();
}
}
当您按Ctrl+Z或Ctrl+Y时,会得到两个按键事件,一个用于Ctrl,另一个用于另一个按键。因此,最好检查第二个事件的特征
e、 字符==0x1a
对于Ctr+Z,以及
e、 字符==0x19
对于Ctrl+Y