T.M. SoftStudio

feci quod potui, faciant meliora potentes

Купить полную версию книги "Среда разработки Eclipse 4: Руководство разработчика"

Разработка Eclipse-плагинов

Пример. Создание Eclipse-плагина Rich Text Editor. Совместное использование SWT и JavaFX

В качестве примера рассмотрим разработку Eclipse-плагина на основе библиотек SWT и JavaFX, добавляющего Eclipse-представление с редактором создания HTML-контента.

Для поддержки технологии JavaFX средой Eclipse установим набор инструментов e(fx)clipse (http://www.eclipse.org/efxclipse/index.html).

Для установки набора инструментов e(fx)clipse в поле Work with: команды Install New Software меню Help среды Eclipse кнопкой Add добавим адрес http://download.eclipse.org/efxclipse/updates-nightly/site, отметим флажок e(fx)clipse – install | e(fx)clipse – IDEKepler и нажмем кнопку Next.

После установки инструментов e(fx)clipse и перезапуска среды Eclipse в меню File выберем команду New | Other | Plug-in Development | Plug-in Project и нажмем кнопку Next.

Введем имя проекта, отметим флажок Eclipse version: и нажмем кнопку Next.

Отметим флажок This plug-in will make contributions to the UI, выберем переключатель Rich Client Application No и нажмем кнопку Next.

Выберем шаблон Plug-in with a view и нажмем кнопку Next.

В поле View Name введем заголовок представления, в поле View Category Name введем имя раздела представления команды Show View | Other меню Window и нажмем кнопку Finish.

Для совместного использования SWT и JavaFX:

  • Во вкладке Dependencies редактора Plug-in Manifest Editor файла plugin.xml проекта в разделе Required Plug-ins кнопкой Add добавим зависимость от плагина org.eclipse.fx.javafx.

  • Скопируем библиотеку jfxrt.jar в папку C:\Program Files\Java\jdk\jre\lib\ext

Переименуем и изменим код класса SampleView проекта:

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.InputStreamReader;

import java.nio.ByteBuffer;

import java.nio.channels.FileChannel;

import javafx.embed.swt.FXCanvas;

import javafx.event.ActionEvent;

import javafx.event.EventHandler;

import javafx.scene.Cursor;

import javafx.scene.Group;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.control.ScrollPane;

import javafx.scene.control.TextArea;

import javafx.scene.layout.HBox;

import javafx.scene.layout.VBox;

import javafx.scene.paint.Color;

import javafx.scene.web.HTMLEditor;

import org.eclipse.core.runtime.FileLocator;

import org.eclipse.core.runtime.Path;

import org.eclipse.core.runtime.Platform;

import org.eclipse.jface.action.Action;

import org.eclipse.jface.action.IMenuManager;

import org.eclipse.jface.action.IToolBarManager;

import org.eclipse.jface.action.Separator;

import org.eclipse.jface.resource.ImageDescriptor;

import org.eclipse.swt.SWT;

import org.eclipse.swt.layout.GridLayout;

import org.eclipse.swt.widgets.Composite;

import org.eclipse.swt.widgets.FileDialog;

import org.eclipse.ui.IActionBars;

import org.eclipse.ui.ISharedImages;

import org.eclipse.ui.PlatformUI;

import org.eclipse.ui.part.ViewPart;

public class RichTextEditorView extends ViewPart {

public static final String ID = "tm_softstudio_rich_text_editor_plugin.views.RichTextEditorView";

private Action actionOpen;

private Action actionSave;

private HTMLEditor editor;

private Composite c;

/**

* The constructor.

*/

public RichTextEditorView() {

}

/**

* This is a callback that will allow us

* to create the viewer and initialize it.

*/

public void createPartControl(Composite parent) {

c = new Composite(parent, SWT.NONE);

c.setLayout(new GridLayout());

FXCanvas fxCanvas = new FXCanvas(c, SWT.NONE);

Group group = new Group();

ScrollPane sp = new ScrollPane();

sp.setLayoutX(10);

sp.setLayoutY(10);

sp.setPrefSize(900, 400);

sp.setContent(group);

sp.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);

sp.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);

sp.setPannable(true);

VBox vbox=new VBox();

vbox.setLayoutX(20);

vbox.setLayoutY(10);

vbox.setSpacing(20);

final TextArea textArea = new TextArea();

textArea.setLayoutX(10);

textArea.setLayoutY(10);

textArea.setCursor(Cursor.TEXT);

textArea.setStyle("-fx-background-radius:20;-fx-border-radius:20;-fx-background-color:#ffefd5;-fx-border-width:3pt;-fx-border-color:#cd853f;-fx-font-weight:normal;-fx-font-size:14pt; -fx-font-family:Georgia; -fx-font-style:normal");

textArea.setPrefSize(600, 200);

textArea.setEditable(true);

textArea.setWrapText(true);

editor=new HTMLEditor();

editor.setPrefSize(600, 300);

editor.setCursor(Cursor.TEXT);

editor.setHtmlText("<html><body></body></html>");

HBox hbox=new HBox();

hbox.setLayoutX(20);

hbox.setLayoutY(10);

hbox.setSpacing(20);

VBox vboxBtn=new VBox();

vboxBtn.setLayoutX(20);

vboxBtn.setLayoutY(10);

vboxBtn.setSpacing(20);

Button btnShow = new Button();

btnShow.setText("Show HTML");

btnShow.setCursor(Cursor.CLOSED_HAND);

btnShow.setStyle("-fx-font: bold 16pt Georgia;-fx-text-fill: white;-fx-background-color: #a0522d;-fx-border-width: 3px; -fx-border-color:#f4a460 #800000 #800000 #f4a460;" );

btnShow.setOnAction(new EventHandler<ActionEvent>() {

@Override public void handle(ActionEvent e) {

textArea.setText(editor.getHtmlText());

}});

Button btnClear = new Button();

btnClear.setText("Clear");

btnClear.setCursor(Cursor.CLOSED_HAND);

btnClear.setStyle("-fx-font: bold 16pt Georgia;-fx-text-fill: white;-fx-background-color: #a0522d;-fx-border-width: 3px; -fx-border-color:#f4a460 #800000 #800000 #f4a460;" );

btnClear.setOnAction(new EventHandler<ActionEvent>() {

@Override public void handle(ActionEvent e) {

editor.setHtmlText("<html><body></body></html>");

}});

vboxBtn.getChildren().addAll(btnClear, btnShow);

hbox.getChildren().addAll(textArea, vboxBtn);

vbox.getChildren().addAll(hbox, editor);

group.getChildren().addAll(vbox);

/* Create the Scene instance and set the group node as root */

Group root = new Group();

root.getChildren().addAll(sp);

Scene scene = new Scene(root, 1100,700, Color.BEIGE);

fxCanvas.setScene(scene);

makeActions();

contributeToActionBars();

}

