Java/SWT JFace Eclipse/Editor
Содержание
Basic Editor
/*******************************************************************************
* All Right Reserved. Copyright (c) 1998, 2004 Jackwind Li Guojie
*
* Created on Feb 23, 2004 8:40:41 PM by JACK $Id$
*
******************************************************************************/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
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.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
public class BasicEditor {
Display display = new Display();
Shell shell = new Shell(display);
// The control used for text displaying and editing.
StyledText text;
// Is there any changes since last saving action?
boolean hasUnsavedChanges;
// The file associated with current text content.
File file;
// The recent directory
private String lastOpenDirectory;
// The name of this program.
public static final String APP_NAME = "BasicEditor v1.0";
MenuItem miWrap = null;
public BasicEditor() {
shell.setLayout(new GridLayout());
// Add a tool bar.
ToolBar toolBar = new ToolBar(shell, SWT.FLAT | SWT.RIGHT );
ToolItem tiNew = new ToolItem(toolBar, SWT.PUSH);
tiNew.setText("&New");
tiNew.setImage(getImage("jexp.gif"));
tiNew.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(handleChangesBeforeDiscard()) {
file = null;
text.setText("");
}
}
});
ToolItem tiOpen = new ToolItem(toolBar, SWT.PUSH);
tiOpen.setText("&Open");
tiOpen.setImage(getImage("open.gif"));
tiOpen.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(handleChangesBeforeDiscard())
loadTextFromFile();
}
});
ToolItem tiSave = new ToolItem(toolBar, SWT.PUSH);
tiSave.setText("&Save");
tiSave.setImage(getImage("save.gif"));
tiSave.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
saveTextToFile();
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
ToolItem tiCopy = new ToolItem(toolBar, SWT.PUSH);
tiCopy.setText("&Copy");
tiCopy.setImage(getImage("copy.gif"));
tiCopy.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.copy();
}
});
ToolItem tiCut = new ToolItem(toolBar, SWT.PUSH);
tiCut.setText("Cu&t");
tiCut.setImage(getImage("cut.gif"));
tiCut.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.cut();
}
});
ToolItem tiPaste = new ToolItem(toolBar, SWT.PUSH);
tiPaste.setText("&Paste");
tiPaste.setImage(getImage("paste.gif"));
tiPaste.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.paste();
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
final ToolItem tiWrap = new ToolItem(toolBar, SWT.CHECK);
tiWrap.setText("&Wrap");
tiWrap.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.setWordWrap(tiWrap.getSelection());
miWrap.setSelection(tiWrap.getSelection());
}
});
toolBar.pack();
System.out.println("Client area: " + shell.getClientArea());
text =
new StyledText(
shell,
SWT.MULTI
| SWT.WRAP
| SWT.BORDER
| SWT.H_SCROLL
| SWT.V_SCROLL);
text.setLayoutData(new GridData(GridData.FILL_BOTH));
Font font = new Font(shell.getDisplay(), "Courier New", 10, SWT.NORMAL);
text.setFont(font);
text.setText("BasicEditor version 1.0\r\nWriten by Jack Li Guojie. ");
text.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
hasUnsavedChanges = true;
}
});
// Add menus.
Menu menuBar = new Menu(shell, SWT.BAR);
// --- sub menu: File
MenuItem fileMenuItem = new MenuItem(menuBar, SWT.CASCADE);
fileMenuItem.setText("&File");
Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem miNew = new MenuItem(fileMenu, SWT.PUSH);
miNew.setText("&New\tCtrl+N");
miNew.setImage(getImage("new.gif"));
miNew.setAccelerator(SWT.CTRL + "N");
miNew.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(handleChangesBeforeDiscard()) {
file = null;
text.setText("");
}
}
});
MenuItem miOpen = new MenuItem(fileMenu, SWT.PUSH);
miOpen.setText("&Open\tCtrl+O");
miOpen.setAccelerator(SWT.CTRL + "O");
miOpen.setImage(getImage("open.gif"));
miOpen.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(handleChangesBeforeDiscard())
loadTextFromFile();
}
});
MenuItem miSave = new MenuItem(fileMenu, SWT.PUSH);
miSave.setText("&Save\tCtrl+S");
miSave.setImage(getImage("save.gif"));
miSave.setAccelerator(SWT.CTRL + "S");
miSave.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
saveTextToFile();
}
});
new MenuItem(fileMenu, SWT.SEPARATOR);
MenuItem miExit = new MenuItem(fileMenu, SWT.PUSH);
miExit.setText("&Exit");
miExit.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if(handleChangesBeforeDiscard())
shell.dispose();
}
});
fileMenuItem.setMenu(fileMenu);
// --- sub menu: Edit.
MenuItem editMenuItem = new MenuItem(menuBar, SWT.CASCADE);
editMenuItem.setText("&Edit");
Menu editMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem miCopy = new MenuItem(editMenu, SWT.PUSH);
miCopy.setText("&Copy\tCtrl+C");
miCopy.setImage(getImage("copy.gif"));
miCopy.setAccelerator(SWT.CTRL + "C");
miCopy.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.copy();
}
});
MenuItem miCut = new MenuItem(editMenu, SWT.PUSH);
miCut.setText("Cu&t\tCtrl+X");
miCut.setImage(getImage("cut.gif"));
miCut.setAccelerator(SWT.CTRL + "X");
miCut.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.cut();
}
});
MenuItem miPaste = new MenuItem(editMenu, SWT.PUSH);
miPaste.setText("&Paste\tCtrl+P");
miPaste.setImage(getImage("paste.gif"));
miPaste.setAccelerator(SWT.CTRL + "P");
miPaste.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.paste();
}
});
editMenuItem.setMenu(editMenu);
// --- sub menu: Format.
MenuItem formatMenuItem = new MenuItem(menuBar, SWT.CASCADE);
formatMenuItem.setText("&Format");
Menu formatMenu = new Menu(shell, SWT.DROP_DOWN);
miWrap = new MenuItem(formatMenu, SWT.CHECK);
miWrap.setText("&Wrap\tCtrl+W");
miWrap.setAccelerator(SWT.CTRL + "W");
miWrap.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
text.setWordWrap(miWrap.getSelection());
tiWrap.setSelection(miWrap.getSelection());
}
});
formatMenuItem.setMenu(formatMenu);
// Add the menu bar to the shell.
shell.setMenuBar(menuBar);
shell.setSize(400, 200);
shell.open();
// Set up the event loop.
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
// If no more entries in event queue
display.sleep();
}
}
display.dispose();
}
ImageRegistry imageRegistry = new ImageRegistry();
/**
* Retrieves the image corresponding to the given file name.
* Note that the image is managed by an image registry. You should not
* dispose the image after use.
* @param shortFileName
* @return
*/
private Image getImage(String shortFileName) {
if(imageRegistry.getDescriptor(shortFileName) == null) {
ImageDescriptor descriptor = ImageDescriptor.createFromFile(null, "icons/" + shortFileName);
imageRegistry.put(shortFileName, descriptor);
}
return imageRegistry.get(shortFileName);
}
/**
* Hands unsaved changes before the text is discarded.
* @return whether furthur action should be carried on.
*/
boolean handleChangesBeforeDiscard() {
if(! hasUnsavedChanges)
return true;
MessageBox messageBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.YES | SWT.NO | SWT.CANCEL);
messageBox.setMessage("Do you want to save the changes to " + (file == null ? "a file?" : file.getName()));
messageBox.setText(APP_NAME);
int ret = messageBox.open();
if(ret == SWT.YES) {
return saveTextToFile();
}else if(ret == SWT.NO) {
return true;
}else{
return false;
}
}
/**
* Loads the text from a file selected by the user.
* @return the status of the operation.
*/
boolean loadTextFromFile() {
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
if (lastOpenDirectory != null)
dialog.setFilterPath(lastOpenDirectory);
String selectedFile = dialog.open();
if (selectedFile == null) {
log("Action cancelled: loading the text from a file");
return false;
}
file = new File(selectedFile);
lastOpenDirectory = file.getParent();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String line = null;
while((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
text.setText(sb.toString());
return true;
}catch(IOException e) {
log("Failed to load the text from file: " + file);
log(e.toString());
}
return false;
}
/**
* Saves the content of the styled text to the file. If the file has
* not been specified yet, a FileDialog prompts up for the user to
* select a file.
* @return the status of the operation.
* @throws IOException
*/
boolean saveTextToFile() {
if (file == null) {
FileDialog dialog = new FileDialog(shell, SWT.SAVE);
if (lastOpenDirectory != null)
dialog.setFilterPath(lastOpenDirectory);
String selectedFile = dialog.open();
if (selectedFile == null) {
log("Action cancelled: saving the text to a file");
return false;
}
file = new File(selectedFile);
lastOpenDirectory = file.getParent();
}
try {
FileWriter writer = new FileWriter(file);
writer.write(text.getText());
writer.close();
log("The text has been saved to file: " + file);
hasUnsavedChanges = false;
return true;
} catch (IOException e) {
log("Failed to save the text to file: " + file);
log(e.toString());
}
return false;
}
/**
* Logs system messages.
*
* @param message
*/
void log(String message) {
System.out.println(message);
}
public static void main(String[] args) {
new BasicEditor();
}
}
Basic Editor 2
/*******************************************************************************
* All Right Reserved. Copyright (c) 1998, 2004 Jackwind Li Guojie
*
* Created on Feb 23, 2004 8:40:41 PM by JACK $Id$
*
******************************************************************************/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Decorations;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
public class BasicEditor2 {
Display display = new Display();
Shell shell = new Shell(display);
// The control used for text displaying and editing.
StyledText text;
// Is there any changes since last saving action?
boolean hasUnsavedChanges;
// The file associated with current text content.
File file;
// The recent directory
private String lastOpenDirectory;
// The name of this program.
public static final String APP_NAME = "BasicEditor v2.0";
MenuItem miWrap = null;
public BasicEditor2() {
// Action: create new text.
Action actionNew =
new Action(
"&New",
ImageDescriptor.createFromFile(null, "icons/new.gif")) {
public void run() {
if (handleChangesBeforeDiscard()) {
file = null;
text.setText("");
}
}
};
actionNew.setAccelerator(SWT.CTRL + "N");
// Action: open a text file.
Action actionOpen =
new Action(
"&Open",
ImageDescriptor.createFromFile(null, "icons/open.gif")) {
public void run() {
if (handleChangesBeforeDiscard())
loadTextFromFile();
}
};
actionOpen.setAccelerator(SWT.CTRL + "O");
// Action: save the text to a file.
Action actionSave =
new Action(
"&Save\tCtrl+S",
ImageDescriptor.createFromFile(null, "icons/save.gif")) {
public void run() {
saveTextToFile();
}
};
//actionSave.setAccelerator(SWT.CTRL + "S");
// Action: copy selected text.
Action actionCopy =
new Action(
"&Copy",
ImageDescriptor.createFromFile(null, "icons/copy.gif")) {
public void run() {
text.copy();
}
};
actionCopy.setAccelerator(SWT.CTRL + "C");
// Separator.
// Action: cut the selected text.
Action actionCut =
new Action(
"Cu&t",
ImageDescriptor.createFromFile(null, "icons/cut.gif")) {
public void run() {
text.cut();
}
};
actionCut.setAccelerator(SWT.CTRL + "X");
// Action: paste the text on clipboard.
Action actionPaste =
new Action(
"&Paste",
ImageDescriptor.createFromFile(null, "icons/paste.gif")) {
public void run() {
text.paste();
}
};
actionPaste.setAccelerator(SWT.CTRL + "P");
// Separator.
// Action: set wrap property.
Action actionWrap =
new Action(
"&Wrap", IAction.AS_CHECK_BOX) {
public void run() {
text.setWordWrap(isChecked());
}
};
actionWrap.setAccelerator(SWT.CTRL + "W");
// Action: exit.
Action actionExit = new Action("&Exit@Ctrl+X") {
public void run() {
if (handleChangesBeforeDiscard())
shell.dispose();
}
};
System.out.println(actionWrap.getText());
// Add a tool bar.
ToolBar toolBar = new ToolBar(shell, SWT.FLAT | SWT.RIGHT);
ToolBarManager toolBarManager = new ToolBarManager(toolBar);
toolBarManager.add(actionNew);
toolBarManager.add(actionOpen);
toolBarManager.add(actionSave);
toolBarManager.add(new Separator());
toolBarManager.add(actionCopy);
toolBarManager.add(actionCut);
toolBarManager.add(actionPaste);
toolBarManager.add(new Separator());
toolBarManager.add(actionWrap);
toolBarManager.update(true);
shell.setLayout(new GridLayout());
System.out.println("Client area: " + shell.getClientArea());
text =
new StyledText(
shell,
SWT.MULTI
| SWT.WRAP
| SWT.BORDER
| SWT.H_SCROLL
| SWT.V_SCROLL);
text.setLayoutData(new GridData(GridData.FILL_BOTH));
Font font = new Font(shell.getDisplay(), "Courier New", 10, SWT.NORMAL);
text.setFont(font);
text.setText("BasicEditor version 1.0\r\nWriten by Jack Li Guojie. ");
text.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
hasUnsavedChanges = true;
}
});
// Add menus.
MenuManager barMenuManager = new MenuManager();
MenuManager fileMenuManager = new MenuManager("&File");
MenuManager editMenuManager = new MenuManager("&Edit");
MenuManager formatMenuManager = new MenuManager("&Format");
barMenuManager.add(fileMenuManager);
barMenuManager.add(editMenuManager);
barMenuManager.add(formatMenuManager);
fileMenuManager.add(actionNew);
fileMenuManager.add(actionOpen);
fileMenuManager.add(actionSave);
fileMenuManager.add(new Separator());
fileMenuManager.add(actionExit);
editMenuManager.add(actionCopy);
editMenuManager.add(actionCut);
editMenuManager.add(actionPaste);
formatMenuManager.add(actionWrap);
// Add the menu bar to the shell.
// shell.setMenuBar(menuBar);
barMenuManager.updateAll(true);
shell.setMenuBar(barMenuManager.createMenuBar((Decorations)shell));
shell.setSize(400, 200);
shell.open();
// Set up the event loop.
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
// If no more entries in event queue
display.sleep();
}
}
display.dispose();
}
ImageRegistry imageRegistry = new ImageRegistry();
/**
* Retrieves the image corresponding to the given file name. Note that the
* image is managed by an image registry. You should not dispose the image
* after use.
*
* @param shortFileName
* @return
*/
private Image getImage(String shortFileName) {
if (imageRegistry.getDescriptor(shortFileName) == null) {
ImageDescriptor descriptor =
ImageDescriptor.createFromFile(null, "icons/" + shortFileName);
imageRegistry.put(shortFileName, descriptor);
}
return imageRegistry.get(shortFileName);
}
/**
* Hands unsaved changes before the text is discarded.
*
* @return whether furthur action should be carried on.
*/
boolean handleChangesBeforeDiscard() {
if (!hasUnsavedChanges)
return true;
MessageBox messageBox =
new MessageBox(
shell,
SWT.ICON_WARNING | SWT.YES | SWT.NO | SWT.CANCEL);
messageBox.setMessage(
"Do you want to save the changes to "
+ (file == null ? "a file?" : file.getName()));
messageBox.setText(APP_NAME);
int ret = messageBox.open();
if (ret == SWT.YES) {
return saveTextToFile();
} else if (ret == SWT.NO) {
return true;
} else {
return false;
}
}
/**
* Loads the text from a file selected by the user.
*
* @return the status of the operation.
*/
boolean loadTextFromFile() {
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
if (lastOpenDirectory != null)
dialog.setFilterPath(lastOpenDirectory);
String selectedFile = dialog.open();
if (selectedFile == null) {
log("Action cancelled: loading the text from a file");
return false;
}
file = new File(selectedFile);
lastOpenDirectory = file.getParent();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
text.setText(sb.toString());
return true;
} catch (IOException e) {
log("Failed to load the text from file: " + file);
log(e.toString());
}
return false;
}
/**
* Saves the content of the styled text to the file. If the file has not
* been specified yet, a FileDialog prompts up for the user to select a
* file.
*
* @return the status of the operation.
* @throws IOException
*/
boolean saveTextToFile() {
if (file == null) {
FileDialog dialog = new FileDialog(shell, SWT.SAVE);
if (lastOpenDirectory != null)
dialog.setFilterPath(lastOpenDirectory);
String selectedFile = dialog.open();
if (selectedFile == null) {
log("Action cancelled: saving the text to a file");
return false;
}
file = new File(selectedFile);
lastOpenDirectory = file.getParent();
}
try {
FileWriter writer = new FileWriter(file);
writer.write(text.getText());
writer.close();
log("The text has been saved to file: " + file);
hasUnsavedChanges = false;
return true;
} catch (IOException e) {
log("Failed to save the text to file: " + file);
log(e.toString());
}
return false;
}
/**
* Logs system messages.
*
* @param message
*/
void log(String message) {
System.out.println(message);
}
public static void main(String[] args) {
new BasicEditor2();
}
}
Basic Editor 3
/*******************************************************************************
* All Right Reserved. Copyright (c) 1998, 2004 Jackwind Li Guojie
*
* Created on Feb 23, 2004 8:40:41 PM by JACK $Id$
*
******************************************************************************/
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextPrintOptions;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Decorations;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
public class BasicEditor3 {
Display display = new Display();
Shell shell = new Shell(display);
// The control used for text displaying and editing.
StyledText text;
// Is there any changes since last saving action?
boolean hasUnsavedChanges;
// The file associated with current text content.
File file;
// The recent directory
private String lastOpenDirectory;
// The name of this program.
public static final String APP_NAME = "BasicEditor v3.0";
MenuItem miWrap = null;
public BasicEditor3() {
// Action: create new text.
Action actionNew =
new Action(
"&New",
ImageDescriptor.createFromFile(null, "jexp.gif")) {
public void run() {
if (handleChangesBeforeDiscard()) {
file = null;
text.setText("");
}
}
};
actionNew.setAccelerator(SWT.CTRL + "N");
// Action: open a text file.
Action actionOpen =
new Action(
"&Open",
ImageDescriptor.createFromFile(null, "icons/open.gif")) {
public void run() {
if (handleChangesBeforeDiscard())
loadTextFromFile();
}
};
actionOpen.setAccelerator(SWT.CTRL + "O");
// Action: save the text to a file.
Action actionSave =
new Action(
"&Save\tCtrl+S",
ImageDescriptor.createFromFile(null, "icons/save.gif")) {
public void run() {
saveTextToFile();
}
};
//actionSave.setAccelerator(SWT.CTRL + "S");
// Action: copy selected text.
Action actionCopy =
new Action(
"&Copy",
ImageDescriptor.createFromFile(null, "icons/copy.gif")) {
public void run() {
text.copy();
}
};
actionCopy.setAccelerator(SWT.CTRL + "C");
// Separator.
// Action: cut the selected text.
Action actionCut =
new Action(
"Cu&t",
ImageDescriptor.createFromFile(null, "icons/cut.gif")) {
public void run() {
text.cut();
}
};
actionCut.setAccelerator(SWT.CTRL + "X");
// Action: paste the text on clipboard.
Action actionPaste =
new Action(
"&Paste",
ImageDescriptor.createFromFile(null, "icons/paste.gif")) {
public void run() {
text.paste();
}
};
actionPaste.setAccelerator(SWT.CTRL + "P");
// Separator.
// Action: set wrap property.
Action actionWrap =
new Action(
"&Wrap", IAction.AS_CHECK_BOX) {
public void run() {
text.setWordWrap(isChecked());
}
};
actionWrap.setAccelerator(SWT.CTRL + "W");
// Action: exit.
Action actionExit = new Action("&Exit@Ctrl+X") {
public void run() {
if (handleChangesBeforeDiscard())
shell.dispose();
}
};
Action actionPrint = new Action("&Print@Ctrl+P") {
public void run() {
printText(text.getText());
}
};
Action actionPrint2 = new Action("Print (StyledText)") {
public void run() {
StyledTextPrintOptions options = new StyledTextPrintOptions();
options.header = "SWT";
options.footer = "Page <page>";
options.jobName = "Text";
Runnable runnable = text.print(new Printer(), options);
runnable.run();
}
};
// Add a tool bar.
ToolBar toolBar = new ToolBar(shell, SWT.FLAT | SWT.RIGHT);
ToolBarManager toolBarManager = new ToolBarManager(toolBar);
toolBarManager.add(actionNew);
toolBarManager.add(actionOpen);
toolBarManager.add(actionSave);
toolBarManager.add(new Separator());
toolBarManager.add(actionCopy);
toolBarManager.add(actionCut);
toolBarManager.add(actionPaste);
toolBarManager.add(new Separator());
toolBarManager.add(actionWrap);
toolBarManager.add(new Separator());
toolBarManager.add(actionPrint);
toolBarManager.add(actionPrint2);
toolBarManager.update(true);
shell.setText(APP_NAME);
shell.setLayout(new GridLayout());
text =
new StyledText(
shell,
SWT.MULTI
| SWT.WRAP
| SWT.BORDER
| SWT.H_SCROLL
| SWT.V_SCROLL);
text.setLayoutData(new GridData(GridData.FILL_BOTH));
Font font = new Font(shell.getDisplay(), "Courier New", 10, SWT.NORMAL);
text.setFont(font);
text.setText("BasicEditor version 3.0\r\nWriten by Jack Li Guojie. ");
text.addModifyListener(new ModifyListener() {
public void modifyText(ModifyEvent e) {
hasUnsavedChanges = true;
}
});
// Add menus.
MenuManager barMenuManager = new MenuManager();
MenuManager fileMenuManager = new MenuManager("&File");
MenuManager editMenuManager = new MenuManager("&Edit");
MenuManager formatMenuManager = new MenuManager("&Format");
barMenuManager.add(fileMenuManager);
barMenuManager.add(editMenuManager);
barMenuManager.add(formatMenuManager);
fileMenuManager.add(actionNew);
fileMenuManager.add(actionOpen);
fileMenuManager.add(actionSave);
fileMenuManager.add(actionPrint);
fileMenuManager.add(new Separator());
fileMenuManager.add(actionExit);
editMenuManager.add(actionCopy);
editMenuManager.add(actionCut);
editMenuManager.add(actionPaste);
formatMenuManager.add(actionWrap);
// Add the menu bar to the shell.
// shell.setMenuBar(menuBar);
barMenuManager.updateAll(true);
shell.setMenuBar(barMenuManager.createMenuBar((Decorations)shell));
shell.setSize(400, 200);
shell.open();
// Set up the event loop.
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
// If no more entries in event queue
display.sleep();
}
}
display.dispose();
}
int x;
int y;
int lineHeight;
PrintMargin margins;
int pageNumber = 1;
int lineNumber = 1;
void printText(String text) {
PrintDialog dialog = new PrintDialog(shell);
PrinterData printerData = dialog.open();
if(printerData == null)
return;
Printer printer = new Printer(printerData);
if(! printer.startJob("text"))
return;
GC gc = new GC(printer);
margins = PrintMargin.getPrintMargin(printer, 1.0);
x = margins.left;
y = margins.top;
StringBuffer buffer = new StringBuffer();
Font font = new Font(printer, "Arial", 12, SWT.NORMAL);
gc.setFont(font);
lineHeight = gc.getFontMetrics().getHeight();
printer.startPage();
// prints page number at the bottom margin.
String page = "- " + pageNumber + " -";
gc.drawString(page, (margins.right - margins.left - gc.textExtent(page).x) / 2 + margins.left, margins.bottom + gc.textExtent(page).y);
for(int index = 0; index <text.length();) {
char c = text.charAt(index);
switch(c) {
case "\r":
if(index < text.length() - 1 && text.charAt(index + 1) == "\n") {
printNewLine(printer, gc, buffer.toString());
buffer.setLength(0);
index += 2;
}
break;
case "\t":
case " ":
if(gc.textExtent(buffer.toString() + " ").x > margins.right - margins.left) {
printNewLine(printer, gc, buffer.toString());
buffer.setLength(0);
}
buffer.append(c);
if(index < text.length() - 1 && (!Character.isWhitespace(text.charAt(index + 1)))) { // Looks up one word to see whether the line should wraps here.
String word = readWord(text, index + 1);
if(gc.textExtent(buffer.toString() + word).x > margins.right - margins.left) {
printNewLine(printer, gc, buffer.toString());
buffer.setLength(0);
}
}
index += 1;
break;
default:
buffer.append(c);
index += 1;
}
}
if(buffer.length() > 0)
printNewLine(printer, gc, buffer.toString());
if(y + lineHeight <= margins.bottom)
printer.endPage();
printer.endJob();
gc.dispose();
font.dispose();
printer.dispose();
}
/**
* Prints the new line to page. If there is not enough vertical space,
* a new page is started.
* @param printer
* @param line
* @param x
* @param y
*/
void printNewLine(Printer printer, GC gc, String line) {
if(y + lineHeight > margins.bottom) {
printer.endPage();
x = margins.left;
y = margins.top;
pageNumber ++;
lineNumber = 1;
// prints page number at the bottom margin.
String page = "- " + pageNumber + " -";
gc.drawString(page, (margins.right - margins.left - gc.textExtent(page).x) / 2 + margins.left, margins.bottom + gc.textExtent(page).y);
}
gc.drawString(line, x, y);
y += lineHeight;
}
/**
* Reads a word from the given text starting from the offset.
* @param text
* @param offset
* @return
*/
String readWord(String text, int offset) {
StringBuffer sb = new StringBuffer();
int index = offset;
char c = 0;
while(index < text.length()) {
c = text.charAt(index);
if(Character.isWhitespace(c))
break;
sb.append(c);
index += 1;
}
return sb.toString();
}
ImageRegistry imageRegistry = new ImageRegistry();
/**
* Retrieves the image corresponding to the given file name. Note that the
* image is managed by an image registry. You should not dispose the image
* after use.
*
* @param shortFileName
* @return
*/
private Image getImage(String shortFileName) {
if (imageRegistry.getDescriptor(shortFileName) == null) {
ImageDescriptor descriptor =
ImageDescriptor.createFromFile(null, "icons/" + shortFileName);
imageRegistry.put(shortFileName, descriptor);
}
return imageRegistry.get(shortFileName);
}
/**
* Hands unsaved changes before the text is discarded.
*
* @return whether furthur action should be carried on.
*/
boolean handleChangesBeforeDiscard() {
if (!hasUnsavedChanges)
return true;
MessageBox messageBox =
new MessageBox(
shell,
SWT.ICON_WARNING | SWT.YES | SWT.NO | SWT.CANCEL);
messageBox.setMessage(
"Do you want to save the changes to "
+ (file == null ? "a file?" : file.getName()));
messageBox.setText(APP_NAME);
int ret = messageBox.open();
if (ret == SWT.YES) {
return saveTextToFile();
} else if (ret == SWT.NO) {
return true;
} else {
return false;
}
}
/**
* Loads the text from a file selected by the user.
*
* @return the status of the operation.
*/
boolean loadTextFromFile() {
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
if (lastOpenDirectory != null)
dialog.setFilterPath(lastOpenDirectory);
String selectedFile = dialog.open();
if (selectedFile == null) {
log("Action cancelled: loading the text from a file");
return false;
}
file = new File(selectedFile);
lastOpenDirectory = file.getParent();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuffer sb = new StringBuffer();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
sb.append("\r\n");
}
text.setText(sb.toString());
return true;
} catch (IOException e) {
log("Failed to load the text from file: " + file);
log(e.toString());
}
return false;
}
/**
* Saves the content of the styled text to the file. If the file has not
* been specified yet, a FileDialog prompts up for the user to select a
* file.
*
* @return the status of the operation.
* @throws IOException
*/
boolean saveTextToFile() {
if (file == null) {
FileDialog dialog = new FileDialog(shell, SWT.SAVE);
if (lastOpenDirectory != null)
dialog.setFilterPath(lastOpenDirectory);
String selectedFile = dialog.open();
if (selectedFile == null) {
log("Action cancelled: saving the text to a file");
return false;
}
file = new File(selectedFile);
lastOpenDirectory = file.getParent();
}
try {
FileWriter writer = new FileWriter(file);
writer.write(text.getText());
writer.close();
log("The text has been saved to file: " + file);
hasUnsavedChanges = false;
return true;
} catch (IOException e) {
log("Failed to save the text to file: " + file);
log(e.toString());
}
return false;
}
/**
* Logs system messages.
*
* @param message
*/
void log(String message) {
System.out.println(message);
}
public static void main(String[] args) {
new BasicEditor3();
}
}
Java Source code Viewer
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.ResourceBundle;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineStyleEvent;
import org.eclipse.swt.custom.LineStyleListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FileDialog;
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 JavaViewer {
Shell shell;
StyledText text;
JavaLineStyler lineStyler = new JavaLineStyler();
FileDialog fileDialog;
Menu createFileMenu() {
Menu bar = shell.getMenuBar();
Menu menu = new Menu(bar);
MenuItem item;
// Open
item = new MenuItem(menu, SWT.CASCADE);
item.setText("Open");
item.setAccelerator(SWT.MOD1 + "O");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
openFile();
}
});
// Exit
item = new MenuItem(menu, SWT.PUSH);
item.setText("Exit");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
menuFileExit();
}
});
return menu;
}
void createMenuBar() {
Menu bar = new Menu(shell, SWT.BAR);
shell.setMenuBar(bar);
MenuItem fileItem = new MenuItem(bar, SWT.CASCADE);
fileItem.setText("File");
fileItem.setMenu(createFileMenu());
}
void createShell(Display display) {
shell = new Shell(display);
shell.setText("Window");
GridLayout layout = new GridLayout();
layout.numColumns = 1;
shell.setLayout(layout);
shell.addShellListener(new ShellAdapter() {
public void shellClosed(ShellEvent e) {
lineStyler.disposeColors();
text.removeLineStyleListener(lineStyler);
}
});
}
void createStyledText() {
text = new StyledText(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL
| SWT.H_SCROLL);
GridData spec = new GridData();
spec.horizontalAlignment = GridData.FILL;
spec.grabExcessHorizontalSpace = true;
spec.verticalAlignment = GridData.FILL;
spec.grabExcessVerticalSpace = true;
text.setLayoutData(spec);
text.addLineStyleListener(lineStyler);
text.setEditable(false);
Color bg = Display.getDefault().getSystemColor(SWT.COLOR_GRAY);
text.setBackground(bg);
}
void displayError(String msg) {
MessageBox box = new MessageBox(shell, SWT.ICON_ERROR);
box.setMessage(msg);
box.open();
}
public static void main(String[] args) {
Display display = new Display();
JavaViewer example = new JavaViewer();
Shell shell = example.open(display);
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
public Shell open(Display display) {
createShell(display);
createMenuBar();
createStyledText();
shell.setSize(500, 400);
shell.open();
return shell;
}
void openFile() {
if (fileDialog == null) {
fileDialog = new FileDialog(shell, SWT.OPEN);
}
fileDialog.setFilterExtensions(new String[] { "*.java", "*.*" });
String name = fileDialog.open();
open(name);
}
void open(String name) {
final String textString;
if ((name == null) || (name.length() == 0))
return;
File file = new File(name);
if (!file.exists()) {
String message = "Err file no exist";
displayError(message);
return;
}
try {
FileInputStream stream = new FileInputStream(file.getPath());
try {
Reader in = new BufferedReader(new InputStreamReader(stream));
char[] readBuffer = new char[2048];
StringBuffer buffer = new StringBuffer((int) file.length());
int n;
while ((n = in.read(readBuffer)) > 0) {
buffer.append(readBuffer, 0, n);
}
textString = buffer.toString();
stream.close();
} catch (IOException e) {
// Err_file_io
String message = "Err_file_io";
displayError(message);
return;
}
} catch (FileNotFoundException e) {
String message = "Err_not_found";
displayError(message);
return;
}
// Guard against superfluous mouse move events -- defer action until
// later
Display display = text.getDisplay();
display.asyncExec(new Runnable() {
public void run() {
text.setText(textString);
}
});
// parse the block comments up front since block comments can go across
// lines - inefficient way of doing this
lineStyler.parseBlockComments(textString);
}
void menuFileExit() {
shell.close();
}
}
/*******************************************************************************
* Copyright (c) 2000, 2003 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
******************************************************************************/
class JavaLineStyler implements LineStyleListener {
JavaScanner scanner = new JavaScanner();
int[] tokenColors;
Color[] colors;
Vector blockComments = new Vector();
public static final int EOF = -1;
public static final int EOL = 10;
public static final int WORD = 0;
public static final int WHITE = 1;
public static final int KEY = 2;
public static final int COMMENT = 3;
public static final int STRING = 5;
public static final int OTHER = 6;
public static final int NUMBER = 7;
public static final int MAXIMUM_TOKEN = 8;
public JavaLineStyler() {
initializeColors();
scanner = new JavaScanner();
}
Color getColor(int type) {
if (type < 0 || type >= tokenColors.length) {
return null;
}
return colors[tokenColors[type]];
}
boolean inBlockComment(int start, int end) {
for (int i = 0; i < blockComments.size(); i++) {
int[] offsets = (int[]) blockComments.elementAt(i);
// start of comment in the line
if ((offsets[0] >= start) && (offsets[0] <= end))
return true;
// end of comment in the line
if ((offsets[1] >= start) && (offsets[1] <= end))
return true;
if ((offsets[0] <= start) && (offsets[1] >= end))
return true;
}
return false;
}
void initializeColors() {
Display display = Display.getDefault();
colors = new Color[] { new Color(display, new RGB(0, 0, 0)), // black
new Color(display, new RGB(255, 0, 0)), // red
new Color(display, new RGB(0, 255, 0)), // green
new Color(display, new RGB(0, 0, 255)) // blue
};
tokenColors = new int[MAXIMUM_TOKEN];
tokenColors[WORD] = 0;
tokenColors[WHITE] = 0;
tokenColors[KEY] = 3;
tokenColors[COMMENT] = 1;
tokenColors[STRING] = 2;
tokenColors[OTHER] = 0;
tokenColors[NUMBER] = 0;
}
void disposeColors() {
for (int i = 0; i < colors.length; i++) {
colors[i].dispose();
}
}
/**
* Event.detail line start offset (input) Event.text line text (input)
* LineStyleEvent.styles Enumeration of StyleRanges, need to be in order.
* (output) LineStyleEvent.background line background color (output)
*/
public void lineGetStyle(LineStyleEvent event) {
Vector styles = new Vector();
int token;
StyleRange lastStyle;
// If the line is part of a block comment, create one style for the
// entire line.
if (inBlockComment(event.lineOffset, event.lineOffset
+ event.lineText.length())) {
styles.addElement(new StyleRange(event.lineOffset, event.lineText
.length(), getColor(COMMENT), null));
event.styles = new StyleRange[styles.size()];
styles.copyInto(event.styles);
return;
}
Color defaultFgColor = ((Control) event.widget).getForeground();
scanner.setRange(event.lineText);
token = scanner.nextToken();
while (token != EOF) {
if (token == OTHER) {
// do nothing for non-colored tokens
} else if (token != WHITE) {
Color color = getColor(token);
// Only create a style if the token color is different than the
// widget"s default foreground color and the token"s style is
// not
// bold. Keywords are bolded.
if ((!color.equals(defaultFgColor)) || (token == KEY)) {
StyleRange style = new StyleRange(scanner.getStartOffset()
+ event.lineOffset, scanner.getLength(), color,
null);
if (token == KEY) {
style.fontStyle = SWT.BOLD;
}
if (styles.isEmpty()) {
styles.addElement(style);
} else {
// Merge similar styles. Doing so will improve
// performance.
lastStyle = (StyleRange) styles.lastElement();
if (lastStyle.similarTo(style)
&& (lastStyle.start + lastStyle.length == style.start)) {
lastStyle.length += style.length;
} else {
styles.addElement(style);
}
}
}
} else if ((!styles.isEmpty())
&& ((lastStyle = (StyleRange) styles.lastElement()).fontStyle == SWT.BOLD)) {
int start = scanner.getStartOffset() + event.lineOffset;
lastStyle = (StyleRange) styles.lastElement();
// A font style of SWT.BOLD implies that the last style
// represents a java keyword.
if (lastStyle.start + lastStyle.length == start) {
// Have the white space take on the style before it to
// minimize the number of style ranges created and the
// number of font style changes during rendering.
lastStyle.length += scanner.getLength();
}
}
token = scanner.nextToken();
}
event.styles = new StyleRange[styles.size()];
styles.copyInto(event.styles);
}
public void parseBlockComments(String text) {
blockComments = new Vector();
StringReader buffer = new StringReader(text);
int ch;
boolean blkComment = false;
int cnt = 0;
int[] offsets = new int[2];
boolean done = false;
try {
while (!done) {
switch (ch = buffer.read()) {
case -1: {
if (blkComment) {
offsets[1] = cnt;
blockComments.addElement(offsets);
}
done = true;
break;
}
case "/": {
ch = buffer.read();
if ((ch == "*") && (!blkComment)) {
offsets = new int[2];
offsets[0] = cnt;
blkComment = true;
cnt++;
} else {
cnt++;
}
cnt++;
break;
}
case "*": {
if (blkComment) {
ch = buffer.read();
cnt++;
if (ch == "/") {
blkComment = false;
offsets[1] = cnt;
blockComments.addElement(offsets);
}
}
cnt++;
break;
}
default: {
cnt++;
break;
}
}
}
} catch (IOException e) {
// ignore errors
}
}
/**
* A simple fuzzy scanner for Java
*/
public class JavaScanner {
protected Hashtable fgKeys = null;
protected StringBuffer fBuffer = new StringBuffer();
protected String fDoc;
protected int fPos;
protected int fEnd;
protected int fStartToken;
protected boolean fEofSeen = false;
private String[] fgKeywords = { "abstract", "boolean", "break", "byte",
"case", "catch", "char", "class", "continue", "default", "do",
"double", "else", "extends", "false", "final", "finally",
"float", "for", "if", "implements", "import", "instanceof",
"int", "interface", "long", "native", "new", "null", "package",
"private", "protected", "public", "return", "short", "static",
"super", "switch", "synchronized", "this", "throw", "throws",
"transient", "true", "try", "void", "volatile", "while" };
public JavaScanner() {
initialize();
}
/**
* Returns the ending location of the current token in the document.
*/
public final int getLength() {
return fPos - fStartToken;
}
/**
* Initialize the lookup table.
*/
void initialize() {
fgKeys = new Hashtable();
Integer k = new Integer(KEY);
for (int i = 0; i < fgKeywords.length; i++)
fgKeys.put(fgKeywords[i], k);
}
/**
* Returns the starting location of the current token in the document.
*/
public final int getStartOffset() {
return fStartToken;
}
/**
* Returns the next lexical token in the document.
*/
public int nextToken() {
int c;
fStartToken = fPos;
while (true) {
switch (c = read()) {
case EOF:
return EOF;
case "/": // comment
c = read();
if (c == "/") {
while (true) {
c = read();
if ((c == EOF) || (c == EOL)) {
unread(c);
return COMMENT;
}
}
} else {
unread(c);
}
return OTHER;
case "\"": // char const
character: for (;;) {
c = read();
switch (c) {
case "\"":
return STRING;
case EOF:
unread(c);
return STRING;
case "\\":
c = read();
break;
}
}
case """: // string
string: for (;;) {
c = read();
switch (c) {
case """:
return STRING;
case EOF:
unread(c);
return STRING;
case "\\":
c = read();
break;
}
}
case "0":
case "1":
case "2":
case "3":
case "4":
case "5":
case "6":
case "7":
case "8":
case "9":
do {
c = read();
} while (Character.isDigit((char) c));
unread(c);
return NUMBER;
default:
if (Character.isWhitespace((char) c)) {
do {
c = read();
} while (Character.isWhitespace((char) c));
unread(c);
return WHITE;
}
if (Character.isJavaIdentifierStart((char) c)) {
fBuffer.setLength(0);
do {
fBuffer.append((char) c);
c = read();
} while (Character.isJavaIdentifierPart((char) c));
unread(c);
Integer i = (Integer) fgKeys.get(fBuffer.toString());
if (i != null)
return i.intValue();
return WORD;
}
return OTHER;
}
}
}
/**
* Returns next character.
*/
protected int read() {
if (fPos <= fEnd) {
return fDoc.charAt(fPos++);
}
return EOF;
}
public void setRange(String text) {
fDoc = text;
fPos = 0;
fEnd = fDoc.length() - 1;
}
protected void unread(int c) {
if (c != EOF)
fPos--;
}
}
}
Script MultiTextEdit
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.UndoEdit;
public class Script {
public static void main(String[] args) throws MalformedTreeException,
BadLocationException {
IDocument document = new Document("Eclipse 3");
System.out.println(document.get());
MultiTextEdit edit = new MultiTextEdit();
edit.addChild(new InsertEdit(0, "Java Entwicklung"));
edit.addChild(new InsertEdit(0, " mit "));
UndoEdit undo = edit.apply(document);
System.out.println(document.get());
undo.apply(document);
System.out.println(document.get());
}
}
SWT Completion Editor
/*
SWT/JFace in Action
GUI Design with Eclipse 3.0
Matthew Scarpino, Stephen Holder, Stanford Ng, and Laurent Mihalkovic
ISBN: 1932394273
Publisher: Manning
*/
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.TextEvent;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.contentassist.rupletionProposal;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.ContextInformationValidator;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.ruposite;
public class Ch5CompletionEditor extends Composite {
private TextViewer textViewer;
private WordTracker wordTracker;
private static final int MAX_QUEUE_SIZE = 200;
public Ch5CompletionEditor(Composite parent) {
super(parent, SWT.NULL);
wordTracker = new WordTracker(MAX_QUEUE_SIZE);
buildControls();
}
private void buildControls() {
setLayout(new FillLayout());
textViewer = new TextViewer(this, SWT.MULTI | SWT.V_SCROLL);
textViewer.setDocument(new Document());
final ContentAssistant assistant = new ContentAssistant();
assistant.setContentAssistProcessor(
new RecentWordContentAssistProcessor(wordTracker),
IDocument.DEFAULT_CONTENT_TYPE);
assistant.install(textViewer);
textViewer.getControl().addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
switch (e.keyCode) {
case SWT.F1:
assistant.showPossibleCompletions();
break;
default:
//ignore everything else
}
}
});
textViewer.addTextListener(new ITextListener() {
public void textChanged(TextEvent e) {
if (isWhitespaceString(e.getText())) {
wordTracker.add(findMostRecentWord(e.getOffset() - 1));
}
}
});
}
protected String findMostRecentWord(int startSearchOffset) {
int currOffset = startSearchOffset;
char currChar;
String word = "";
try {
while (currOffset > 0
&& !Character.isWhitespace(currChar = textViewer
.getDocument().getChar(currOffset))) {
word = currChar + word;
currOffset--;
}
return word;
} catch (BadLocationException e) {
e.printStackTrace();
return null;
}
}
protected boolean isWhitespaceString(String string) {
StringTokenizer tokenizer = new StringTokenizer(string);
//if there is at least 1 token, this string is not whitespace
return !tokenizer.hasMoreTokens();
}
}
class WordTracker {
private int maxQueueSize;
private List wordBuffer;
private Map knownWords = new HashMap();
public WordTracker(int queueSize) {
maxQueueSize = queueSize;
wordBuffer = new LinkedList();
}
public int getWordCount() {
return wordBuffer.size();
}
public void add(String word) {
if (wordIsNotKnown(word)) {
flushOldestWord();
insertNewWord(word);
}
}
private void insertNewWord(String word) {
wordBuffer.add(0, word);
knownWords.put(word, word);
}
private void flushOldestWord() {
if (wordBuffer.size() == maxQueueSize) {
String removedWord = (String) wordBuffer.remove(maxQueueSize - 1);
knownWords.remove(removedWord);
}
}
private boolean wordIsNotKnown(String word) {
return knownWords.get(word) == null;
}
public List suggest(String word) {
List suggestions = new LinkedList();
for (Iterator i = wordBuffer.iterator(); i.hasNext();) {
String currWord = (String) i.next();
if (currWord.startsWith(word)) {
suggestions.add(currWord);
}
}
return suggestions;
}
}
class RecentWordContentAssistProcessor implements IContentAssistProcessor {
private String lastError = null;
private IContextInformationValidator contextInfoValidator;
private WordTracker wordTracker;
public RecentWordContentAssistProcessor(WordTracker tracker) {
super();
contextInfoValidator = new ContextInformationValidator(this);
wordTracker = tracker;
}
public ICompletionProposal[] computeCompletionProposals(
ITextViewer textViewer, int documentOffset) {
IDocument document = textViewer.getDocument();
int currOffset = documentOffset - 1;
try {
String currWord = "";
char currChar;
while (currOffset > 0
&& !Character.isWhitespace(currChar = document
.getChar(currOffset))) {
currWord = currChar + currWord;
currOffset--;
}
List suggestions = wordTracker.suggest(currWord);
ICompletionProposal[] proposals = null;
if (suggestions.size() > 0) {
proposals = buildProposals(suggestions, currWord,
documentOffset - currWord.length());
lastError = null;
}
return proposals;
} catch (BadLocationException e) {
e.printStackTrace();
lastError = e.getMessage();
return null;
}
}
private ICompletionProposal[] buildProposals(List suggestions,
String replacedWord, int offset) {
ICompletionProposal[] proposals = new ICompletionProposal[suggestions
.size()];
int index = 0;
for (Iterator i = suggestions.iterator(); i.hasNext();) {
String currSuggestion = (String) i.next();
proposals[index] = new CompletionProposal(currSuggestion, offset,
replacedWord.length(), currSuggestion.length());
index++;
}
return proposals;
}
public IContextInformation[] computeContextInformation(
ITextViewer textViewer, int documentOffset) {
lastError = "No Context Information available";
return null;
}
public char[] getCompletionProposalAutoActivationCharacters() {
//we always wait for the user to explicitly trigger completion
return null;
}
public char[] getContextInformationAutoActivationCharacters() {
//we have no context information
return null;
}
public String getErrorMessage() {
return lastError;
}
public IContextInformationValidator getContextInformationValidator() {
return contextInfoValidator;
}
}
SWT Editor
SWT Text Editor Demo
import java.io.IOException;
import java.io.InputStream;
import java.util.ResourceBundle;
import java.util.Vector;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ExtendedModifyEvent;
import org.eclipse.swt.custom.ExtendedModifyListener;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.FontDialog;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;
/**
*/
public class TextEditor {
Shell shell;
ToolBar toolBar;
StyledText text;
Images images = new Images();
Vector cachedStyles = new Vector();
Color RED = null;
Color BLUE = null;
Color GREEN = null;
Font font = null;
ToolItem boldButton, italicButton, underlineButton, strikeoutButton;
Menu createEditMenu() {
Menu bar = shell.getMenuBar();
Menu menu = new Menu(bar);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Cut_menuitem");
item.setAccelerator(SWT.MOD1 + "X");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
handleCutCopy();
text.cut();
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Copy_menuitem");
item.setAccelerator(SWT.MOD1 + "C");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
handleCutCopy();
text.copy();
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Paste_menuitem");
item.setAccelerator(SWT.MOD1 + "V");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
text.paste();
}
});
new MenuItem(menu, SWT.SEPARATOR);
item = new MenuItem(menu, SWT.PUSH);
item.setText("Font_menuitem");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setFont();
}
});
return menu;
}
Menu createFileMenu() {
Menu bar = shell.getMenuBar();
Menu menu = new Menu(bar);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Exit_menuitem");
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
shell.close();
}
});
return menu;
}
/*
* Set a style
*/
void setStyle(Widget widget) {
Point sel = text.getSelectionRange();
if ((sel == null) || (sel.y == 0))
return;
StyleRange style;
for (int i = sel.x; i < sel.x + sel.y; i++) {
StyleRange range = text.getStyleRangeAtOffset(i);
if (range != null) {
style = (StyleRange) range.clone();
style.start = i;
style.length = 1;
} else {
style = new StyleRange(i, 1, null, null, SWT.NORMAL);
}
if (widget == boldButton) {
style.fontStyle ^= SWT.BOLD;
} else if (widget == italicButton) {
style.fontStyle ^= SWT.ITALIC;
} else if (widget == underlineButton) {
style.underline = !style.underline;
} else if (widget == strikeoutButton) {
style.strikeout = !style.strikeout;
}
text.setStyleRange(style);
}
text.setSelectionRange(sel.x + sel.y, 0);
}
/*
* Clear all style data for the selected text.
*/
void clear() {
Point sel = text.getSelectionRange();
if ((sel != null) && (sel.y != 0)) {
StyleRange style;
style = new StyleRange(sel.x, sel.y, null, null, SWT.NORMAL);
text.setStyleRange(style);
}
text.setSelectionRange(sel.x + sel.y, 0);
}
/*
* Set the foreground color for the selected text.
*/
void fgColor(Color fg) {
Point sel = text.getSelectionRange();
if ((sel == null) || (sel.y == 0))
return;
StyleRange style, range;
for (int i = sel.x; i < sel.x + sel.y; i++) {
range = text.getStyleRangeAtOffset(i);
if (range != null) {
style = (StyleRange) range.clone();
style.start = i;
style.length = 1;
style.foreground = fg;
} else {
style = new StyleRange(i, 1, fg, null, SWT.NORMAL);
}
text.setStyleRange(style);
}
text.setSelectionRange(sel.x + sel.y, 0);
}
void createMenuBar() {
Menu bar = new Menu(shell, SWT.BAR);
shell.setMenuBar(bar);
MenuItem fileItem = new MenuItem(bar, SWT.CASCADE);
fileItem.setText("File_menuitem");
fileItem.setMenu(createFileMenu());
MenuItem editItem = new MenuItem(bar, SWT.CASCADE);
editItem.setText("edit");
editItem.setMenu(createEditMenu());
}
void createShell(Display display) {
shell = new Shell(display);
shell.setText("Window");
images.loadAll(display);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
shell.setLayout(layout);
shell.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (font != null)
font.dispose();
images.freeAll();
RED.dispose();
GREEN.dispose();
BLUE.dispose();
}
});
}
void createStyledText() {
initializeColors();
text = new StyledText(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL
| SWT.H_SCROLL);
GridData spec = new GridData();
spec.horizontalAlignment = GridData.FILL;
spec.grabExcessHorizontalSpace = true;
spec.verticalAlignment = GridData.FILL;
spec.grabExcessVerticalSpace = true;
text.setLayoutData(spec);
text.addExtendedModifyListener(new ExtendedModifyListener() {
public void modifyText(ExtendedModifyEvent e) {
handleExtendedModify(e);
}
});
}
void createToolBar() {
toolBar = new ToolBar(shell, SWT.NULL);
SelectionAdapter listener = new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
setStyle(event.widget);
}
};
boldButton = new ToolItem(toolBar, SWT.CHECK);
boldButton.setImage(images.Bold);
boldButton.setToolTipText("Bold");
boldButton.addSelectionListener(listener);
italicButton = new ToolItem(toolBar, SWT.CHECK);
italicButton.setImage(images.Italic);
italicButton.setToolTipText("Italic");
italicButton.addSelectionListener(listener);
underlineButton = new ToolItem(toolBar, SWT.CHECK);
underlineButton.setImage(images.Underline);
underlineButton.setToolTipText("Underline");
underlineButton.addSelectionListener(listener);
strikeoutButton = new ToolItem(toolBar, SWT.CHECK);
strikeoutButton.setImage(images.Strikeout);
strikeoutButton.setToolTipText("Strikeout");
strikeoutButton.addSelectionListener(listener);
ToolItem item = new ToolItem(toolBar, SWT.SEPARATOR);
item = new ToolItem(toolBar, SWT.PUSH);
item.setImage(images.Red);
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
fgColor(RED);
}
});
item = new ToolItem(toolBar, SWT.PUSH);
item.setImage(images.Green);
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
fgColor(GREEN);
}
});
item = new ToolItem(toolBar, SWT.PUSH);
item.setImage(images.Blue);
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
fgColor(BLUE);
}
});
item = new ToolItem(toolBar, SWT.SEPARATOR);
item = new ToolItem(toolBar, SWT.PUSH);
item.setImage(images.Erase);
item.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
clear();
}
});
}
/*
* Cache the style information for text that has been cut or copied.
*/
void handleCutCopy() {
// Save the cut/copied style info so that during paste we will maintain
// the style information. Cut/copied text is put in the clipboard in
// RTF format, but is not pasted in RTF format. The other way to
// handle the pasting of styles would be to access the Clipboard
// directly and
// parse the RTF text.
cachedStyles = new Vector();
Point sel = text.getSelectionRange();
int startX = sel.x;
for (int i = sel.x; i <= sel.x + sel.y - 1; i++) {
StyleRange style = text.getStyleRangeAtOffset(i);
if (style != null) {
style.start = style.start - startX;
if (!cachedStyles.isEmpty()) {
StyleRange lastStyle = (StyleRange) cachedStyles
.lastElement();
if (lastStyle.similarTo(style)
&& lastStyle.start + lastStyle.length == style.start) {
lastStyle.length++;
} else {
cachedStyles.addElement(style);
}
} else {
cachedStyles.addElement(style);
}
}
}
}
void handleExtendedModify(ExtendedModifyEvent event) {
if (event.length == 0)
return;
StyleRange style;
if (event.length == 1
|| text.getTextRange(event.start, event.length).equals(
text.getLineDelimiter())) {
// Have the new text take on the style of the text to its right
// (during
// typing) if no style information is active.
int caretOffset = text.getCaretOffset();
style = null;
if (caretOffset < text.getCharCount())
style = text.getStyleRangeAtOffset(caretOffset);
if (style != null) {
style = (StyleRange) style.clone();
style.start = event.start;
style.length = event.length;
} else {
style = new StyleRange(event.start, event.length, null, null,
SWT.NORMAL);
}
if (boldButton.getSelection())
style.fontStyle |= SWT.BOLD;
if (italicButton.getSelection())
style.fontStyle |= SWT.ITALIC;
style.underline = underlineButton.getSelection();
style.strikeout = strikeoutButton.getSelection();
if (!style.isUnstyled())
text.setStyleRange(style);
} else {
// paste occurring, have text take on the styles it had when it was
// cut/copied
for (int i = 0; i < cachedStyles.size(); i++) {
style = (StyleRange) cachedStyles.elementAt(i);
StyleRange newStyle = (StyleRange) style.clone();
newStyle.start = style.start + event.start;
text.setStyleRange(newStyle);
}
}
}
public static void main(String[] args) {
Display display = new Display();
TextEditor example = new TextEditor();
Shell shell = example.open(display);
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
public Shell open(Display display) {
createShell(display);
createMenuBar();
createToolBar();
createStyledText();
shell.setSize(500, 300);
shell.open();
return shell;
}
void setFont() {
FontDialog fontDialog = new FontDialog(shell);
fontDialog.setFontList((text.getFont()).getFontData());
FontData fontData = fontDialog.open();
if (fontData != null) {
if (font != null) {
font.dispose();
}
font = new Font(shell.getDisplay(), fontData);
text.setFont(font);
}
}
void initializeColors() {
Display display = Display.getDefault();
RED = new Color(display, new RGB(255, 0, 0));
BLUE = new Color(display, new RGB(0, 0, 255));
GREEN = new Color(display, new RGB(0, 255, 0));
}
}
/*******************************************************************************
* Copyright (c) 2000, 2004 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
******************************************************************************/
class Images {
// Bitmap Images
public Image Bold;
public Image Italic;
public Image Underline;
public Image Strikeout;
public Image Red;
public Image Green;
public Image Blue;
public Image Erase;
Image[] AllBitmaps;
Images() {
}
public void freeAll() {
for (int i = 0; i < AllBitmaps.length; i++)
AllBitmaps[i].dispose();
AllBitmaps = null;
}
Image createBitmapImage(Display display, String fileName) {
InputStream sourceStream = Images.class.getResourceAsStream(fileName
+ ".bmp");
InputStream maskStream = Images.class.getResourceAsStream(fileName
+ "_mask.bmp");
ImageData source = new ImageData(sourceStream);
ImageData mask = new ImageData(maskStream);
Image result = new Image(display, source, mask);
try {
sourceStream.close();
maskStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
public void loadAll(Display display) {
// Bitmap Images
Bold = createBitmapImage(display, "bold");
Italic = createBitmapImage(display, "italic");
Underline = createBitmapImage(display, "underline");
Strikeout = createBitmapImage(display, "strikeout");
Red = createBitmapImage(display, "red");
Green = createBitmapImage(display, "green");
Blue = createBitmapImage(display, "blue");
Erase = createBitmapImage(display, "erase");
AllBitmaps = new Image[] { Bold, Italic, Underline, Strikeout, Red,
Green, Blue, Erase, };
}
}