Co to jest SWT?

No właśnie, co to jest? SWT jest wytworem chorej wyobraźni twórców Eclipsa. Pewnego pięknego dnia zapragnęli mieć oni bibliotekę tak szybką jak AWT i jednocześnie tak bogatą jak Swing. Wymyślili więc bardzo ciekawe rozwiązanie…

O AWT i Swingu

AWT jest najstarszą graficzną biblioteką w Javie. Ma ona jedną zaletę, a mianowicie jest szybka. Posiada coś takiego jak AWT Native Interface – JAWT. Napisany w C++, pozwalający na integrację z pewnymi elementami systemu. Z drugiej strony AWT jest bardzo ubogie. Nie ma wielu komponentów, a skomplikowane API utrudnia pisanie własnych.

Dlatego też programiści z Suna wpadli na „genialny” pomysł implementacji wszystkich elementów GUI bezpośrednio w Javie. Otrzymali w ten sposób Swinga, który ma wiele klas reprezentujących najprzeróżniejsze elementy graficzne, ale ma też dwa poważne błędy. Pierwszy z nich to potworna powolność. Bardziej skomplikowany interfejs zaczyna mulić, zżerać zasoby i wkurwiać użyszkodnika. Drugą wadą jest całkowite olanie Look’n’Feel systemu. Dostajemy zatem swingowe potworki graficzne.

AWT + Swing = SWT

Twórcy Eclipsa mając do wyboru ubogie AWT i powolnego Swinga poszli trzecią drogą. Założyli, że wszystkie elementy Swinga (znaczną większość w zasadzie), należy zaimplementować w C++ tak jak w AWT. Elementy, które nie mają swoich odpowiedników w danym systemie są emulowane. Prawda, że genialne?

Pierwszy program SWT

Tworzymy nowy projekt w Eclipsie i następnie do listy bibliotek dodajemy:

eclipse/plugins/org.eclipse.swt.win32.win32.xxxxxx.jar

Lub inną odpowiednia dla danego systemu. Zamiast xxxxxx będzie ciąg cyferek, wybrać najnowszą wersję. W Eclipse 3.3 nie musimy już dodawać plików .dll z implementacją w C++, ponieważ pliki te są zaszyte w jarze.

Teraz wystarczy stworzyć kod:

public class Main {<br></br><br></br> public static void main(String[] args) {<br></br>  Display display = new Display();<br></br>  Shell shell = new Shell(display);<br></br>  shell.setText("dupa");<br></br>  shell.open();<br></br>  while(!shell.isDisposed())<br></br>   if(!display.readAndDispatch())display.sleep();<br></br><br></br>  display.dispose();<br></br> }<br></br>}

.. i jesteśmy w domu. Tylko zaraz czy ten kod czegoś nie przypomina?

Niestety tak. Obiekt Display odpowiada za połączenie pomiędzy SWT i systemem. Obiekt Shellodpowiada oknu głównemu aplikacji. Tworzymy więc połączenie pomiędzy naszym programem i systemem, tworzymy okno główne i…

Jak w Pascalu panie kochany, jak w Pascalu

… tworzymy pętle nasłuchującą komunikatów. Zastrzelić się można, ale problem ten jest do ominięcia dzięki delegowaniu zachowania. Przykładowy program rozbity na dwie klasy:

import org.eclipse.swt.widgets.Display;<br></br>import org.eclipse.swt.widgets.Shell;<br></br><br></br>public class Main {<br></br><br></br> /**<br></br>  * @param args<br></br>  */<br></br> public static void main(String[] args) {<br></br>  Display display = new Display();<br></br>  MyShell myShell = new MyShell();<br></br>  display.dispose();<br></br><br></br> }<br></br><br></br>}<br></br><br></br>class MyShell {<br></br> private Shell shell;<br></br> private Display display;<br></br> public MyShell() {<br></br>  display= Display.getCurrent();<br></br>  shell = new Shell(display);<br></br>  init();<br></br>  open();<br></br>  startEventLoop();<br></br> }<br></br><br></br> private void init() {<br></br>  shell.setText("dupa");<br></br> }<br></br><br></br> private void startEventLoop() {<br></br>  while (!shell.isDisposed())<br></br>   if (!display.readAndDispatch())<br></br>    display.sleep();  <br></br> }<br></br><br></br> private void open() {<br></br>  shell.open();<br></br> }<br></br><br></br>}

Jak widać nie dziedziczę po klasie Shell, a to dlatego, że się nie da.

To na dziś tyle. Następny tydzień muszę poświęcić na napisanie kilku przykładowych aplikacji JEE, więc do tego tematu wrócimy za dwa tygodnie. Zresztą tak jak i do Egg’a