private void contributeToActionBars() {

IActionBars bars = getViewSite().getActionBars();

fillLocalPullDown(bars.getMenuManager());

fillLocalToolBar(bars.getToolBarManager());

}

private void fillLocalPullDown(IMenuManager manager) {

manager.add(actionOpen);

manager.add(new Separator());

manager.add(actionSave);

}

private void fillLocalToolBar(IToolBarManager manager) {

manager.add(actionOpen);

manager.add(actionSave);

}

private void makeActions() {

actionOpen = new Action() {

public void run() {

FileDialog dialog = new FileDialog(c.getShell(), SWT.OPEN);

dialog.setFilterExtensions(new String[]{"*.html","*.htm"});

dialog.setFilterPath("C:/");

String fileName = dialog.open();

if (fileName != null) {

try {

File fileDir = new File(fileName);

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(

new FileInputStream(fileDir), "UTF8"));

StringBuffer stringBuffer = new StringBuffer();

while (bufferedReader.ready()) {

stringBuffer.append(bufferedReader.readLine() + "\n");

}

editor.setHtmlText(stringBuffer.toString());

bufferedReader.close();

} catch (Exception e) {

e.printStackTrace();

}}};

actionOpen.setText("Open");

actionOpen.setToolTipText("Open HTML File");

actionOpen.setImageDescriptor(ImageDescriptor.createFromURL(FileLocator.find(Platform.getBundle("TM_SoftStudio_Rich_Text_Editor_Plug-in"), new Path("icons/open_file-icon.gif"), null)));

actionSave = new Action() {

public void run() {

FileDialog dialog = new FileDialog(c.getShell(), SWT.SAVE);

dialog.setFilterPath("C:/");

dialog.setFilterExtensions(new String[]{".html"});

dialog.setOverwrite(true);

String location=dialog.open();

if (location != null) {

File exportFile=new File(location);

String outputString=editor.getHtmlText();

exportFile.delete();

FileOutputStream fileOutputStream=null;

try {

fileOutputStream=new FileOutputStream(exportFile,true);

FileChannel outChannel=fileOutputStream.getChannel();

ByteBuffer buffer=ByteBuffer.allocate(outputString.length());

byte[] bytes=outputString.getBytes();

buffer.put(bytes);

buffer.flip();

outChannel.write(buffer);

fileOutputStream.close();

} catch (Exception e) {

e.printStackTrace();

}}}};

actionSave.setText("Save");

actionSave.setToolTipText("Save HTML File");

actionSave.setImageDescriptor( PlatformUI.getWorkbench().getSharedImages().

getImageDescriptor(ISharedImages.IMG_ETOOL_SAVE_EDIT));

}

