用于文本编辑的control有2个:Text和StyledText.后者可以为文本和control本身设定颜色,格式等。这两个control之间毫无关联,除了都是Composite的子类之外。
- The basic Text widget
package com.swtjface.Ch5;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
public class Ch5Capitalizer extends Composite {
public Ch5Capitalizer(Composite parent) {
super(parent, SWT.NONE);
buildControls();
}
private void buildControls() {
this.setLayout(new FillLayout());
Text text = new Text(this, SWT.MULTI | SWT.V_SCROLL);
text.addVerifyListener(new VerifyListener() { //每当text被改变,任何以注册的VerifyListeners便会被调用。此处每按一次键盘,此方法就被调用。如果是同时输入多个字符,也调用一次
public void verifyText(VerifyEvent e) {
if( e.text.startsWith("1") ) {
e.doit = false;
} //如果文本以1开头,即不允许编辑
else {
e.text = e.text.toUpperCase();
}
}
});
}
}
Text的重要方法,见下图
insert()--doesn’t allow you to insert text into the existing content.
- The StyledText widget
StyledText包含了一系列的应用到该小部件的预定义的动作,这些是常规的东西如:剪切、粘贴、移动至下一个词、移动至文末。代表这些动作的常量在org.eclipse.swt.custom程序包中的ST类中有定义。这些常量在两种情况下发挥功效:首先,你可以使用它们程序性地使用invokeAction()方法调用任一的这些方法;其次,你也可以使用setKeyBinding()方法来将它们绑定于键击行为。setKeyBinding()选定一个键(可以通过诸如Shift或是Ctrl之类的编辑键来修改SWT常量之一)绑定于指定的动作。如下的例子中组合键Ctrl-Q绑定于粘贴动作。引起注意的是这并不意味着会将默认键的绑定清除,该两个绑定都会生效。
相对于Text而言,还添加了drawing line backgrounds and line styles的事件,可以通过此事件来改变整行的style或背景颜色。注意:如果使用了LineStyleListener,就不能在StyledText实例上调用get/setStyleRange(), 如果使用了LineBackgroundListener,那你就不能调用getLineBackground() or setLineBackground().
可以通过使用一个StyledText的StyleRanges来改变显示的风格
StyleRange
StyledText通过使用StyleRange类来管理当前所显示的不同styles。其所有的栏位都是public的可随意修改,但是要一直到当此StyledText实例的setStyleRange()被调用之后才会生效。
StyleRanges通过开始偏移量和长度来设定text的区域范围。 StyleRange可设定背景和前景色,默认为null,还可设定字体,SWT.NORMAL 或者SWT.BOLD.
similarTo()可用来判断两个StyleRange实例是否有同样的前景、背景和字体。
当我们保存text之后,可通过styledText.getStyleRanges()来获取style信息,此函数会返回an array of StyleRange
toggleBold()--将已输入的文本在bold和normal之间切换,是被一个KeyListener调用的,此KeyListener会监听F1是否被按下
A StyledText example
复制、粘贴功能不需要通过代码便可使用,是和platform的标准键盘快捷方式相关联的
ExtendedModifyListener和ModifyListener不同,前者提供了关于what was done的event细节,而后者只是当编辑懂作产生时notify,不会去准确的辨别到底何种修改发生了。
package com.swtjface.Ch5;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Composite;
public class Ch5Undoable extends Composite {
private static final int MAX_STACK_SIZE = 25;
private List undoStack;
private List redoStack;
private StyledText styledText;
public Ch5Undoable(Composite parent) {
super(parent, SWT.NONE);
undoStack = new LinkedList();
redoStack = new LinkedList();
buildControls();
}
private void buildControls() {
this.setLayout(new FillLayout());
styledText = new StyledText(this, SWT.MULTI | SWT.V_SCROLL);
styledText.addExtendedModifyListener(
new ExtendedModifyListener() { //每次text被编辑的时候,都会调用此listener
public void modifyText(ExtendedModifyEvent event) {
String currText = styledText.getText();
String newText = currText.substring(event.start,
event.start + event.length); //获得新插入的文本
if( newText != null && newText.length() > 0 ) {
if( undoStack.size() == MAX_STACK_SIZE ) {
undoStack.remove( undoStack.size() - 1 );
}
undoStack.add(0, newText);//将新插入的文本保存到undoStack中
}
}
}); //关键部分
styledText.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch(e.keyCode) {
case SWT.F1:
undo(); break;
case SWT.F2:
redo(); break;
default: //ignore everything else
}
}
});
}
private void undo() {
if( undoStack.size() > 0 ) {
String lastEdit = (String)undoStack.remove(0);//得到要undo的字符
int editLength = lastEdit.length();
String currText = styledText.getText();
int startReplaceIndex = currText.length() - editLength;
styledText.replaceTextRange(startReplaceIndex, editLength, ""); //将最后输入的字符替换成空
redoStack.add(0, lastEdit);//把最后的这个undo的字符加到redoStack中
}
}
private void redo() {
if( redoStack.size() > 0 ) {
String text = (String)redoStack.remove(0);//得到要恢复的字符
moveCursorToEnd();
styledText.append(text);//将要恢复的字符加至文本的最后
moveCursorToEnd();
}
}
private void moveCursorToEnd() {
styledText.setCaretOffset(styledText.getText().length());
}
}