standard widget toolkit
DESCRIPTION
Standard Widget Toolkit. ECESIS Eclipse Community Education Project An Eclipse Technology Research Subproject. Jak budować interfejs użytkownika?. Topics. SWT czy Swing? Terminologia Prosty program w SWT Wzorzec Observer Widgets Menus Layouts Graphics Drag and Drop. Swing. - PowerPoint PPT PresentationTRANSCRIPT
Mirosław OchodekMirosław [email protected]@put.poznan.pl
Sponsorzy:Sponsorzy:
Standard Widget ToolkitStandard Widget ToolkitJak budować interfejs użytkownika?Jak budować interfejs użytkownika?
ECESIS Eclipse Community Education Project
An Eclipse Technology Research Subproject
UCWorkbench Team Eclipse Summer School (2)
TopicsTopics▪SWT czy Swing?
▪Terminologia
▪Prosty program w SWT
▪Wzorzec Observer
▪Widgets
▪Menus
▪Layouts
▪Graphics
▪Drag and Drop
UCWorkbench Team Eclipse Summer School (3)
Operating system
sun.awt
SwingSwing
▪Biblioteka GUI w javie (javax.swing.*)
▪Była mało wydajna (poprawiono w Java 1.4)
▪Napisana w Javie (korzysta AWT – Java / C)
▪Niezależna platformowo (daleko od OS)
java.awt
Swing
UCWorkbench Team Eclipse Summer School (4)
Operating system
Windowing system
JNI
SWTSWT▪Zależna od platformy (dostępne implementacje dla
większości popularnych platform)
▪Wykorzystuje komponenty OS (JNI) – dispose!
▪Tylko kontrolki nie obsługiwane przez dany system zostały stworzone
▪Posiada wsparcie w postaci JFace
SWT
JFace
UCWorkbench Team Eclipse Summer School (5)
Operating system
Windowing system
JNI
SWT vs. SwingSWT vs. Swing▪Zależny od platformy
▪Wydajny (Komponenty z systemu operacyjnego)
▪Wykorzystuje wzorzec observer
▪Menadżery rozmieszczenia
SWT
JFace
Operating system
sun.awt
java.awt
Swing
▪Niezależny od platformy
▪Niewydajny
▪ Look and Feel
▪Wykorzystuje wzorze observer
▪Menadżery rozmieszczenia
UCWorkbench Team Eclipse Summer School (6)
org.eclipse.swt.SWTorg.eclipse.swt.SWT
▪Klasa z polami static public
▪Dostarcza stałe dla SWT
▪Bez instancji (eg. SWT.BOLD)
▪Stałe w SWT można sumować bitowo (eg. SWT.BOLD | SWT.ITALIC)
SWT
UCWorkbench Team Eclipse Summer School (7)
TerminyTerminy▪Display
• Połączenie między SWT i systemem GUI danej platformy
• Wykorzystywana do zarządzania pętlą komunikatów i wątkami UI
▪Shell
• Okno zarządzane przez Window menadżer danego OS
▪Composite
• Widget, który może zawierać inne widgety
▪ Layout manager
• Klasa odpowiedzialna za zarządzanie rozkładem
UCWorkbench Team Eclipse Summer School (8)
Jak uruchomić program w SWT?Jak uruchomić program w SWT?
▪ classpath SWT.jar library (eclipse/plugins)
▪ Add to the JVM arguments
• Djava.library.path=<katalog z dll>
• albo wybrać Run as ... SWT Application
▪ JFace wymaga bibliotek:
• org.eclipse.jface_x.jar, org.eclipse.core.commands_x.jar, org.eclipse.equinox.common_x.jar, (org.eclipse.osgi)
▪ Podczas pisania pluginów nie trzeba się tym martwić!
UCWorkbench Team Eclipse Summer School (9)
Basic SWT applicationBasic SWT application
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
Label label = new Label(shell, SWT.CENTER);
label.setText(”Witaj świecie");
label.pack();
shell.pack();
shell.open();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ())
display.sleep ();
}
display.dispose ();
}
UCWorkbench Team Eclipse Summer School (10)
Wzorzec ObserverWzorzec Observer
Lalaaaalalaa!
Dziękujemy.Proszę nie
dzwonić, to my zadzwonimy…
Następny proszę!
UCWorkbench Team Eclipse Summer School (11)
Wzorzec ObserverWzorzec Observer
UCWorkbench Team Eclipse Summer School (12)
SWT&ObserverSWT&Observer
Widget
Control
Scrollable
Composite
Button
Object
public void addListener (int eventType, Listener listener)
public interface Listener { void handleEvent (Event event);}
public void addSelectionListener (SelectionListener listener)
public interface SelectionListener extends SWTEventListener { public void widgetSelected(SelectionEvent e); public void widgetDefaultSelected(SelectionEvent e);}
UCWorkbench Team Eclipse Summer School (13)
Composite Pattern IdeaComposite Pattern Idea
UCWorkbench Team Eclipse Summer School (14)
Wzorzec CompositeWzorzec Composite
UCWorkbench Team Eclipse Summer School (15)
SWT&CompositeSWT&Composite
Widget
Control
Scrollable
Composite
Button
Object
public Control (Composite parent, int style)
Button button = new Button(shell,SWT.PUSH);*
UCWorkbench Team Eclipse Summer School (16)
WidgetsWidgets
UCWorkbench Team Eclipse Summer School (17)
LabelLabel
Label label = new Label(shell, SWT.CENTER);label.setText("Hello World");
label.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLUE));
UCWorkbench Team Eclipse Summer School (18)
ButtonButtonButton button = new Button(shell, SWT.PUSH);button.setText("Click me!");
Button button = new Button(shell, SWT.CHECK);button.setText("Click me!");
Button button = new Button(shell, SWT.ARROW|SWT.RIGHT);
Button button = new Button(shell, SWT.RADIO);button.setText("Click me!");
Button button = new Button(shell, SWT.TOGGLE);button.setText("Click me!");
UCWorkbench Team Eclipse Summer School (19)
Button UsageButton Usage
Button button = new Button(shell, SWT.PUSH);button.setText("Click me!");button.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { System.out.println(e.getSource().toString()+" was clicked!"); }});
Button {Click me!} was clicked!
UCWorkbench Team Eclipse Summer School (20)
TextText
Text text = new Text(shell, SWT.SINGLE | SWT.BORDER);text.setText("Text");
Text text = new Text(shell, SWT.MULTI | SWT.BORDER | SWT.VERTICAL);text.setText("Text\nText");
Text text = new Text(shell, SWT.PASSWORD | SWT.SINGLE | SWT.BORDER);text.setText("Text");
UCWorkbench Team Eclipse Summer School (21)
Text UsageText UsageText text = new Text(shell, SWT.SINGLE | SWT.BORDER);text.addVerifyListener(new VerifyListener(){ public void verifyText(VerifyEvent e) { if (e.text.matches("[0-9]*")){ e.doit = true; }else{ e.doit = false; } }});text.addModifyListener(new ModifyListener(){ public void modifyText(ModifyEvent e) { System.out.println(((Text)(e.widget)).getText()+
" - text after modification"); }});
2 - text after modification23 - text after modification232 - text after modification2321 - text after modification23212 - text after modification232123 - text after modification2321231 - text after modification
UCWorkbench Team Eclipse Summer School (22)
ProgressBarProgressBar
ProgressBar pb = new ProgressBar(shell, SWT.SMOOTH);pb.setMinimum(0);pb.setMaximum(100);pb.setSelection(34);
ProgressBar pb = new ProgressBar(shell, SWT.SMOOTH | SWT.INDETERMINATE);pb.setMinimum(0);pb.setMaximum(100);
UCWorkbench Team Eclipse Summer School (23)
Slider and ScaleSlider and Scale
Slider slider = new Slider(shell, SWT.HORIZONTAL);slider.setMinimum(0);slider.setMaximum(100);slider.setSelection(30);
Scale scale = new Scale(shell, SWT.HORIZONTAL);scale.setMinimum(0);scale.setMaximum(100);scale.setSelection(30);
UCWorkbench Team Eclipse Summer School (24)
ListListList list = new List(shell, SWT.MULTI);list.add("First");list.add("Second");list.add("Third");list.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent e) { System.out.println("Default action - double click(Windows)"); widgetSelected(e); } public void widgetSelected(SelectionEvent e) { System.out.println("Selected items:"); String[] selection = ((List)(e.widget)).getSelection(); for (int i = 0; i < selection.length; i++) { System.out.println(" - "+selection[i]+""); } }});
UCWorkbench Team Eclipse Summer School (25)
ComboCombo
Combo combo = new Combo(shell, SWT.DROP_DOWN);combo.add("First");combo.add("Second");combo.add("Third");combo.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent e) { System.out.println("Default action - Enter (Windows)"); widgetSelected(e); } public void widgetSelected(SelectionEvent e) { System.out.println("Selected "+((Combo)(e.widget)).getText()); }});
UCWorkbench Team Eclipse Summer School (26)
TreeTreeTree tree = new Tree(shell, SWT.SINGLE);TreeItem node1 = new TreeItem(tree, SWT.NULL);node1.setText("1. Main node");TreeItem node11 = new TreeItem(node1, SWT.NULL);node11.setText("1.1 First sub node");TreeItem node12 = new TreeItem(node1, SWT.NULL);node12.setText("1.2 First sub node");tree.addTreeListener(new TreeListener(){ public void treeCollapsed(TreeEvent e) { System.out.println(((TreeItem)e.item).getText()+ " was collapsed");} public void treeExpanded(TreeEvent e) { System.out.println(((TreeItem)e.item).getText()+ " was expanded"); }});
UCWorkbench Team Eclipse Summer School (27)
MenuMenuMenu menuBar = new Menu(shell, SWT.BAR);shell.setMenuBar(menuBar);
MenuItem fileTitle = new MenuItem(menuBar, SWT.CASCADE);fileTitle.setText("File");Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);fileTitle.setMenu(fileMenu);
MenuItem exitItem = new MenuItem(fileMenu, SWT.PUSH);exitItem.setText("Exit");exitItem.addSelectionListener(new SelectionListener(){ public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } public void widgetSelected(SelectionEvent e) { ((MenuItem)(e.widget)).getParent().getShell().close(); }});
SWT.BARSWT.DROP_DOWNSWT.POP_UP
SWT.CHECKSWT.CASCADESWT.PUSHSWT.RADIO
SWT.SEPARATOR
setManuBar – SWT.BARsetMenu – SWT.POP_UP
UCWorkbench Team Eclipse Summer School (28)
LayoutsLayouts▪Kontroluje rozmiar i rozmieszczenie komponentów
▪Klasy menadżerów, są podklasami abstrakcyjnej klasy Layout
▪SWT udostępnia kilka podstawowych layout’ów
• FillLayout, rozmieszcza komponenty w rzędzie lub w kolumnie, równych rozmiarów, wypełniając dostępne miejsce
• RowLayout, ustawia komponenty w rzędzie lub kolumnie
• GridLayout, wpisuje komponenty w siatkę
• FormLayout, ustawia komponenty doczepiając je między sobą
UCWorkbench Team Eclipse Summer School (29)
Praca zPraca z Layout Layout’ami’ami
▪Importujemy odpowiedni pakiet SWT:
• import org.eclipse.swt.layout.*;
▪Aby przypisać Layout obiektowi klasy Composite użyj setLayout(Layout)
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
UCWorkbench Team Eclipse Summer School (30)
Layout DataLayout Data
▪ Klasy layout’ów często wykorzystują pomocnicze klasy nazywane ogólnie LayoutData
• RowLayout -> RowData
• GridLayout -> GridData
• FormLayout -> FormData
▪ Przypisanie danych układu
Button button = new Button(shell, SWT.PUSH);
button.setLayoutData(new RowData(10, 20));
UCWorkbench Team Eclipse Summer School (31)
FillLayoutFillLayout▪Ustawia komponenty w rzędzie lub
kolumnie
▪Wszystkie tego samego rozmiaru
▪Bez zawijania wierszy
▪Nie można zdefiniować marginesów i odstępów
▪Wykorzystywany do:
• Umieszczanie przycisków na paskach zadań
• Umieszczania checkbox’ów w grupy
UCWorkbench Team Eclipse Summer School (32)
FillLayout ExampleFillLayout Example
Display display = new Display();
Shell shell = new Shell(display);
FillLayout fillLayout = new FillLayout();
fillLayout.type = SWT.VERTICAL;
shell.setLayout(fillLayout);
new Button(shell, SWT.PUSH).setText("1'st Button");
new Button(shell, SWT.PUSH).setText("Big Button");
new Button(shell, SWT.PUSH).setText("Button 3");
new Button(shell, SWT.PUSH).setText("Last Button");
shell.pack();
shell.open();
UCWorkbench Team Eclipse Summer School (33)
FillLayout ExampleFillLayout ExamplefillLayout.type = SWT.VERTICAL;
fillLayout.type = SWT.HORIZONTAL;
UCWorkbench Team Eclipse Summer School (34)
RowLayoutRowLayout
▪RowLayout ma możliwość zawijania wierszy
▪Można ustawiać marginesy i odległości
▪Różne właściwości mogą zostać ustawione
• Wysokość i szerokość widget’ów
• Użyj obiektu klasy RowData
UCWorkbench Team Eclipse Summer School (35)
RowLayout Example RowLayout Example RowLayout rowLayout = new RowLayout();
rowLayout.wrap = true;
rowLayout.pack = true;
rowLayout.justify = true;
rowLayout.type = SWT.HORIZONTAL;
rowLayout.marginLeft = 4;
rowLayout.marginTop = 4;
rowLayout.marginRight = 4;
rowLayout.marginBottom = 4;
rowLayout.spacing = 0;
shell.setLayout(rowLayout);
UCWorkbench Team Eclipse Summer School (36)
RowLayout ExampleRowLayout Example
rowLayout.wrap = false;
rowLayout.pack = false;
rowLayout.justify = false;
UCWorkbench Team Eclipse Summer School (37)
RowData ExampleRowData Example
RowLayout rowLayout = new RowLayout();
shell.setLayout(rowLayout);
Button button1 = new Button(shell, SWT.PUSH);
button1.setText("First");
button1.setLayoutData(new RowData(50, 100));
Button button2 = new Button(shell, SWT.PUSH);
button2.setText("Second");
button2.setLayoutData(new RowData(200, 400));
UCWorkbench Team Eclipse Summer School (38)
GridLayoutGridLayout
▪Chyba najczęściej wykorzystywany
▪Najbardziej rozbudowany
▪Komponenty wpisane w siatkę
• Kolumny i rzędy dostowują się do wielkości zawartości
▪Różne wartości mogą zostać ustawione
▪Do komponentów można dodawać GridData
UCWorkbench Team Eclipse Summer School (39)
GridLayout ExampleGridLayout Example
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
shell.setLayout(gridLayout);
new Button(shell, SWT.PUSH).setText("B1");
new Button(shell, SWT.PUSH).setText("Second Button");
new Button(shell, SWT.PUSH).setText("Third Button");
new Button(shell, SWT.PUSH).setText("B4");
new Button(shell, SWT.PUSH).setText("B5");
new Button(shell, SWT.PUSH).setText("Button Number 6");
UCWorkbench Team Eclipse Summer School (40)
GridLayout FieldsGridLayout Fields
▪Pola
• makeColumnsEqualWidth narzuca kolumną równą szerokość
• marginWidth ustala lewy i prawy margines
• marginHeight ustala górny i dolny margines
• horizontalSpacing i verticalSpacing odległości między komponentami
UCWorkbench Team Eclipse Summer School (41)
GridDataGridData
▪Zawiera wskazówki dla GridLayout
▪Dodaje się za pomocą metody setLayoutData
Button aButton = new Button(shell, SWT.PUSH);
aButton.setText("FirstButton");
aButton.setLayoutData(new GridData());
UCWorkbench Team Eclipse Summer School (42)
GridData FieldsGridData Fields
▪horizontalAlignment: specyfikuje gdzie umiścić widget horyzontalnie lub wertykalnie w komórce siatki
• BEGINNING, CENTER, END, FILL
▪horizontalIndent: umożliwia przesunięcie kontrolki w prawo o wybraną liczbę pixeli
• Użyteczne kiedy horizontalAlignment jest BEGINNING
▪horizontalSpan i verticalSpan: jedna kontrolka może zajmować kilka komórek
UCWorkbench Team Eclipse Summer School (43)
GridData FieldsGridData Fields
▪grabExcessHorizontalSpace i grabExcessVerticalSpace: pozwala kontrolkom zwiększać rozmiar jeśli ich rodzic zmienia rozmiar
▪widthHint i heightHint: zalecany rozmiar kontrolki
UCWorkbench Team Eclipse Summer School (44)
ĆwiczenieĆwiczenie
UCWorkbench Team Eclipse Summer School (45)
ĆwiczenieĆwiczenie
UCWorkbench Team Eclipse Summer School (46)
Ćwiczenie - rozwiązanieĆwiczenie - rozwiązanie
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 3;
shell.setLayout(gridLayout);
new Label(shell, SWT.NONE).setText(„Name:");
Text userName = new Text(shell, SWT.SINGLE | SWT.BORDER);
GridData gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gridData.horizontalSpan = 2;
userName.setLayoutData(gridData);
…
Każdy widget musi mieć własną instancję GridData
UCWorkbench Team Eclipse Summer School (47)
Ćwiczenie - rozwiązanieĆwiczenie - rozwiązanie
new Label(shell, SWT.NONE).setText(”Sex:");
Combo sex = new Combo(shell, SWT.NONE);
sex.setItems(new String [] {"Male", "Female"});
gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
gridData.horizontalSpan = 2;
sex.setLayoutData(gridData);
new Label(shell, SWT.NONE).setText("Photo:");
Canvas photo = new Canvas(shell, SWT.BORDER);
gridData = new GridData(GridData.FILL_BOTH);
gridData.widthHint = 80;
gridData.heightHint = 80;
gridData.verticalSpan = 3;
photo.setLayoutData(gridData);
UCWorkbench Team Eclipse Summer School (48)
GridData ExampleGridData Example
UCWorkbench Team Eclipse Summer School (49)
FormLayoutFormLayout
▪Tworzy FormAttachments dla krawędzi widget’a
• Przechowuje attachments jako layout data
• Przyłącza krawędź relatywnie do Composite’a rodzica innego widget’a w ramach layout’u
▪Pozwala w pełni wyspecyfikować położenie widgetu
http://www.eclipse.org/articles/Article-Understanding-Layouts/Understanding-Layouts.htm
UCWorkbench Team Eclipse Summer School (50)
GraphicsGraphics▪ GC – Graphics Context (można rysować po wszystkich klasach
które implementują interfejs Drawable (np. Image, Control, Canvas itd.)
▪ Jeśli używasz konstruktora GC(), nie zapomnij dispose!
▪ Rysowania dokonujemy wewnątrz metody paintControl(PaintEvent) należącej do PaintListener
Composite.addPaintListener(new PaintListener(){
public void paintControl(PaintEvent event){
Display display = event.display;
GC gc = event.gc
gc.drawRectangle(0,0,10,10);
}
});
UCWorkbench Team Eclipse Summer School (51)
ColorColor
▪Domyślne kolory systemowe można uzyskać przy pomocy Display poprzez metodę getSystemColor(id) (SWT.COLOR...), ich nie wolno disposować
▪Albo new Color(device, 255, 255, 255), te kolory należy usuwać
• Device -> Display, Printer
UCWorkbench Team Eclipse Summer School (52)
FontsFonts
▪Domyśną czionkęmożna uzyskać poprzez klasę Display wywołując metodę getSystemFont()
▪Albo stworzyć obiekt Font
• new Font(device, ”Arial”, 12, SWT.BOLD);
• new Font(device, new FontData(”Arial”,12,SWT.BOLD));
• Device -> Display, Printer
• Należy je usuwać!
UCWorkbench Team Eclipse Summer School (53)
Drag and dropDrag and drop
▪Drag Source – dostarcza dane które mają być upuszczone
• Ten sam widget
• Inny widget
• Inna aplikacja!
▪Transfer object – obiekt do przenoszenia danych (np. dla plików FileTransfer – przechowuje lokalizacje plików)
▪Drop Target – odbiorca danych
UCWorkbench Team Eclipse Summer School (54)
DragSource ExampleDragSource Examplefinal Label dragLabel = new Label(shell, SWT.BORDER);dragLabel.setText("text to be transferred");
int operations = DND.DROP_MOVE | DND.DROP_COPY;DragSource source = new DragSource(dragLabel, operations);
Transfer[] types = new Transfer[] { TextTransfer.getInstance() };source.setTransfer(types);
source.addDragListener(new DragSourceListener() { public void dragStart(DragSourceEvent event) { if (dragLabel.getText().length() == 0) { event.doit = false; } } public void dragSetData(DragSourceEvent event) { if (TextTransfer.getInstance().isSupportedType(event.dataType)) { event.data = dragLabel.getText(); } } public void dragFinished(DragSourceEvent event) { if (event.detail == DND.DROP_MOVE) dragLabel.setText(""); }});
UCWorkbench Team Eclipse Summer School (55)
DropTarget ExampleDropTarget Example
final Text dropText = new Text(shell, SWT.BORDER);
operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;DropTarget target = new DropTarget(dropText, operations);
final TextTransfer textTransfer = TextTransfer.getInstance();target.setTransfer(new Transfer[]{textTransfer});
target.addDropListener(new DropTargetAdapter() { public void drop(DropTargetEvent event) { if (textTransfer.isSupportedType(event.currentDataType)) { String text = (String) event.data; dropText.setText(text); } }});
UCWorkbench Team Eclipse Summer School (56)
SWT - KoniecSWT - Koniec
Dziękuje slides.dispose()