/**

* Passing the focus request to the viewer's control.

*/

public void setFocus() {

c.setFocus();

}}

В коде класса RichTextEditorView в методе createPartControl в Eclipse-представление добавляется контейнер Composite, содержащий компонент javafx.embed.swt.FXCanvas, служащий мостом между библиотеками SWT и JavaFX.

В компонент FXCanvas добавляется сцена с JavaFX-компонентами:

  • HTMLEditor – редактор, при наборе текста в котором автоматически создается HTML-код.

  • TextArea – отображает HTML-код, созданный компонентом HTMLEditor.

  • Button btnShow – кнопка, при нажатии на которой компонент TextArea отображает HTML-код, созданный компонентом HTMLEditor.

  • Button btnClear – кнопка, при нажатии на которой очищается содержимое компонента HTMLEditor.

Кроме того, в коде класса RichTextEditorView создаются элементы панели инструментов представления, в методах run() которых производится загрузка в редактор HTMLEditor внешнего HTML-файла для просмотра и редактирования и сохранение из редактора HTMLEditor работы в виде HTML-файла каталога компьютера.

Методом setImageDescriptor для элементов панели инструментов представления определяются значки.

Во вкладке Extensions редактора Plug-in Manifest Editor файла plugin.xml проекта в разделе All Extensions откроем узел org.eclipse.ui.views | Rich Text Editor и в поле icon: определим значок представления.

Для запуска плагина во вкладке Overview редактора Plug-in Manifest Editor файла plugin.xml проекта в разделе Testing нажмем на ссылку Launch an Eclipse application.

В результате в команду Show View | Other меню Window будет добавлен раздел Rich Text Editor с представлением Rich Text Editor (рис. 6.1 и рис. 6.2).

Рис. 6.1. Раздел Rich Text Editor с представлением Rich Text Editor команды Show View | Other меню Window

Рис. 6.2. Представление Rich Text Editor с редактором HTML-кода

Для экспорта в готовый для развертывания плагин в окне Package Explorer нажмем правой кнопкой мышки на узле проекта и в контекстном меню выберем команду Export | Plug-in Development | Deployable plug-ins and fragments и нажмем кнопку Next.

В переключателе Directory кнопкой Browse выберем каталог плагина и нажмем кнопку Finish.

После размещения созданного плагина в каталоге \eclipse\plugins и запуске среды Eclipse, представление Rich Text Editor автоматически добавится в команду Show View | Other меню Window.



Размещение плагина в Eclipse Marketplace

Т. Машнин