Программирование приложения Java Desktop с использованием SWT
1. Введение
Статья основана на:
Eclipse 4.6, 47 (NEON, OXYGEN)
В данной статье я ознакомлю вас с программированием приложения Desktop с SWT.
Вопросом является, есть ли в Java способ выбора технологии для программирования приложения Desktop, или какая технология помогает программировать веб приложение с интерфейсом похожим на приложение Desktop.
Смотрите так же:
2. RCP (Rich Client Platform)
RCP (Rich Client Platform) - Это платформа (Platform) разработанная на основе SWT, используется для программирования приложений Desktop и еще дальше он построил для вас платформу, позволяющую вас разрабатывать приложения Desktop вида Workbench, похоже на Eclipse IDE, или программировать Plugin которые могут интегрировать в Eclipse IDE.
Но даже если вы хотите использовать только SWT для программирования не использовать то, что предоставлено RCP-ом вам так же нужно создать приложение RCP.
Но даже если вы хотите использовать только SWT для программирования не использовать то, что предоставлено RCP-ом вам так же нужно создать приложение RCP.
SWT:
Workbench Application:
Чтобы создать приложение Desktop используя SWT. В Eclipse мы создадим RCP Plugin project. У вас есть 2 варианта.
- Использовать только свойства SWT
- Использовать платформу предоставленную RCP для программирования приложения RCP Workbench.
В данной статье я покажу вам как ознакомиться с программированием стандартного SWT, используя WindowBuilder чтобы перетаскивать компоненты в интерфейс.
3. Необходимые настройки для начала
Есть необходимые настройки, которые нужно сделать перед тем, как начать:
Вам нужно иметь Eclipse самой новой версии. Сейчас это Eclipse 4.7 (Код OXYGEN).
Вам нужно иметь Eclipse самой новой версии. Сейчас это Eclipse 4.7 (Код OXYGEN).
По-моему вам нужно скачать пакет: "Eclipse IDE for Java EE Developers". Пакеты отличаются колличеством Plugin, для разных целей программирования. В процессе программирования можно установить дополнительно Plugin для других целей.
Установка Plugin WindowBuilder, это 1 Plugin позволяющий вас сделать интерфейс дизайна приложения SWT с помощью перетаскивания, очень удобно.
Смотрите инструкцию установки по ссылке:
Смотрите инструкцию установки по ссылке:
4. Некоторые понятия о SWT.
Display & Shell
Класс Display и Shell являются ключевыми компонентами приложения SWT.
- org.eclipse.swt.widgets.Shell описывает окно (Window)
- org.eclipse.swt.widgets.Display отвечает за управление цикла события (event loops), шрифт, цвет и контролирует информацию коммуникации между потоками интерфкйса пользователя (UI Thread) и другими потоками (other Thread). Display это основа для всех способностей свойств SWT.
Каждое приложение SWT требует минимум один Display и один или более объектов Shell.
- org.eclipse.swt.widgets.Shell описывает окно (Window)
- org.eclipse.swt.widgets.Display отвечает за управление цикла события (event loops), шрифт, цвет и контролирует информацию коммуникации между потоками интерфкйса пользователя (UI Thread) и другими потоками (other Thread). Display это основа для всех способностей свойств SWT.
Каждое приложение SWT требует минимум один Display и один или более объектов Shell.
Пример:
Display display = new Display();
Shell shell = new Shell(display);
shell.open();
// run the event loop as long as the window is open
while (!shell.isDisposed()) {
// read the next OS event queue and transfer it to a SWT event
if (!display.readAndDispatch())
{
// if there are currently no other OS event to process
// sleep until the next OS event is available
display.sleep();
}
}
// disposes all associated windows and their components
display.dispose();
SWT Widgets
SWT widget установлены в пакетах org.eclipse.swt.widgets и org.eclipse.swt.custom. Этом widget расширен из класса Widget или Control. Некоторые widget иллюстрированы в изображении ниже.
Детали вы можете просмотреть в SWT widget homepage.
5. Создать RCP Plugin Project
В Eclipse выбрать:
- File/New/Other...
- Так как нет надобности создать приложение Workbench поэтому мы не выбираем (1) как в изображении ниже.
- Выбрать Yes в области (2) чтобы Eclipse создал RCP Application (Работающий на Desktop), напротив он создаст RAP Application (Работающий на Web).
Project создан:
Добавить библиотеку swt: org.eclipse.swt
Если вы программируете приложение RAP, соответствующей библиотекой является org.eclipse.rap.rwt
6. Первый пример
Это простой пример, не используя инструмент перетаскивания WindowBuilder.
HelloSWT.java
package org.o7planning.tutorial.swt.helloswt;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class HelloSWT {
public static void main(String[] args) {
// Create Display
Display display = new Display();
// Create Shell (Window) from diplay
Shell shell = new Shell(display);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
Нажмите на правую кнопку мыши на HelloSWT.java и выберите Run As/Java Application.
Результаты запуска примера:
7. Использование WindowBuilder
Далее, мы создадим пример с перетаскиванием на WindowBuilder.
- File/New/Other ..
Это окно дизайна в WindowBuilder. Оно позволяет вам легко перетаскивать Widget.
You can watch the video below:
8. SWT Widget
Обзор
Это иерарзия Widget в SWT.
Вы можете посмотреть демо (demo) про Control по ссылке ниже, это RWT Control, но на самом деле они похожи на SWT control.
Demo:
Widget могут содержать другие Widget (Container)
Control
9. SWT Layout
Что такое Layout?
Проще говоря, Layout это способ распорядка компонентов на интерфейсе.
Стандартные Layout в SWT это:
- FillLayout – Выравнивает размер Widget в строке или столбце
- RowLayout – Связывает Widget в строке или заполненной строке (Fill), обернутой (Wrap), и с вариантами пробела (space).
- GridLayout – Связывает Widget в сети
Онлайн пример
Это пример онлайн, позволяющий вам увидеть действия Layout.
- TODO Link?
FillLayout
FillLayout это простой класс layout. н расставляет виджет (Widget) в одной строке или столбце, заставляя их иметь один размер. Сначала Widget иметь высоту как самый высокий Widget, и широту как самый широкий widget. FillLayout не wrap (обертывает) Widget, и вы не можете определить грань (margin) или расстояние (space).
FillLayout fillLayout = new FillLayout();
fillLayout.type = SWT.VERTICAL;
shell.setLayout(fillLayout);
Сначала | После изменения размера | |
fillLayout.type = SWT.HORIZONTAL (Mặc định) | ||
fillLayout.type = SWT.VERTICAL |
Video:
FillLayoutExample.java
package org.o7planning.tutorial.swt.layout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class FillLayoutExample {
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
//
Composite parent = new Composite(shell, SWT.NONE);
FillLayout fillLayout= new FillLayout();
fillLayout.type= SWT.VERTICAL;
parent.setLayout(fillLayout);
Button b1 = new Button(parent, SWT.NONE);
b1.setText("B1");
Button b2 = new Button(parent, SWT.NONE);
b2.setText("B2");
Button button3 = new Button(parent, SWT.NONE);
button3.setText("Button 3");
// Windows back to natural size.
shell.pack();
//
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
// tear down the SWT window
display.dispose();
}
}
Результаты запуска примера:
RowLayout
RowLayout используются больше чем FillLayout так как он имеет способность wrap (обертывать), и потому что он поддерживает margin и spacing. RowLayout имеет некоторые поля (field) конфигурации. Помимо этого, высота и ширина каждого widget в каждом RowLayout может быть определен созданием объекта RowData для widget используя setLayoutData
The field configuration:
Wrap, Pack, Justify:
Сначала | После изменения размера | |
wrap = true pack = true justify = false (По умолчанию) | ||
wrap = false (Немного отрезан если не хватает пространства) | ||
pack = false (Все Widget имеют одинаковый размер) | ||
justify = true (Widget будут распространены на готовом пространстве и поровну) |
MarginLeft, MarginTop, MarginRight, MarginBottom, Spacing:
Поля (field) контролирующие пиксели (Pixel) между widget (space - расстояние) и количество пикселей между widget и стороной родительского Composite (margin - грань). По умолчанию, RowLayout использует 3 Pixel для выравнивания (margin) и интервалом (space). Смотрите детали в следующем изображении.
Video:
GridLayout
GridLayout это самый полезный и сильный в стандартных Layout, но так же являеся самым сложным. С GridLayout, дочерний Widget одного Composite будет расставлен в сетке. GridLayout имеет некоторые конфигурационные поля, и так же как RowLayout, Widget расположенные в GridLayout могут иметь связанный объект данных Layout, так же называется GridData. Сила GridLayout находится в способности конфигурации GridData для каждого widget управляемый с помощью GridLayout.
Конфигурации GridLayout:
- NumColumns
- MakeColumnsEqualWidth
Video GridLayout:
StackLayout
StackLayout расставляет все Widget в стопку, они будут иметь одинаковый размер и местоположение. Поле topControl определяет какой Widget находится в самом верху и видно. Пользователь должен настроить значение topControl и потом вызвать метод layout() родительского Composite.
Video StackLayout:
Комбинирование Layout
Выше мы ознакомились со стандартными Layout, и сочетаниями разных Layout, и разными контейнерами (Container) (Composite, TabFolder, SashForm,.. ) которые создают желаемый интерфейс.
- TODO
10. Написать расширенные классы из widget в SWT
Иногда вам нжуно написать расширенный класс из класса widget готовый в SWT. Это совершенно нормально, но есть маленькое примечание, вам нужно переопределить метод checkSubclass() ничего не делая в том методе.
MyButton.java
package org.o7planning.tutorial.swt.swtsubclass;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
public class MyButton extends Button {
public MyButton(Composite parent, int style) {
super(parent, style);
}
// You have to override this method.
@Override
protected void checkSubclass() {
// No need to do anything.
}
}
11. Module становится компонентом интерфейса
В случае, когда вам нужно сделать дизайн сложного интерфейса. Разделение дизайна это необходимо и потом соединить их снова, с дизайном на WindowBuilder это становится легче.
Посмотрим следующий интерфейс, мы попытаемся разделить его.
Посмотрим следующий интерфейс, мы попытаемся разделить его.
Предположим, вы хотите сделать дизайн похожим на изображение ниже. (Он сложный и нужно разделить дизайн, но это иллюстрация примера разделения дизайна интерфейса)
Мы можем сделать дизайн 2-х отдельных Composite и соединить их на MainComposite.
TopComposite
- File/New/Other...
Дизайн интерфейса для TopComposite.
TopComposite.java
package org.o7planning.tutorial.swt.module;
import org.eclipse.swt.widgets.Composite;
public class TopComposite extends Composite {
private Text text;
/**
* Create the composite.
* @param parent
* @param style
*/
public TopComposite(Composite parent, int style) {
super(parent, style);
setLayout(new FillLayout(SWT.HORIZONTAL));
Composite composite = new Composite(this, SWT.NONE);
composite.setLayout(new GridLayout(1, false));
Button btnPreferredSite = new Button(composite, SWT.CHECK);
btnPreferredSite.setText("Preferred Site");
Label lblColumnWidth = new Label(composite, SWT.NONE);
lblColumnWidth.setText("Column width");
text = new Text(composite, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
}
@Override
protected void checkSubclass() {
}
}
BottomComposite
Индентично создайте класс BottomComposite:
Дизайн интерфейса для BottomComposite:
BottomComposite.java
package org.o7planning.tutorial.swt.module;
import org.eclipse.swt.SWT;
public class BottomComposite extends Composite {
private Text text;
/**
* Create the composite.
* @param parent
* @param style
*/
public BottomComposite(Composite parent, int style) {
super(parent, style);
setLayout(new FillLayout(SWT.HORIZONTAL));
Composite composite = new Composite(this, SWT.NONE);
composite.setLayout(new GridLayout(1, false));
Composite composite_1 = new Composite(composite, SWT.NONE);
GridLayout gl_composite_1 = new GridLayout(3, false);
gl_composite_1.marginHeight = 0;
gl_composite_1.marginWidth = 0;
composite_1.setLayout(gl_composite_1);
composite_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Button btnNewButton = new Button(composite_1, SWT.NONE);
btnNewButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
btnNewButton.setText("Add");
Button btnNewButton_1 = new Button(composite_1, SWT.NONE);
btnNewButton_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
btnNewButton_1.setText("Delete");
Button btnNewButton_2 = new Button(composite_1, SWT.NONE);
btnNewButton_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
btnNewButton_2.setText("Clear");
text = new Text(composite, SWT.BORDER | SWT.MULTI);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
}
@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}
MainComposite
Индентично создайте класс MainComposite:
Регистрация TopComposite & BottomComposite на Palette
Нажмите на правую кнопку мыши на Palette и выберите Add category...
Назовите Pallete Category:
- My Composite
Нажмите на правую кнопку мыши на "My Composite" чтобы добавить TopComposite & BottomComposite.
Индентично добавьте BottomComposite в каталог My Composite.
Теперь TopComposite & BottomComposite могут быть легко перетащены в другие Composite.
MainComposite.java
package org.o7planning.tutorial.swt.module;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
public class MainComposite extends Composite {
/**
* Create the composite.
* @param parent
* @param style
*/
public MainComposite(Composite parent, int style) {
super(parent, style);
setLayout(new FillLayout(SWT.HORIZONTAL));
Composite composite = new Composite(this, SWT.NONE);
composite.setLayout(new GridLayout(1, false));
TopComposite topComposite = new TopComposite(composite, SWT.BORDER);
topComposite.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
BottomComposite bottomComposite = new BottomComposite(composite, SWT.BORDER);
bottomComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
}
@Override
protected void checkSubclass() {
}
}
12. Обработка события
No ADS
Обработка события SWT является очень простой с поддержкой WindowBuilder.
Иллюстрированные примеры:
- File/New/Other...
- Package: org.o7planning.tutorial.swt.event1
- Name: ButtonEventDemo
Кликнете правой кнопкой мыши на Button, выберите "Add event handler", отобразится серия событий соответствующие с Button.
WindowBuilder автоматически создает для вас code:
btnClickToMe.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// Sử lý sự kiện Button được chọn tại đây.
System.out.println("Button selected!");
}
});
ButtonEventDemo.java
package org.o7planning.tutorial.swt.event1;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class ButtonEventDemo {
protected Shell shlButtonEventDemo;
public static void main(String[] args) {
try {
ButtonEventDemo window = new ButtonEventDemo();
window.open();
} catch (Exception e) {
e.printStackTrace();
}
}
public void open() {
Display display = Display.getDefault();
createContents();
shlButtonEventDemo.open();
shlButtonEventDemo.layout();
while (!shlButtonEventDemo.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
protected void createContents() {
shlButtonEventDemo = new Shell();
shlButtonEventDemo.setSize(296, 205);
shlButtonEventDemo.setText("Button Event Demo");
shlButtonEventDemo.setLayout(new RowLayout(SWT.HORIZONTAL));
Button btnClickToMe = new Button(shlButtonEventDemo, SWT.NONE);
btnClickToMe.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
// Handle Button selected here!
System.out.println("Button selected!");
}
});
btnClickToMe.setText("Click to me");
}
}
No ADS
Технология Eclipse
- Установите Tycho для Eclipse
- Руководство Java OSGi для начинающих
- Создайте проект Java OSGi с Maven и Tycho
- Установите WindowBuilder для Eclipse
- Какую платформу я должен выбрать для разработки приложений Java Desktop?
- Программирование приложения Java Desktop с использованием SWT
- Руководство Eclipse JFace
- Установить Eclipse RAP Target Platform
- Установите RAP e4 Tooling для Eclipse
- Создать Eclipse RAP Widget из ClientScripting-based widget
- Руководство Eclipse RCP 4 для начинающих - e4 Workbench Application
- Установите RAP Tools для Eclipse
- Руководство Eclipse RAP для начинающих - приложение e4 Workbench
Show More
Руководства Java SWT
- Руководство Java SWT FillLayout
- Руководство Java SWT RowLayout
- Руководство Java SWT SashForm
- Руководство Java SWT Label
- Руководство Java SWT Button
- Руководство Java SWT Toggle Button
- Руководство Java SWT Radio Button
- Руководство Java SWT Text
- Руководство Java SWT Password Field
- Руководство Java SWT Link
- Программирование приложения Java Desktop с использованием SWT
- Руководство Java SWT Combo
- Руководство Java SWT Spinner
- Руководство Java SWT Slider
- Руководство Java SWT Scale
- Руководство Java SWT ProgressBar
- Руководство Java SWT TabFolder и CTabFolder
- Руководство Java SWT List
Show More