Java Tutorial/SWT/StyledText — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
Admin (обсуждение | вклад) м (1 версия) |
(нет различий)
|
Текущая версия на 15:20, 31 мая 2010
Содержание
- 1 A simple editor
- 2 Create a StyledText that scrolls vertically, wraps text, and displays a border:
- 3 Creating a StyledText Widget
- 4 Draw a box around text
- 5 Getting Statistics: Caret Offset, Total Lines of Text, Total Characters and Current Line
- 6 Limit the number of characters that the StyledText accepts
- 7 Make a StyledText read-only
- 8 Print StyledText out
- 9 Print to the default printer in a separate thread
- 10 Replace Text Range
- 11 Set page format for printing
- 12 StyledText: embed controls
- 13 StyledText: embed images
- 14 StyledText: use gradient background
- 15 Understanding the Repercussions
- 16 Using the Clipboard
A simple editor
//Code revised from
/*
The Definitive Guide to SWT and JFace
by Robert Harris and Rob Warner
Apress 2004
*/
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Stack;
import java.util.StringTokenizer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextPrintOptions;
import org.eclipse.swt.events.ArmEvent;
import org.eclipse.swt.events.ArmListener;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
public class PmpEditor {
// The number of operations that can be undone
private static final int UNDO_LIMIT = 500;
// Contains a reference to this application
private static PmpEditor app;
// Contains a reference to the main window
private Shell shell;
// Displays the file
private StyledText st;
// The full path of the current file
private String filename;
// The font for the StyledText
private Font font;
// The label to display statistics
private Label status;
// The print options and printer
private StyledTextPrintOptions options;
private Printer printer;
// The stack used to store the undo information
private Stack changes;
// Flag to set before performaing an undo, so the undo
// operation doesn"t get stored with the rest of the undo
// information
private boolean ignoreUndo = false;
// Syntax data for the current extension
private SyntaxData sd;
// Line style listener
private PmpeLineStyleListener lineStyleListener;
/**
* Gets the reference to this application
*
* @return HexEditor
*/
public static PmpEditor getApp() {
return app;
}
/**
* Constructs a PmpEditor
*/
public PmpEditor() {
app = this;
changes = new Stack();
// Set up the printing options
options = new StyledTextPrintOptions();
options.footer = StyledTextPrintOptions.SEPARATOR + StyledTextPrintOptions.PAGE_TAG
+ StyledTextPrintOptions.SEPARATOR + "Confidential";
}
/**
* Runs the application
*/
public void run() {
Display display = new Display();
shell = new Shell(display);
// Choose a monospaced font
font = new Font(display, "Terminal", 12, SWT.NONE);
createContents(shell);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
font.dispose();
display.dispose();
if (printer != null)
printer.dispose();
}
/**
* Creates the main window"s contents
*
* @param shell
* the main window
*/
private void createContents(Shell shell) {
// Set the layout and the menu bar
shell.setLayout(new FormLayout());
shell.setMenuBar(new PmpEditorMenu(shell).getMenu());
// Create the status bar
status = new Label(shell, SWT.BORDER);
FormData data = new FormData();
data.left = new FormAttachment(0, 0);
data.right = new FormAttachment(100, 0);
data.bottom = new FormAttachment(100, 0);
data.height = status.ruputeSize(SWT.DEFAULT, SWT.DEFAULT).y;
status.setLayoutData(data);
// Create the styled text
st = new StyledText(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
data = new FormData();
data.left = new FormAttachment(0);
data.right = new FormAttachment(100);
data.top = new FormAttachment(0);
data.bottom = new FormAttachment(status);
st.setLayoutData(data);
// Set the font
st.setFont(font);
// Add Brief delete next word
// Use SWT.MOD1 instead of SWT.CTRL for portability
st.setKeyBinding("k" | SWT.MOD1, ST.DELETE_NEXT);
// Add vi end of line (kind of)
// Use SWT.MOD1 instead of SWT.CTRL for portability
// Use SWT.MOD2 instead of SWT.SHIFT for portability
// Shift+4 is $
st.setKeyBinding("4" | SWT.MOD1 | SWT.MOD2, ST.LINE_END);
// Handle key presses
st.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent event) {
// Update the status bar
updateStatus();
}
});
// Handle text modifications
st.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent event) {
// Update the status bar
updateStatus();
// Update the comments
if (lineStyleListener != null) {
lineStyleListener.refreshMultilineComments(st.getText());
st.redraw();
}
}
});
// Store undo information
st.addExtendedModifyListener(new ExtendedModifyListener() {
public void modifyText(ExtendedModifyEvent event) {
if (!ignoreUndo) {
// Push this change onto the changes stack
changes.push(new TextChange(event.start, event.length, event.replacedText));
if (changes.size() > UNDO_LIMIT)
changes.remove(0);
}
}
});
// Update the title bar and the status bar
updateTitle();
updateStatus();
}
/**
* Opens a file
*/
public void openFile() {
FileDialog dlg = new FileDialog(shell);
String temp = dlg.open();
if (temp != null) {
try {
// Get the file"s contents
String text = PmpeIoManager.getFile(temp);
// File loaded, so save the file name
filename = temp;
// Update the syntax properties to use
updateSyntaxData();
// Put the new file"s data in the StyledText
st.setText(text);
// Update the title bar
updateTitle();
// Delete any undo information
changes.clear();
} catch (IOException e) {
showError(e.getMessage());
}
}
}
/**
* Saves a file
*/
public void saveFile() {
if (filename == null) {
saveFileAs();
} else {
try {
// Save the file and update the title bar based on the new file name
PmpeIoManager.saveFile(filename, st.getText().getBytes());
updateTitle();
} catch (IOException e) {
showError(e.getMessage());
}
}
}
/**
* Saves a file under a different name
*/
public void saveFileAs() {
FileDialog dlg = new FileDialog(shell);
if (filename != null) {
dlg.setFileName(filename);
}
String temp = dlg.open();
if (temp != null) {
filename = temp;
// The extension may have changed; update the syntax data accordingly
updateSyntaxData();
saveFile();
}
}
/**
* Prints the document to the default printer
*/
public void print() {
if (printer == null)
printer = new Printer();
options.header = StyledTextPrintOptions.SEPARATOR + filename + StyledTextPrintOptions.SEPARATOR;
st.print(printer, options).run();
}
/**
* Cuts the current selection to the clipboard
*/
public void cut() {
st.cut();
}
/**
* Copies the current selection to the clipboard
*/
public void copy() {
st.copy();
}
/**
* Pastes the clipboard"s contents
*/
public void paste() {
st.paste();
}
/**
* Selects all the text
*/
public void selectAll() {
st.selectAll();
}
/**
* Undoes the last change
*/
public void undo() {
// Make sure undo stack isn"t empty
if (!changes.empty()) {
// Get the last change
TextChange change = (TextChange) changes.pop();
// Set the flag. Otherwise, the replaceTextRange call will get placed
// on the undo stack
ignoreUndo = true;
// Replace the changed text
st.replaceTextRange(change.getStart(), change.getLength(), change.getReplacedText());
// Move the caret
st.setCaretOffset(change.getStart());
// Scroll the screen
st.setTopIndex(st.getLineAtOffset(change.getStart()));
ignoreUndo = false;
}
}
/**
* Toggles word wrap
*/
public void toggleWordWrap() {
st.setWordWrap(!st.getWordWrap());
}
/**
* Gets the current word wrap settings
*
* @return boolean
*/
public boolean getWordWrap() {
return st.getWordWrap();
}
/**
* Shows an about box
*/
public void about() {
MessageBox mb = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
mb.setMessage("Poor Man"s Programming Editor");
mb.open();
}
/**
* Updates the title bar
*/
private void updateTitle() {
String fn = filename == null ? "Untitled" : filename;
shell.setText(fn + " -- PmPe");
}
/**
* Updates the status bar
*/
private void updateStatus() {
// Show the offset into the file, the total number of characters in the
// file,
// the current line number (1-based) and the total number of lines
StringBuffer buf = new StringBuffer();
buf.append("Offset: ");
buf.append(st.getCaretOffset());
buf.append("\tChars: ");
buf.append(st.getCharCount());
buf.append("\tLine: ");
buf.append(st.getLineAtOffset(st.getCaretOffset()) + 1);
buf.append(" of ");
buf.append(st.getLineCount());
status.setText(buf.toString());
}
/**
* Updates the syntax data based on the filename"s extension
*/
private void updateSyntaxData() {
// Determine the extension of the current file
String extension = "";
if (filename != null) {
int pos = filename.lastIndexOf(".");
if (pos > -1 && pos < filename.length() - 2) {
extension = filename.substring(pos + 1);
}
}
// Get the syntax data for the extension
sd = SyntaxManager.getSyntaxData(extension);
// Reset the line style listener
if (lineStyleListener != null) {
st.removeLineStyleListener(lineStyleListener);
}
lineStyleListener = new PmpeLineStyleListener(sd);
st.addLineStyleListener(lineStyleListener);
// Redraw the contents to reflect the new syntax data
st.redraw();
}
/**
* Shows an error message
*
* @param error
* the text to show
*/
private void showError(String error) {
MessageBox mb = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK);
mb.setMessage(error);
mb.open();
}
/**
* The application entry point
*
* @param args
* the command line arguments
*/
public static void main(String[] args) {
new PmpEditor().run();
}
}
class PmpEditorMenu {
// The underlying menu this class wraps
Menu menu = null;
/**
* Constructs a PmpEditorMenu
*
* @param shell
* the parent shell
*/
public PmpEditorMenu(final Shell shell) {
// Create the menu
menu = new Menu(shell, SWT.BAR);
// Create the File top-level menu
MenuItem item = new MenuItem(menu, SWT.CASCADE);
item.setText("File");
Menu dropMenu = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(dropMenu);
// Create File->Open
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Open...\tCtrl+O");
item.setAccelerator(SWT.CTRL + "O");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().openFile();
}
});
// Create File->Save
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Save\tCtrl+S");
item.setAccelerator(SWT.CTRL + "S");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().saveFile();
}
});
// Create File->Save As
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Save As...");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().saveFileAs();
}
});
new MenuItem(dropMenu, SWT.SEPARATOR);
// Create File->Print
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Print\tCtrl+P");
item.setAccelerator(SWT.CTRL + "P");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().print();
}
});
new MenuItem(dropMenu, SWT.SEPARATOR);
// Create File->Exit
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Exit\tAlt+F4");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
shell.close();
}
});
// Create Edit
item = new MenuItem(menu, SWT.CASCADE);
item.setText("Edit");
dropMenu = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(dropMenu);
// Create Edit->Cut
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Cut\tCtrl+X");
item.setAccelerator(SWT.CTRL + "X");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().cut();
}
});
// Create Edit->Copy
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Copy\tCtrl+C");
item.setAccelerator(SWT.CTRL + "C");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().copy();
}
});
// Create Edit->Paste
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Paste\tCtrl+V");
item.setAccelerator(SWT.CTRL + "V");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().paste();
}
});
new MenuItem(dropMenu, SWT.SEPARATOR);
// Create Select All
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Select All\tCtrl+A");
item.setAccelerator(SWT.CTRL + "A");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().selectAll();
}
});
new MenuItem(dropMenu, SWT.SEPARATOR);
// Create Undo
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("Undo\tCtrl+Z");
item.setAccelerator(SWT.CTRL + "Z");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().undo();
}
});
new MenuItem(dropMenu, SWT.SEPARATOR);
// Create Word Wrap
final MenuItem wwItem = new MenuItem(dropMenu, SWT.CHECK);
wwItem.setText("Word Wrap\tCtrl+W");
wwItem.setAccelerator(SWT.CTRL + "W");
wwItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().toggleWordWrap();
}
});
wwItem.addArmListener(new ArmListener() {
public void widgetArmed(ArmEvent event) {
wwItem.setSelection(PmpEditor.getApp().getWordWrap());
}
});
// Create Help
item = new MenuItem(menu, SWT.CASCADE);
item.setText("Help");
dropMenu = new Menu(shell, SWT.DROP_DOWN);
item.setMenu(dropMenu);
// Create Help->About
item = new MenuItem(dropMenu, SWT.NULL);
item.setText("About\tCtrl+A");
item.setAccelerator(SWT.CTRL + "A");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
PmpEditor.getApp().about();
}
});
}
/**
* Gets the underlying menu
*
* @return Menu
*/
public Menu getMenu() {
return menu;
}
}
class PmpeIoManager {
/**
* Gets a file (loads it) from the filesystem
*
* @param filename
* the full path of the file
* @return String
* @throws IOException
* if file cannot be loaded
*/
public static String getFile(String filename) throws IOException {
InputStream in = new BufferedInputStream(new FileInputStream(filename));
StringBuffer buf = new StringBuffer();
int c;
while ((c = in.read()) != -1) {
buf.append((char) c);
}
return buf.toString();
}
/**
* Saves a file
*
* @param filename
* the full path of the file to save
* @param data
* the data to save
* @throws IOException
* if file cannot be saved
*/
public static void saveFile(String filename, byte[] data) throws IOException {
File outputFile = new File(filename);
FileOutputStream out = new FileOutputStream(outputFile);
out.write(data);
out.close();
}
}
class TextChange {
// The starting offset of the change
private int start;
// The length of the change
private int length;
// The replaced text
String replacedText;
/**
* Constructs a TextChange
*
* @param start
* the starting offset of the change
* @param length
* the length of the change
* @param replacedText
* the text that was replaced
*/
public TextChange(int start, int length, String replacedText) {
this.start = start;
this.length = length;
this.replacedText = replacedText;
}
/**
* Returns the start
*
* @return int
*/
public int getStart() {
return start;
}
/**
* Returns the length
*
* @return int
*/
public int getLength() {
return length;
}
/**
* Returns the replacedText
*
* @return String
*/
public String getReplacedText() {
return replacedText;
}
}
/**
* This class contains information for syntax coloring and styling for an
* extension
*/
class SyntaxData {
private String extension;
private Collection keywords;
private String punctuation;
private String comment;
private String multiLineCommentStart;
private String multiLineCommentEnd;
/**
* Constructs a SyntaxData
*
* @param extension
* the extension
*/
public SyntaxData(String extension) {
this.extension = extension;
}
/**
* Gets the extension
*
* @return String
*/
public String getExtension() {
return extension;
}
/**
* Gets the comment
*
* @return String
*/
public String getComment() {
return comment;
}
/**
* Sets the comment
*
* @param comment
* The comment to set.
*/
public void setComment(String comment) {
this.rument = comment;
}
/**
* Gets the keywords
*
* @return Collection
*/
public Collection getKeywords() {
return keywords;
}
/**
* Sets the keywords
*
* @param keywords
* The keywords to set.
*/
public void setKeywords(Collection keywords) {
this.keywords = keywords;
}
/**
* Gets the multiline comment end
*
* @return String
*/
public String getMultiLineCommentEnd() {
return multiLineCommentEnd;
}
/**
* Sets the multiline comment end
*
* @param multiLineCommentEnd
* The multiLineCommentEnd to set.
*/
public void setMultiLineCommentEnd(String multiLineCommentEnd) {
this.multiLineCommentEnd = multiLineCommentEnd;
}
/**
* Gets the multiline comment start
*
* @return String
*/
public String getMultiLineCommentStart() {
return multiLineCommentStart;
}
/**
* Sets the multiline comment start
*
* @param multiLineCommentStart
* The multiLineCommentStart to set.
*/
public void setMultiLineCommentStart(String multiLineCommentStart) {
this.multiLineCommentStart = multiLineCommentStart;
}
/**
* Gets the punctuation
*
* @return String
*/
public String getPunctuation() {
return punctuation;
}
/**
* Sets the punctuation
*
* @param punctuation
* The punctuation to set.
*/
public void setPunctuation(String punctuation) {
this.punctuation = punctuation;
}
}
/**
* This class manages the syntax coloring and styling data
*/
class SyntaxManager {
// Lazy cache of SyntaxData objects
private static Map data = new Hashtable();
/**
* Gets the syntax data for an extension
*/
public static synchronized SyntaxData getSyntaxData(String extension) {
// Check in cache
SyntaxData sd = (SyntaxData) data.get(extension);
if (sd == null) {
// Not in cache; load it and put in cache
sd = loadSyntaxData(extension);
if (sd != null)
data.put(sd.getExtension(), sd);
}
return sd;
}
/**
* Loads the syntax data for an extension
*
* @param extension
* the extension to load
* @return SyntaxData
*/
private static SyntaxData loadSyntaxData(String extension) {
SyntaxData sd = null;
try {
ResourceBundle rb = ResourceBundle.getBundle("examples.ch11." + extension);
sd = new SyntaxData(extension);
sd.setComment(rb.getString("comment"));
sd.setMultiLineCommentStart(rb.getString("multilinecommentstart"));
sd.setMultiLineCommentEnd(rb.getString("multilinecommentend"));
// Load the keywords
Collection keywords = new ArrayList();
for (StringTokenizer st = new StringTokenizer(rb.getString("keywords"), " "); st
.hasMoreTokens();) {
keywords.add(st.nextToken());
}
sd.setKeywords(keywords);
// Load the punctuation
sd.setPunctuation(rb.getString("punctuation"));
} catch (MissingResourceException e) {
// Ignore
}
return sd;
}
}
/**
* This class performs the syntax highlighting and styling for Pmpe
*/
class PmpeLineStyleListener implements LineStyleListener {
// Colors
private static final Color COMMENT_COLOR = Display.getCurrent().getSystemColor(
SWT.COLOR_DARK_GREEN);
private static final Color COMMENT_BACKGROUND = Display.getCurrent().getSystemColor(
SWT.COLOR_GRAY);
private static final Color PUNCTUATION_COLOR = Display.getCurrent().getSystemColor(
SWT.COLOR_DARK_CYAN);
private static final Color KEYWORD_COLOR = Display.getCurrent().getSystemColor(
SWT.COLOR_DARK_MAGENTA);
// Holds the syntax data
private SyntaxData syntaxData;
// Holds the offsets for all multiline comments
List commentOffsets;
/**
* PmpeLineStyleListener constructor
*
* @param syntaxData
* the syntax data to use
*/
public PmpeLineStyleListener(SyntaxData syntaxData) {
this.syntaxData = syntaxData;
commentOffsets = new LinkedList();
}
/**
* Refreshes the offsets for all multiline comments in the parent StyledText.
* The parent StyledText should call this whenever its text is modified. Note
* that this code doesn"t ignore comment markers inside strings.
*
* @param text
* the text from the StyledText
*/
public void refreshMultilineComments(String text) {
// Clear any stored offsets
commentOffsets.clear();
if (syntaxData != null) {
// Go through all the instances of COMMENT_START
for (int pos = text.indexOf(syntaxData.getMultiLineCommentStart()); pos > -1; pos = text
.indexOf(syntaxData.getMultiLineCommentStart(), pos)) {
// offsets[0] holds the COMMENT_START offset
// and COMMENT_END holds the ending offset
int[] offsets = new int[2];
offsets[0] = pos;
// Find the corresponding end comment.
pos = text.indexOf(syntaxData.getMultiLineCommentEnd(), pos);
// If no corresponding end comment, use the end of the text
offsets[1] = pos == -1 ? text.length() - 1 : pos
+ syntaxData.getMultiLineCommentEnd().length() - 1;
pos = offsets[1];
// Add the offsets to the collection
commentOffsets.add(offsets);
}
}
}
/**
* Checks to see if the specified section of text begins inside a multiline
* comment. Returns the index of the closing comment, or the end of the line
* if the whole line is inside the comment. Returns -1 if the line doesn"t
* begin inside a comment.
*
* @param start
* the starting offset of the text
* @param length
* the length of the text
* @return int
*/
private int getBeginsInsideComment(int start, int length) {
// Assume section doesn"t being inside a comment
int index = -1;
// Go through the multiline comment ranges
for (int i = 0, n = commentOffsets.size(); i < n; i++) {
int[] offsets = (int[]) commentOffsets.get(i);
// If starting offset is past range, quit
if (offsets[0] > start + length)
break;
// Check to see if section begins inside a comment
if (offsets[0] <= start && offsets[1] >= start) {
// It does; determine if the closing comment marker is inside
// this section
index = offsets[1] > start + length ? start + length : offsets[1]
+ syntaxData.getMultiLineCommentEnd().length() - 1;
}
}
return index;
}
/**
* Called by StyledText to get styles for a line
*/
public void lineGetStyle(LineStyleEvent event) {
// Only do styles if syntax data has been loaded
if (syntaxData != null) {
// Create collection to hold the StyleRanges
List styles = new ArrayList();
int start = 0;
int length = event.lineText.length();
// Check if line begins inside a multiline comment
int mlIndex = getBeginsInsideComment(event.lineOffset, event.lineText.length());
if (mlIndex > -1) {
// Line begins inside multiline comment; create the range
styles.add(new StyleRange(event.lineOffset, mlIndex - event.lineOffset, COMMENT_COLOR,
COMMENT_BACKGROUND));
start = mlIndex;
}
// Do punctuation, single-line comments, and keywords
while (start < length) {
// Check for multiline comments that begin inside this line
if (event.lineText.indexOf(syntaxData.getMultiLineCommentStart(), start) == start) {
// Determine where comment ends
int endComment = event.lineText.indexOf(syntaxData.getMultiLineCommentEnd(), start);
// If comment doesn"t end on this line, extend range to end of line
if (endComment == -1)
endComment = length;
else
endComment += syntaxData.getMultiLineCommentEnd().length();
styles.add(new StyleRange(event.lineOffset + start, endComment - start, COMMENT_COLOR,
COMMENT_BACKGROUND));
// Move marker
start = endComment;
}
// Check for single line comments
else if (event.lineText.indexOf(syntaxData.getComment(), start) == start) {
// Comment rest of line
styles.add(new StyleRange(event.lineOffset + start, length - start, COMMENT_COLOR,
COMMENT_BACKGROUND));
// Move marker
start = length;
}
// Check for punctuation
else if (syntaxData.getPunctuation().indexOf(event.lineText.charAt(start)) > -1) {
// Add range for punctuation
styles.add(new StyleRange(event.lineOffset + start, 1, PUNCTUATION_COLOR, null));
++start;
} else if (Character.isLetter(event.lineText.charAt(start))) {
// Get the next word
StringBuffer buf = new StringBuffer();
int i = start;
// Call any consecutive letters a word
for (; i < length && Character.isLetter(event.lineText.charAt(i)); i++) {
buf.append(event.lineText.charAt(i));
}
// See if the word is a keyword
if (syntaxData.getKeywords().contains(buf.toString())) {
// It"s a keyword; create the StyleRange
styles.add(new StyleRange(event.lineOffset + start, i - start, KEYWORD_COLOR, null,
SWT.BOLD));
}
// Move the marker to the last char (the one that wasn"t a letter)
// so it can be retested in the next iteration through the loop
start = i;
} else
// It"s nothing we"re interested in; advance the marker
++start;
}
// Copy the StyleRanges back into the event
event.styles = (StyleRange[]) styles.toArray(new StyleRange[0]);
}
}
}
Create a StyledText that scrolls vertically, wraps text, and displays a border:
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextCreate {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText text = new StyledText(shell, SWT.V_SCROLL | SWT.WRAP | SWT.BORDER);
text.setBounds(10,10,100,100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Creating a StyledText Widget
StyledText(Composite parent, int style)
StyledText Styles
ConstantDescriptionSWT.BORDERDraws a border around the StyledText.SWT.SINGLECreates a single-line StyledText.SWT.MULTICreates a multiline StyledText. This is the default.SWT.H_SCROLLEnables horizontal scrolling.SWT.V_SCROLLEnables vertical scrolling.SWT.WRAPTurns on word wrapping, trumping the horizontal scrolling style.SWT.READ_ONLYMakes the StyledText read-only.SWT.FULL_SELECTIONCauses redrawing operations to redraw the full line instead of only the invalidated portion.
Draw a box around text
/*******************************************************************************
* Copyright (c) 2000, 2006 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
//package org.eclipse.swt.snippets;
/*
* StyledText snippet: Draw a box around text.
*
* For a list of all SWT example snippets see
* http://www.eclipse.org/swt/snippets/
*/
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class TextAroundBox {
static String SEARCH_STRING = "box";
public static void main(String[] args) {
final Display display = new Display();
final Color RED = display.getSystemColor(SWT.COLOR_RED);
Shell shell = new Shell(display);
shell.setBounds(10, 10, 250, 250);
final StyledText text = new StyledText(shell, SWT.NONE);
text.setBounds(10, 10, 200, 200);
text.addListener(SWT.Paint, new Listener() {
public void handleEvent(Event event) {
String contents = text.getText();
int stringWidth = event.gc.stringExtent(SEARCH_STRING).x;
int lineHeight = text.getLineHeight();
event.gc.setForeground(RED);
int index = contents.indexOf(SEARCH_STRING);
while (index != -1) {
Point topLeft = text.getLocationAtOffset(index);
event.gc.drawRectangle(topLeft.x - 1, topLeft.y, stringWidth + 1, lineHeight - 1);
index = contents.indexOf(SEARCH_STRING, index + 1);
}
}
});
text
.setText("This demonstrates drawing a box\naround every occurrence of the word\nbox in the StyledText");
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
Getting Statistics: Caret Offset, Total Lines of Text, Total Characters and Current Line
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextStatistics {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.setText("12345");
System.out.println("Caret Offset: " + styledText.getCaretOffset());
System.out.println("Total Lines of Text: " + styledText.getLineCount());
System.out.println("Total Characters: " + styledText.getCharCount());
System.out.println("Current Line: " + (styledText.getLineAtOffset(styledText.getCaretOffset()) + 1));
styledText.setBounds(10,10,100,100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Limit the number of characters that the StyledText accepts
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextLimit {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.setText("12345");
styledText.setTextLimit(10);
styledText.setBounds(10, 10, 100, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Make a StyledText read-only
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextReadOnly {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.setText("12345");
styledText.setEditable(false);
styledText.setBounds(10, 10, 100, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Print StyledText out
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextPrint {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.setText("12345");
styledText.print();
styledText.setBounds(10,10,100,100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Print to the default printer in a separate thread
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextPrintSeparateThread {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.print(new Printer()).run();
styledText.setBounds(10,10,100,100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Replace Text Range
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextReplaceTextRange {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
final StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.setText("12345");
styledText.replaceTextRange(2, 3, "A");
styledText.setBounds(10, 10, 100, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Set page format for printing
- print the name of the file on top of each page,
- print the page number at the bottom of each page,
- print the word "Confidential" in the lower-right corner,
- print the text in the appropriate colors and styles
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextPrintOptions;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextPrintFormat {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText styledText = new StyledText(shell, SWT.V_SCROLL | SWT.BORDER);
styledText.setText("12345");
StyledTextPrintOptions options = new StyledTextPrintOptions();
options.header = StyledTextPrintOptions.SEPARATOR + "myfile.txt"
+ StyledTextPrintOptions.SEPARATOR;
options.footer = StyledTextPrintOptions.SEPARATOR + StyledTextPrintOptions.PAGE_TAG
+ StyledTextPrintOptions.SEPARATOR + "Confidential";
options.printLineBackground = true;
options.printTextBackground = true;
options.printTextFontStyle = true;
options.printTextForeground = true;
styledText.print(new Printer(), options).run();
styledText.setBounds(10, 10, 100, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
StyledText: embed controls
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
//package org.eclipse.swt.snippets;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.PaintObjectEvent;
import org.eclipse.swt.custom.PaintObjectListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GlyphMetrics;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.rubo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* StyledText snippet: embed controls
*
* For a list of all SWT example snippets see
* http://www.eclipse.org/swt/snippets/
*
* @since 3.2
*/
public class StyledTextEmbebControls {
static StyledText styledText;
static String text = "This snippet shows how to embed widgets in a StyledText.\n"
+ "Here is one: \uFFFC, and here is another: \uFFFC.";
static int[] offsets;
static Control[] controls;
static int MARGIN = 5;
static void addControl(Control control, int offset) {
StyleRange style = new StyleRange();
style.start = offset;
style.length = 1;
control.pack();
Rectangle rect = control.getBounds();
int ascent = 2 * rect.height / 3;
int descent = rect.height - ascent;
style.metrics = new GlyphMetrics(ascent + MARGIN, descent + MARGIN, rect.width + 2 * MARGIN);
styledText.setStyleRange(style);
}
public static void main(String[] args) {
final Display display = new Display();
Font font = new Font(display, "Tahoma", 32, SWT.NORMAL);
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
styledText = new StyledText(shell, SWT.WRAP | SWT.BORDER);
styledText.setFont(font);
styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
styledText.setText(text);
controls = new Control[2];
Button button = new Button(styledText, SWT.PUSH);
button.setText("Button 1");
controls[0] = button;
Combo combo = new Combo(styledText, SWT.NONE);
combo.add("item 1");
combo.add("another item");
controls[1] = combo;
offsets = new int[controls.length];
int lastOffset = 0;
for (int i = 0; i < controls.length; i++) {
int offset = text.indexOf("\uFFFC", lastOffset);
offsets[i] = offset;
addControl(controls[i], offsets[i]);
lastOffset = offset + 1;
}
// use a verify listener to keep the offsets up to date
styledText.addVerifyListener(new VerifyListener() {
public void verifyText(VerifyEvent e) {
int start = e.start;
int replaceCharCount = e.end - e.start;
int newCharCount = e.text.length();
for (int i = 0; i < offsets.length; i++) {
int offset = offsets[i];
if (start <= offset && offset < start + replaceCharCount) {
// this widget is being deleted from the text
if (controls[i] != null && !controls[i].isDisposed()) {
controls[i].dispose();
controls[i] = null;
}
offset = -1;
}
if (offset != -1 && offset >= start)
offset += newCharCount - replaceCharCount;
offsets[i] = offset;
}
}
});
// reposition widgets on paint event
styledText.addPaintObjectListener(new PaintObjectListener() {
public void paintObject(PaintObjectEvent event) {
StyleRange style = event.style;
int start = style.start;
for (int i = 0; i < offsets.length; i++) {
int offset = offsets[i];
if (start == offset) {
Point pt = controls[i].getSize();
int x = event.x + MARGIN;
int y = event.y + event.ascent - 2 * pt.y / 3;
controls[i].setLocation(x, y);
break;
}
}
}
});
shell.setSize(400, 400);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
font.dispose();
display.dispose();
}
}
StyledText: embed images
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
//package org.eclipse.swt.snippets;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.PaintObjectEvent;
import org.eclipse.swt.custom.PaintObjectListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.GlyphMetrics;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
/**
* StyledText snippet: embed images
*
* For a list of all SWT example snippets see
* http://www.eclipse.org/swt/snippets/
*
* @since 3.2
*/
public class StyledTextEmbedImages {
static StyledText styledText;
static String text = "This snippet shows how to embed images in a StyledText.\n"
+ "Here is one: \uFFFC, and here is another: \uFFFC."
+ "Use the add button to add an image from your filesystem to the StyledText at the current caret offset.";
static Image[] images;
static int[] offsets;
static void addImage(Image image, int offset) {
StyleRange style = new StyleRange();
style.start = offset;
style.length = 1;
Rectangle rect = image.getBounds();
style.metrics = new GlyphMetrics(rect.height, 0, rect.width);
styledText.setStyleRange(style);
}
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
styledText = new StyledText(shell, SWT.WRAP | SWT.BORDER);
styledText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
styledText.setText(text);
images = new Image[] { display.getSystemImage(SWT.ICON_QUESTION),
display.getSystemImage(SWT.ICON_INFORMATION), };
offsets = new int[images.length];
int lastOffset = 0;
for (int i = 0; i < images.length; i++) {
int offset = text.indexOf("\uFFFC", lastOffset);
offsets[i] = offset;
addImage(images[i], offset);
lastOffset = offset + 1;
}
// use a verify listener to keep the offsets up to date
styledText.addVerifyListener(new VerifyListener() {
public void verifyText(VerifyEvent e) {
int start = e.start;
int replaceCharCount = e.end - e.start;
int newCharCount = e.text.length();
for (int i = 0; i < offsets.length; i++) {
int offset = offsets[i];
if (start <= offset && offset < start + replaceCharCount) {
// this image is being deleted from the text
if (images[i] != null && !images[i].isDisposed()) {
images[i].dispose();
images[i] = null;
}
offset = -1;
}
if (offset != -1 && offset >= start)
offset += newCharCount - replaceCharCount;
offsets[i] = offset;
}
}
});
styledText.addPaintObjectListener(new PaintObjectListener() {
public void paintObject(PaintObjectEvent event) {
GC gc = event.gc;
StyleRange style = event.style;
int start = style.start;
for (int i = 0; i < offsets.length; i++) {
int offset = offsets[i];
if (start == offset) {
Image image = images[i];
int x = event.x;
int y = event.y + event.ascent - style.metrics.ascent;
gc.drawImage(image, x, y);
}
}
}
});
Button button = new Button(shell, SWT.PUSH);
button.setText("Add Image");
button.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
button.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
FileDialog dialog = new FileDialog(shell);
String filename = dialog.open();
if (filename != null) {
try {
Image image = new Image(display, filename);
int offset = styledText.getCaretOffset();
styledText.replaceTextRange(offset, 0, "\uFFFC");
int index = 0;
while (index < offsets.length) {
if (offsets[index] == -1 && images[index] == null)
break;
index++;
}
if (index == offsets.length) {
int[] tmpOffsets = new int[index + 1];
System.arraycopy(offsets, 0, tmpOffsets, 0, offsets.length);
offsets = tmpOffsets;
Image[] tmpImages = new Image[index + 1];
System.arraycopy(images, 0, tmpImages, 0, images.length);
images = tmpImages;
}
offsets[index] = offset;
images[index] = image;
addImage(image, offset);
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
shell.setSize(400, 400);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
for (int i = 0; i < images.length; i++) {
Image image = images[i];
if (image != null && !image.isDisposed()) {
image.dispose();
}
}
display.dispose();
}
}
StyledText: use gradient background
/*******************************************************************************
* Copyright (c) 2000, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
//package org.eclipse.swt.snippets;
/*
* SWT StyledText snippet: use gradient background.
*
* For a list of all SWT example snippets see
* http://www.eclipse.org/swt/snippets/
*
* @since 3.2
*/
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
public class StyledTextGradientBackground {
static String text = "Plans do not materialize out of nowhere, nor are they entirely static. To ensure the planning process is "
+ "transparent and open to the entire Eclipse community, we (the Eclipse PMC) post plans in an embryonic "
+ "form and revise them throughout the release cycle. \n"
+ "The first part of the plan deals with the important matters of release deliverables, release milestones, target "
+ "operating environments, and release-to-release compatibility. These are all things that need to be clear for "
+ "any release, even if no features were to change. \n";
static Image oldImage;
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
final StyledText styledText = new StyledText(shell, SWT.WRAP | SWT.BORDER);
styledText.setText(text);
FontData data = display.getSystemFont().getFontData()[0];
Font font = new Font(display, data.getName(), 16, SWT.BOLD);
styledText.setFont(font);
styledText.setForeground(display.getSystemColor(SWT.COLOR_BLUE));
styledText.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
Rectangle rect = styledText.getClientArea();
Image newImage = new Image(display, 1, Math.max(1, rect.height));
GC gc = new GC(newImage);
gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
gc.setBackground(display.getSystemColor(SWT.COLOR_YELLOW));
gc.fillGradientRectangle(rect.x, rect.y, 1, rect.height, true);
gc.dispose();
styledText.setBackgroundImage(newImage);
if (oldImage != null)
oldImage.dispose();
oldImage = newImage;
}
});
shell.setSize(700, 400);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
if (oldImage != null)
oldImage.dispose();
font.dispose();
display.dispose();
}
}
Understanding the Repercussions
When you use a LineStyleListener , you shouldn"t use the following API calls:
- getStyleRangeAtOffset(int offset)
- StyleRange[] getStyleRanges()
- void replaceStyleRanges(int start, int length, StyleRange[] ranges)
- void setStyleRange(StyleRange range)
- void setStyleRanges(StyleRange[] ranges)
Mixing these API calls with a LineStyleListener is unsupported. (The Definitive Guide to SWT and JFace by Robert Harris and Rob Warner Apress 2004 )
Using the Clipboard
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class StyledTextClipboard {
public static void main(String[] args) {
final Display display = new Display();
final Shell shell = new Shell(display);
StyledText text1 = new StyledText(shell, SWT.V_SCROLL | SWT.WRAP | SWT.BORDER);
StyledText text2 = new StyledText(shell, SWT.V_SCROLL | SWT.WRAP | SWT.BORDER);
text1.setText("1234567");
text1.setSelectionRange(2,4);
text1.cut();
text2.paste();
text1.setBounds(10,10,100,100);
text2.setBounds(10,300,100,100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}