czwartek, 15 października 2009

Prosty Web Service + prosty klient mobilny J2ME z użyciem NetBeans i GlassFish V2

Szkoła się zaczęła a razem z nią zajęcia dotyczące Web Serviców. Pierwsze laboratoria to baaardzo prosty wstęp na którym trzeba było napisać web service i do niego klienta. Jako, że trochę w tym porobiłem już to przygotowałem prezentację jak to wykonać tworząc dodatkowo klienta na urządzanie mobilne z Java ME z użyciem NetBeans oraz GlassFish.

Prezentację postanowiłem się podzielić ze wszystkimi, zapraszam ! ;)


Oczywiście jest to super prosta aplikacja ale mam nadzieje, że komuś się przyda przy rozpoczynaniu przygody z technologiami Javowymi ;-)

poniedziałek, 5 października 2009

Co nowego w Java 7 ? Część druga

Dawno dawno temu pisałem już co nowego było planowane w nowej Javie (artykuł: Co nowego w Java 7 ?). Dzisiaj zapraszam do obejrzenia wywiadu z Dannym Cowardem - głównym architektem dla aplikacji klienckich w firmie Sun. Przedstawia on pokrótce co przeszło ciężkie głosowania i dyskusje i pojawi się w nowej Javie.

Czas trwania: 24:31

Podsumowując:
Nowe słowo kluczowe module
Służyć będzie do tworzenia modułów. Docelowo ma zastąpić wykorzystywanie classpath.
Przykład:
module wazny_modul;
package com.blogspot.wookasz.java7;

class WaznaKlasa {
//...
}
Definicja modułu w pliku java:
modules wazny_modul @1.5 {
requires inny_wazny_modul @2.0;
requires jeszcze_inny_wazny_modul @1.0;
}


Switch po Stringu
To przetrwało. Przykład z poprzedniego artykułu:
String str = "test";
switch(str) {
case "test":
System.out.println("TEST!");
break;
case "test2":
System.out.println("TEST2");
break;

default:
System.out.println("KLOPS!");
break;
}


Wyłapywaniewielu typów wyjątków w jednym bloku catch.
To też przetrwało (na szczęście !)
try {
mbs.registerMBean(mbean, name);
} catch (InstanceAlreadyExistsException | 
MBeanRegistrationException |
NotCompliantMBeanException e) {
logger.log(e);
throw e;
}


Wnioskowanie typu
Też przeszło:)
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();

Będzie można zastąpić przez:
Map<String, List<String>> anagrams = new HashMap<>();

Elvis operator (lub Null-Safe Operator) ?:
O tym szczerze mówiąc wcześniej nie słyszałem. Często w kodzie sprawdzamy czy jakiś obiekt nie jest nullem i w zależności od tego wykonujemy inne operacje. Teraz takiego ifa będzie można zastąpić jedną instrukcją:
String s = object?.toString() ?: "nothing";
int i = intObject ?: -1;
Nie jestem tylko przekonany czy ten pierwszy zapis jest w pełni zrozumiały jak się na niego spojrzy...

NIO #2 API
I/O w nowej odsłonie!:) Co teraz dodatkowego ?
- przeszukiwanie katalogów (dość rozbudowane)
- nasłuchiwanie na zmiany w plikach
- asynchroniczność
I inne

Poza tym:
- nowości w Swingu (wywiad od 16minuty, pokazują demo)
- nowy odśmiecacz pamięci (może będzie działać ?:P)
- zmiany w bytecodzie pod kątem innych języków programowania
- zmiany w bibliotekach od kolekcji i współbieżności (przykłady)
- duuuużo rzeczy w ramach projektu Coin. Zapraszam do zapoznania się z ich stroną -> link. Długa lista nowości.

Dla osób do których jeszcze nie dotarła informacja - NIE będzie domknięć w nowej Javie! Nie skomentuje tego...

Plan wydania -> Marzec 2010

https://jdk7.dev.java.net/
http://openjdk.java.net/projects/jdk7/

EDIT:
Jednak domknięcia będą :) -> Co nowego w Java 7 ? Część trzecia - będą domknięcia !

EDIT 2:
Jednak nie będzie... -> (Prawdopodobnie ostatnie) Podsumowanie nowości w Java 7

wtorek, 18 sierpnia 2009

Trochę humoru z reklam

Humoru też dawno nie było! Dlatego wrzucam troszkę reklam, które są wg mnie "masterpiece" ^^






piątek, 7 sierpnia 2009

(Nie?)istniejąca ścieżka do bazy danych - błąd SQL1052N w DB2

Trwają moje przygotowania do certyfikatu DB2 Administrator, więc chyba troszkę zmienię tematykę bloga z programowania na bazy danych. Zwłaszcza, że ostatnio prawie nic nie piszę to może tym nadrobię :)

Podczas nauki zawiłej komendy CREATE DATABASE natrafiłem na dziwny błąd, gdy chciałem utworzyć bazę danych w podanej lokalizacji.
Komenda:
db2 => create database hellodb on f:\bazydb2\
zwróciła mi błąd treści:
SQL1052N  Ścieżka bazy danych "F:\bazydb2\" nie istnieje.

Upewniłem się 2x, że dany katalog istnieje (a nawet jeśli nie to chyba powinien zostać utworzony?). Zasięgnąłem więc do helpa:
db2 => ? SQL1052N


SQL1052N Ścieżka bazy danych "<ścieżka>" nie istnieje.

Objaśnienie:

Ścieżka podana w parametrze "<ścieżka>" bieżącej komendy jest
niepoprawna. Albo nie ma ścieżki o takiej nazwie, albo ścieżka została
określona, podczas gdy zmienna rejestrowa DB2_CREATE_DB_ON_PATHS jest
wyłączona (tylko w systemie Windows).

...

I odpowiedz znaleziona. Bardzo dziwne, że nie można pod windowsem tworzyć bazy danych w dowolnym katalogu domyślnie. W dalszej części wyjaśnienia kodu błędu dotyczącym możliwych akcji znajdowało się wyjaśnienie:
*  W systemie Windows, jeśli wszystkie aplikacje, które będą się łączyły
z bazą danych, są zbudowane przy użyciu interfejsu API co najmniej w
wersji 9, wtedy można włączyć zmienną środowiskową
DB2_CREATE_DB_ON_PATHS, aby obsługiwała tę ścieżkę jako ścieżkę bazy
danych.


Ok, ale żeby możliwe było utworzenie bazy w podanej lokali należy wykonać komendę:
db2set DB2_CREATE_DB_ON_PATH=YES
A następnie po tym konieczny restart usługi zarządzającej bazami danych:
db2stop
2009-08-07 14:47:50 0 0 SQL1064N Działanie menedżera baz danych zakończyło się poprawnie.
SQL1064N Działanie menedżera baz danych zakończyło się poprawnie.

db2start
2009-08-07 14:47:56 0 0 SQL1063N Komenda DB2START została wykonana poprawnie.
SQL1063N Komenda DB2START została wykonana poprawnie.


I sprawdzamy czy można już utworzyć:
db2 => create database hellodb on f:\bazydb2
DB20000I Wykonanie komendy CREATE DATABASE zakończyło się pomyślnie.

:)

Przy okazji znalazłem błąd w pomocy DB2. W informacji o błędzie podana jest zmienna DB2_CREATE_DB_ON_PATHS, natomiast faktycznie istnieje DB2_CREATE_DB_ON_PATH. Poszukam gdzie to można zgłosić.

środa, 15 lipca 2009

NetBeans 6.7 - fail dla php ?

Od paru dni korzystam z nowego NetBeansa w moim projekcie PHP i muszę szczerze przyznać, że jestem zawiedziony i to bardzo.
Po pierwsze wydajność - hmm sorry ale jakieś wielkiej różnicy w wydajności nie dostrzegłem. Features on Demand? No pomysł szczytny ale jakoś nadal nie widzę wzrostu wydajności - co więcej, gdy np. tworze nowy projekt Java ME/C++/cokolwiek i uruchamia się komponent za obsługę danej platformy odpowiedzialny trwa to spooooro czasu. Co ciekawe dysk jakoś w tym czasie nie pracuje dopiero na jakieś 2-3 sek przed samą aktywacją coś pomuli.
Wracając do PHP co mnie zdenerwowało:
- szybkość podpowiadania składni zwolniła bardzo mocno, mój kolega z zespołu po godzinie ją wyłączył, bo do niczego się nie nadawało - mam podobne wrażenia
- podpowiadanie składni potrafiło nawet nawalać w prostych przypadkach np. brak jakichkolwiek podpowiedzi o pola/metody klasy lub dziedziczonych
- ctrl+lewy klik przestał działać dla przypadków dla których działał w wersji 6.5
I teraz to co mnie zniszczyło... po uruchomieniu projektu korzystającego z SVN i próbie updatea netbeans poinformował mnie, że nie mam klienta. Poprosiłem go (bo była taka opcja) aby sam go ściągnął i zainstalował - dostałem komunikat, że jednak go MAM! No to super ponowna próba updatea i to samo! No to postanowiłem sam ściągnąć klienta i go zainstalować. Po podpięciu go pod NetBeans ten stwierdził, że jednak mam jego za starą wersję i nie będzie z nią działać . Ok, nagrałem najnowszą dostępna (1.6.cośtam). Znowu podpinanie i.... ! Teraz NetBeans twierdzi, że wszystkie pliki z projekcie są nowe, nie działają żadne ignore na katalogach a jakiekolwiek operacje ponownego ich zakładania nie przynoszą żadnego rezultatu. Jest fajnie!
Postanowiłem wywalić projekt i ściągnąć całość od nowa z SVN. Tym razem już miarka się przebrała, bo gdy chciałem połączyć się z serwerem pasek postępu po sekundzie w nieznanych okolicznościach znikał i nic nie mogłem zrobić.
Tyle od sfrustrowanego Łukasza i jego walk z NetBeansem. Wróciłem do 6.5 gdzie wszystko działa poprawnie.
Być może ja coś skopałem, czegoś nie skonfigurowałem, jestem głupi itp. ale używam tego środowiska od ponad roku i myślałem, że jednak taka operacja nie przysporzy problemów.

Nie testowałem jeszcze projektów Javowych w nowej wersji, ale w niedługim czasie to mam nadzieję nadrobię i liczę, że będzie ok.

A jakie Wy macie doświadczenia z nowym NB 6.7 ??

_
Dodam jeszcze, że pracuję na:
PC - Athlon X2 3800, 3GB RAMu, dysk 650GB SATA, win xp
oraz
Laptop - Core 2 Duo P8400, 4GB RAMu, Dysk 160GB SATA, vista
na obu te same doświadczenia.

sobota, 16 maja 2009

Proste skalowanie aplikacji z Terracotta na Poznań Java User Group - 26.05.09r.

Zapraszam wszystkich na spotkanie Poznańskiej Grupy Użytkowników Javy poświęconemu oprogramowaniu wspomagającym skalowanie aplikacji w poziomie (ang. scaling out) o nazwie Terracotta. Prelegentem będzie Krzysztof Kliś programista w firmie BS Partner.

Oto krótkie streszczenie tego co będzie można usłyszeć na miejscu:
Terracotta jest oprogramowaniem open source, które pozwala na proste skalowanie w poziomie aplikacji działających na platformie Java, bez konieczności wykorzystywania dodatkowego kodu lub zewnętrznych baz danych. Efekt taki udało się uzyskać dzięki umieszczeniu całego mechanizmu klastrowania pomiędzy maszyną wirtualną Javy a warstwą aplikacji, dzięki czemu jest ona w praktyce całkowicie przezroczysta dla programisty. W trakcie prezentacji omówiona zostanie architektura Terracotty, przedstawione przykłady jej zastosowań (wraz z utworzeniem prostego projektu w Eclipse), a także współpraca z innymi technologiami opartymi na Javie (na przykładzie JRuby). Poruszone zagadnienia obejmą ponadto doświadczenia autora w pracy z Terracottą w kontekście wydajności, zagadnienia związane z licencją Terracotta Public License, jak również informacje na temat społeczności związanej z Terracottą.

Dodam jeszcze filmik z youtube mówiący co to jest Terracotta:


Miejsce i data spotkania:
Siedziba Cognifide - Aleje Wielkopolskie 4, Poznań
Wtorek 26.05.2009, godzina 18:00
Wymagana jest rejestracja pod adresem: www.oiola.com/e/382-spotkanie-poznan-jug-260509-terracota-krzysztof-klis/

Linki:
Web λ.0 - Functional programming for the Web - blog Krzysztofa Klisia

sobota, 9 maja 2009

Podstawowe komponenty w LWUIT #part 1/2

Skoro pierwsze spotkanie z biblioteką LightWeightUserInterfaceToolkit mamy już za sobą, chciałbym dziś przybliżyć podstawowe komponenty jakimi możemy się posługiwać aby wzbogacić UI naszej aplikacji mobilnej.

Hierarchia klas w LWUIT:


Component
To klasa bazowa dla wszystkich komponentów, tylko klasy które dziedziczą po niej mogą być wyświetlane na ekranie. W ogólności nie będziemy z niej korzystać chyba, że zaczniemy pisać własne komponenty to wtedy możemy się nią zainteresować;-)

Container
Kontener to obiekt który umożliwia przechowywanie w sobie wielu innych komponentów. W tym innych kontenerów które zawierają inne komponenty, możliwość zagnieżdżania jest praktycznie nieograniczona.
Komponenty które dodajemy do kontenera trafiają na listę wg której są później wyświetlane na ekranie, jeśli nie podamy indeksu na który ma on trafić to jest domyślnie umieszczany na ostatnim miejscu.

Form
Formularz jest klasą reprezentującą okna w programie. Składa się on z 3 części: paska tytułowego, zawartości okna oraz paska menu. Jak to wygląda przedstawia obrazek obok.
Jeśli chodzi o pasek tytułowy to wg mnie jest on trochę ograniczony ponieważ możemy na niego wrzucać tylko tekst, no ale gdyby było inaczej to może inaczej też by się nazywał ;P Zawartość okna to nasze pole gdzie wrzucamy jakiekolwiek komponenty potrzebujemy. Możemy je rozmieszczać za pomocą różnych układów (layouts) ale o nich znacznie więcej w innej części tutoriala.
Pasek menu zawiera pozycje pomocne przy sterowaniu aplikacją, jeśli jest ich więcej niż dwie to będzie nam się wyświetlać menu wyboru. Przycisku na tym pasku tworzy się poprzez dodanie do obiektu formularza obiektów typu Command.
Form udostępnia nam dwa konstruktory. Jeden jest bez bezparametrowy, a drugi posiada parametr typu String który jest tekstem na pasku tytułowym. Formularz wyświetlamy za pomocą metody Form.show();.
API tej klasy jest dość bogate i jego znajomość jest podstawą z którą trzeba się zapoznać.

Label
Label to po prostu komponent który wyświetla tekst i/lub obrazek. Należy pamiętać by używać go tylko w tym wypadku! Gdyby istniała potrzeba jakieś interaktywności to lepszym wyborem byłoby skorzystanie z klasy Button.
Dla zawartości etykiety możemy definiować wyrównania - domyślnym jest LEFT, ale poza nim jest jeszcze CENTER i RIGHT. Ponadto jeśli dodany jest zarówno tekst jak i obrazek to możemy wyrównać tekst względem obrazka mamy do dyspozycji pozycje: TOP, BOTTOM, LEFT, RIGHT. A wykonujemy to za pomocą metody: setTextPosition(Label.TOP);.
Może mały przykład:
Form form = new Form("Label in action!");
// utworzenie obrazka
Image image = Image.createImage("/picture.png");

Label label = new Label(image);
label.setText("Hello Label !!");
label.setAlignment(Label.CENTER);
label.setTextPosition(Label.BOTTOM);

// dodanie labela do formularza
form.addComponent(label);
// wyświetlenie
form.show();
Button
Przyciski wywołują dla nas jakieś akcje. Podobnie jak Label może składać się z ikony i teksty (przecież jest to klasa rozszerzająca Label^^). Do przycisku możemy podpiąć dwa rodzaje "słuchaczy" (nie lubię tej nazwy, zna ktoś może jakąś lepsza polską ?;), na aktywowanie (FocusListener) oraz akcje (ActionListener). Ponieważ drugi przypadek jest częstszy w użyciu to posłużę się nim jako przykładem. Może od razu podam przykład który wyjaśni działanie tego mechanizmu:
Button coolButton = new Button("Great button!");
coolButton.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {
// instrukcje w tej metodzie zostaną wywołane po wciśnięciu przycisku
}
});
Można też utworzyć osobne klasy implementujące ten interfejs i podać je jako parametr. Zależy jakie kto rozwiązanie lubi i jak długa jest metoda obsługi zdarzenia.

RadioButton
To element dobrze nam znany chociażby z HTMLa. Jest to element który może posiadać dwa stany wybrany oraz nie wybrany. Stan taki może posiadać tylko jeden radio button w obrębie grupy o której za chwilę. Jeśli chodzi o zasady tworzenia oraz przypisywania obsługi zdarzeń to są one identyczne jak w przypadku przycisku.

ButtonGroup
Ta użyteczna klasa w sumie nie powinna zostać nazwana komponentem a bardziej takim zarządcą grupy komponentów. Jej funkcją jest grupowanie jakiegoś zbioru przycisków, żeby np. przypilnować, że został zaznaczony tylko jeden RadioButton.
Przykład działania:
// tworzenie przycisków
RadioButton radio1 = new RadioButton("RadioButton1");
radio1.setSelected(true); // niech jeden będzie zaznaczony domyślnie
RadioButton radio2 = new RadioButton("RadioButton2");
RadioButton radio3 = new RadioButton("RadioButton3");
RadioButton radio4 = new RadioButton("RadioButton4");

// tworzenie grupy oraz dodawanie do niej przycisków
ButtonGroup group = new ButtonGroup();
group.add(radio1);
group.add(radio2);
group.add(radio3);
group.add(radio4);

/**
* Jakieś operacje
*/

// pobranie indeksu który przycisk jest zaznaczony
int index = group.getSelectedIndex();
// pobranie zaznaczonego przycisku
RadioButton radioSelected = group.getRadioButton(index);
Gdy mamy indeks zaznaczonego przycisku to później można sobie zrobić jakiegoś switcha i wykonać odpowiednie akcje. Należy tylko pamiętać o tym by nie zmieniać kolejności ich dodawania do grupy, bo wg tego są one indeksowane.

To koniec części pierwszej o komponentach w LWUIT. W następnym wpisie z tej serii omówię CheckBox, ComboBox, TextArea oraz TabbedPane.

Zapraszam do komentowania !

_
Źródła obrazków oraz linki:
[1] https://lwuit.dev.java.net/
[2] http://lwuit.blogspot.com/

niedziela, 3 maja 2009

Pierwsze spotkanie sympatyków technik Agile w Poznaniu !

Na ostatnim spotkaniu Java User Group ogłoszono, że rozpoczyna się (oprócz Javowych) seria spotkań poświęcona technikom wytwarzania oprogramowania. Spotkania oprócz wystąpień mają w założeniu mieć także formę otwartej dyskusji. Pierwsze już 6 maja (czyli już w tę środę) w miejscu dobrze znanym czyli siedzibie Cognifide, przy ulicy Al. Wielkopolska 4 - godzina 18:00.

Będzie poświęcone sposobach prowadzenia projektu - metodyce Scrum. Prowadzącym spotkanie będzie pracownik firmy OpenX Andrzej Swędrzyński.
Oprócz wystąpienia spotkanie będzie także miało charakter organizacyjny - tematyka spotkań, terminy itp.

Zapraszam wszystkich !

ps. Zapraszam jeszcze na bloga AgileTuning.pl na którym można posłuchać bardzo ciekawych podcastów na ten temat.

piątek, 1 maja 2009

10 minut z biblioteką SAX - Simple API for XML

Przy okazji projektu z sieci komputerowych przyszło mi szukać biblioteki do parsowania XML, która będzie działać na wszystkich 3 platformach Java. Długo się nie zastanawiając wybrałem SAX. Miałem już dość męczenia się z jakimś kXML czy jakimś innym wytworem i wybrałem coś konkretnego. Jaki był tego koszt ? Moja aplikacja na komórkę będzie wymagać implementacji Java ME Web Service (JSR 172). No ale żałować nie będę, bo bez tego już chyba urządzeń mobilnych z Javą nie wprowadzają na rynek.

Ok, ale przejdźmy do zadania :) Trzeba parsować proste komunikaty XML o postaci:
<?xml version=”1.0” encoding=”utf-8”?>
<response value=”[odpowiedz]”>
<params>
<[klucz] value=”[wartość]”/>
<!-- inne parametry takiej postaci -->
</params>
</response>

Nie wygląda na trudne. Ale zobaczmy jak to się robi z użyciem SAX.
W pierwszej kolejności musimy utworzyć klasę handlera który będzie odpowiadać za obsługę poszczególnych elementów dokumentu XML. Klasa handlera musi dziedziczyć po klasie DefaultHandler, która umożliwia implementacje kilku bardzo przydatnych metod. Nasz handler będzie posiadać następujące:
- public void startElement(String uri, String localName, String qName, Attributes attribs) - metoda ta wywoływana jest gdy parser natrafi na znacznik otwierający
- public void endElement(String uri, String localName, String qName) - metoda ta zostanie wywołana po natrafieniu na znacznik zamykający
W tym miejscu dodam jeszcze notkę o metodzie characters chociaż jej nie będziemy używać jest dość istotna. Ma następującą sygnaturę:
- public void characters(char[] ch, int start, int lenght) - wywoływana jest gdy parser natrafi na tekst (tekstowa zawartość węzła)

A oto znaczenie poszczególnych parametrów:
uri - namespace uri
localName - lokalna nazwa znacznika (bez prefiksu)
qName - nazwa kwalifikowana znacznika (z prefiksem)
attribs - obiekt typu Attributes zawierający atrybuty danego znacznika
ch - tablica znaków
start - pozycja startowa w tablicy znaków
lenght - liczba znaków
To są absolutnie podstawowe metody które należy znać. Po więcej zapraszam do dokumentacji DeafultHadler.

Ok, to możemy przystąpić do implementacji klasy.
package com.blogspot.wookasz.saxexample;

import java.util.HashMap;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

class SAXMessageHandler extends DefaultHandler {
// flaga oznaczająca czy teraz wczytywane będą parametry
private boolean paramMode = false;
// parametry
private HashMap<String, String> params;
// wartość odpowiedzi w komunikacie
private String response;

public SAXMessageHandler() {
super();
this.params = new HashMap<String, String>();
}

@Override
public void startElement(String uri, String localName, String qName,
Attributes attribs) throws SAXException {
// jeśli natrafiono na węzeł z odpowiedzią
if (qName.equals("response") && !paramMode) {
response = attribs.getValue("value");
return;
}
// jeśli natrafiono na węzęł rozpoczynający parametry
if (qName.equals("params")) {
paramMode = true; // ustawiamy flagę że teraz będą parametry
return;
}

// jeśli ustawiona jest flaga parametrów
if (paramMode) {
// dodajemy parametr z wartością do mapy
params.put(qName, attribs.getValue("value"));
return;
}
}

@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// jeśli włączyony był tryb parametrów
// i nastrafiono na zamykający go znacznik
// to zmieniamy flegę
if (qName.equals("params")) {
paramMode = false;
}
}

public HashMap<String, String> getParams() {
return params;
}

public String getResponse() {
return response;
}
}

Komentarze w kodzie myślę wyjaśniają całkowicie działanie ;) Jakby co komentować!
Teraz czas na utworzenie parsera i zarejestrowanie handlera:)
To już tylko kilka linijek:
// utworzenie fabryki SAX
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
// utworzenie parsera
SAXParser parser = saxFactory.newSAXParser();
// utworzenie obiektu czytającego wiadomości XML
XMLReader reader = parser.getXMLReader();

// utworzenie naszego handlera
MessageSAXHandler xmlHandler = new SAXMessageHandler();
// oraz ustawienie go jako domyślnego dla obiektu czytającego
reader.setContentHandler(xmlHandler);

Teraz możemy poprzez metodę reader.parse(InputStram input) parsować wiadomości które do nas przychodzą. Należy zwrócić uwagę na to, że parametrem jest obiekt typu InputSource (dostępna jest jeszcze implementacja tej metody przyjmująca String - URI)! Jeśli mamy już całą wiadomość w pamięci to możemy to obejść w prosty sposób:
String xmlMsg = "[wiadomosc]";
InputStream streamXml = new ByteArrayInputStream(xmlMsg.getBytes()); // utworzenie strumienia bajtów z wiadomości
reader.parse(new InputSource(streamXml)); // parsowanie

Powinno działać :)

Jeszcze dodam uwagę co do implementacji tej biblioteki na platformie Java ME. JSR-172 trochę obcięło API i nie możemy utworzyć obiektu typu XMLReader. Na tej platformie parsowanie wygląda następująco:
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();

SAXMessageHandler xmlHandler = new SAXMessageHandler();

parser.parse(new InputSource(streamXml), xmlHandler);

Oraz w klasie SAXMessageHandler należy zmienić typ zmiennej params na Hashmap.
To rozwiązanie powinno także działać w Java SE oraz Java EE ;-)

Mam nadzieję, że ten krótki tutorial komuś pomoże rozpocząć pracę z biblioteką SAX. Po więcej informacji zapraszam na stronę www.saxproject.org.

czwartek, 19 marca 2009

Spotkanie Poznań JUG [26.03.2009] - Vine/Flex/BlazeDS

Po dość długiej przerwie w spotkaniach JUGowych na najbliższym będziemy mogli posłuchać o Vine, Flexie i BlazeDS z ust Piotra Dziubickiego. Oto krótki opis prelegenta nt wystąpienia:
"Tworzenie nowoczesnych serwisów internetowych z wykorzystaniem Vine/Flex/BlazeDs. Wybór odpowiedniej technologii często przesądza o późniejszym "być, albo nie być" projektu. Dlatego dyskusja skupiona będzie wokół często pojawiających się pytań:
- na co zwrócić uwagę i jak podejść do ewaluacji dostępnych rozwiązań?
- jak wygląda serwis internetowy wspomagający HPC wykorzystujący i łączący wiele standardów produkcyjnych.
"

Informacje techniczne:
26.03.2009, godzina 18:00
Siedziba Cognifide, Aleja Wielkopolska 4
Rejestracja

Zapraszam!!

niedziela, 15 marca 2009

Przykładowa aplikacja Java ME w NetBeans IDE z wtyczką Mobility

Dostałem już kilka maili od osób które zaczynają swoją przygodę z Java ME a mają problem ze zbudowaniem działającej prostej aplikacji. Dlatego chciałbym dziś zaprezentować mały tutorial jak stworzyć taką prostą aplikację za pomocą NetBeans IDE z wtyczką Mobility. Który wg mnie jest najlepszym środowiskiem do mobilnej Javy z jakim się spotkałem - a wiele już przeszło przez moje macki ^^
Zacznijmy od pobrania środowiska ze strony Download. Wybieramy wersje z pełnym wsparciem Java lub minimalna a po uruchomieniu w oknie Tools -> plugins pobieramy wtyczki:
  • Mobility

  • Visual Mobile Designer

  • Po instalacji potrzebny będzie restart IDE.
    Gdy już jesteśmy przygotowani możemy przystąpić do utworzenia nowego projeku Java ME.
    Wybieramy File -> New Project, na liście kategorii klikamy Java ME a następnie po prawej stronie Mobile Application.

    Na następnym ekranie wybieramy nazwę projektu (u mnie SampleJ2MEApp) oraz odznaczamy opcję Create Hello MIDlet (przecieć mamy go sami stworzyć ;)
    . Następne co musimy skonfigurować to emulator oraz platforma docelowa naszej aplikacji. Emulator powinniśmy mieć do wyboru jeden Sun Java(TM) Wireless Toolkit 2.5.2 for CLDC . Aby większość komórek mogła uruchomić nasz MIDlet wybieramy konfigurację CLDC 1.1 oraz profil MIDP 2.0.
    To wszystko. Klikamy finish.
    Ok, dodajemy nowy Midlet: File -> New File -> MIDP -> Visual MIDletI nadajemy mu nazwę np. SampleApp.
    Po wybraniu finish powinien wyświetlić się nam ekran Flow Design w którym to możemy przedstawić cały przepływ sterowania między ekranami aplikacji a wtyczka Mobility wygeneruje za nas kod Javy do tego (klepanie tego ręcznie jest strasznie denerwujące:/).

    Możemy przystąpić do tworzenia! Zróbmy aplikację która po uruchomieniu wyświetli nam ekran powitalny z jakimś obrazkiem a następnie przejdzie do ekranu z tekstem np "Hello, world!".
    Jedynym obiektem który istnieje na diagramie jest Mobile Device który reprezentuje urządzenie. Ma przypisane dwie akcje - started do którego przypisujemy ekran który ma się wyświetlić po uruchomieniu oraz Resumed do którego przypisujemy ekran który ma się pojawić po wznowieniu działania aplikacji.
    Do diagramu będziemy musieli dodać dwa nowe elementy z panelu bocznego (palety). Mianowicie Splash Screen oraz Form. Pierwszy z nich reprezentuje ekran powitalny i jest specjalna klasą dostępną tylko w NetBeans, więc jeśli będzie konieczność przeniesienia projektu np. do Eclipse potrzebne będzie dodanie bibliotek w classpath. Form jest standardową klasą MIDP i reprezentuje standardowy ekran na którym będziemy wyświetlać jakieś kontrolki.
    Teraz dodamy jeden przycisk akcji do Form który będzie odpowiadać za zamykanie aplikacji. Z kategorii Commands wybieramy Exit Command i 'przenosimy' go na form.
    Następnie dodajmy działania do tych akcji. Aby tego dokonać należy połączyć akcje z ekranem docelowym klikając na akcję źródłową i próbować 'przenieść' ją (pojawi się strzałka) na ekran docelowy. W taki sposób łączymy
    - Started z splashScreen (po uruchomieniu to on się właśnie pojawi)
    - DISMISS_COMMAND z form (po upływie 5s zostanie wyświetlony form)
    - exitCommand1 z Mobile Device (wyłączenie aplikacji).
    Ostatecznie diagram przepływu powinien wyglądać następująco:

    Teraz możemy się zabrać za wygląd ekranów.
    Na ekranie powitalnym możemy wyświetlić naszego wiernego Javowego towarzysza Dukea !

    Klikamy prawym przyciskiem na splashScreen następnie Properties i z listy Image wybieramy <New Image Resource>. Pojawi się nowy element na liście, wybieramy go i klkamy trzy kropki obok. Odnajdujemy obrazek z naszym Dukiem.

    I klikamy OK. W oknie properties możemy zmienić jeszcze wartość title na "Przykładowa aplikacja Java ME !".
    No to został nam jeszcze form. Klikamy na niego i na nad widokiem diagramy przepływu wybieramy Screen. Wyświetli się designer ekranu form. Klikamy prawym przyciskiem na ekranik i wybieramy New/Add -> String Item. Po dodaniu edytujemy pogrubiony tekst na "Hello, world!". Następnie nagłówek 'form' zmieniamy na "Przykładowa aplikacja Java ME !".

    I to wszystko! Możemy teraz uruchomić aplikację i przetestować jej działanie na emulatorze (prawy przycisk myszy na nazwę projektu na liście a następnie run) a później wgrać na telefon i przekonać się, że wszystko ok:)


    Za pomocą kilku kliknięć udało nam się stworzyć prostą aplikację bez pisania nawet linijki kodu. Oczywiście tworząc normalne aplikacje koniecznie będzie pokodowanie trochę ale takie operacje jak sterowanie przepływem ekranów czy prosty design okna może zostać bardzo łatwo zrealizowany za pomocą środowiska:)

    Zapraszam do komentowania!

    wtorek, 3 marca 2009

    Brak obsługi klawiszy multimedialnych w laptopie Lenovo SL500 na Ubuntu

    Dzisiaj troszkę z innej beczki. Jakiś czas temu stałem się posiadaczem laptopa Lenovo SL500. Chcąc w końcu nauczyć się obsługiwać linuxa zainstalowałem sobie Ubuntu 8.10 dla 64 bitowych procesorów. Zaskoczony byłem gdy po instalacji działał praktycznie cały sprzęt! Nie musiałem dogrywać żadnych dodatkowych sterowników:) No z jednym wyjątkiem... po jakimś czasie zauważyłem, że nie działają klawisze głośniej/ciszej i wyciszenia.
    Na polskich stronach nic nie znalazłem, na angielskich dotarłem do sterownika autorstwa Alexandre Rostovtsev. Opiszę jak go zainstalować, może komuś się kiedyś przyda ;)

    Pobieramy sterownik ze strony http://github.com/tetromino/lenovo-sl-laptop/tree/master
    Rozpakowujemy go w jakimś katalogu gdzie będzie mógł sobie bezpiecznie siedzieć i służyć.
    Wchodzimy do tego katalogu przez konsolę i wpisujemy:
    make
    insmod lenovo-sl-laptop.ko

    Ok, już powinno działać:)
    Jeszcze trzeba sprawić, by ten moduł uruchamiał się przy starcie systemu. Musimy napisać prosty skrypt w bashu:
    #!/bin/bash
    insmod sciezka_do_katalogu_z_modulem/lenovo-sl-laptop.ko

    I umieścić go w katalogu /etc/init.d/ pod dowolną nazwą z rozszerzeniem .sh. Następnie dodajemy mu uprawnienia na wykonywanie:
    chmod +x [nazwa skryptu]

    I dodajemy go by uruchamiał się przy starcie:
    update-rc.d nazwa_skryptu defaults


    No i problem rozwiązany.

    ps. Dziękuję za pomoc koledze Spawaczowi!
    UPDATE
    Na Ubuntu 9.04 też to rozwiązanie działa.

    UPDATE 2
    Trafiło do mnie podobne rozwiązanie którego jeszcze nie testowałem ale może ktoś będzie miał czas się pobawić.. chyba jest bardzie profesjonalne ^^ Link: http://gianlucamagalotti.wordpress.com/2009/02/16/lenovo-thinkpad-sl-series-hotkeys/

    poniedziałek, 2 marca 2009

    Tytuł inżyniera oraz DB2 Fundamentals Certificate zdobyte!

    Dłuuuga przerwa spowodowana dwoma sukcesami :)

    1. Tytuł inżyniera informatyki - po jakiś 17 latach nauki nareszcie są efekty! 16 lutego udało mi się uzyskać tytuł inżyniera na politechnice poznańskiej. Za prace pt. System informacji giełdowej na urządzenia mobilne otrzymałem ocenę 5, a na dyplom (obrona + średnia ze studiów) trafi ocena 4,5 :) Co prawda jakoś mój świat się nie zmienił po otrzymaniu tego tytułu ale miło, że coś dzięki temu zmieni się w CV (co prawda tylko 4 litery inż. ale zawsze;).

    2. DB2 Fundamentals Certificate (exam 730) - to świeże info, bo dziś w okolicach 16 moim oczom ukazał się taki oto ekran:

    Miło #2 :) Wynik jest dla mnie satysfakcjonujący, zważywszy na to, że pytania to prostych nie należały - spodziewałem się znacznie prostszych. Przygotowania do tego certyfikatu wiele mnie nauczyły, podczas projektowania bazy danych zwracam uwagę na znacznie więcej aspektów. Poza tym DB2 okazało się bardzo ciekawą relacyjną bazą danych. Nowy typ danych - XML, sposób jego przechowywania oraz operacje na nim są ciekawą innowacją. Postaram się coś o tym (i nie tylko) napisać na blogu;)
    Szkoda, że po otrzymaniu wyników nie mogłem przejrzeć gdzie popełniłem błędy :-/

    Jakie teraz mam plany (kolejność przypadkowa) ?;]
    - DB2 Administrator (exam 731)
    - Dokończyć szkolenie z Glassfish
    - SCJP - ale nad tym się jeszcze zastanawiam czy warto

    środa, 4 lutego 2009

    MIDP 3.0 - co nowego ?

    Zabrałem się za czytanie JSR-271 czyli specyfikacji Mobile Information Device Profile w wersji 3. Na tę chwilę przygotowana jest wersja public review. Z tego co gdzieś tam usłyszałem to pod koniec połowy tego roku ma zostać wydana wersja finalna specyfikacji (informacja niepewna!).
    Ok, ale jakie nowe możliwości będą miały nasze aplikacje na komóreczki ? Oto lista:
    - Zwiększone wymagania sprzętowe - po pierwsze ekran 176x220 pikseli, głębia kolorów 16bit. 1 MB pamięci na MIDP, 512 KB pamięci trwałej dla zapisu danych aplikacji oraz 1 MB pamięci dla Java runtime. To wszystko oczywiście poza tym co wymaga CLDC/CDC.
    - wprowadzenie LIBletów, komponentów które mogą być używane przez jeden lub więcej MIDletów. Zawierają one zbiór klas i nie mogą być uruchamiane.
    - W pliku JAR mogą być teraz przechowywane dane w formacie RMS. A nawet więcej! Można pobierać dane RMS z internetu! Szkoda, że nie było tego wcześniej, bo ułatwiłoby mi inżynierkę;) W deskryptorze MIDletu musi znajdować się wpis ze ścieżką gdzie dane się znajdują. Oto przykład:
    MIDlet-Data-Size: 3000
    MIDlet-Persistent-Data-URL-1: data.rms overwrite encryptLocally
    MIDlet-Persistent-Data-URL-2: http://vendor.com/gamedata/coolgame.rms

    - w deskryptorze muszą być teraz zapisane JSRy oraz LIDlety z jakich korzysta MIDlet, jeśli można pobrać je z sieci to dodatkowo URL. Przykład:
    Dependency-1: microedition.location; JCP; 1.0+; standard
    Dependency-2: MapsForAll; MapsGalore, Inc.; 1.1.2; liblet
    LIBlet-Dependency-JAD-URL-2: http://www.mapsgalore.com/liblets/mapsforall.jad

    - możliwość uruchamiania kilku MIDletów jednocześnie. Dotychczas aby uruchomić inną aplikację, konieczne było zamknięcie poprzedniej. Teraz będzie można minimalizować programy i uruchamiać kolejne.
    - spooooro zmian w bezpieczeństwie. Tutaj zapraszam do lektury specyfikacji, bo jest tego naprawdę dużo ;-)

    Są jeszcze sprawy nad którymi dyskusja nadal trwa:
    - czy Form może być przewijany horyzontalnie ?
    - obsługa wielu ekranów powitalnych (ang. splash screen)
    - wymagana obsługa SVG Tiny 1.1 i obsługa tego formatu przy tworzeniu komponentów interfejsu użytkownika
    - poprawki do komponentu TabbedPane oraz obiektu nasłuchującego TabListener
    - lokalizacja nazw MIDletów
    - zmiana domyślnego kodowania znaków na UTF-8
    - wprowadzanie adresu URL dla aktualizacji MIDletu

    Oczywiście zapewniona jest zgodność wstecz ;-)

    Osobiście podobają mi się zmiany. Niektóre ciekawe, inne bardzo ciekawe. Mam nadzieję, że SVG stanie się standardem oraz zostanie wprowadzony URL do aktualizacji. Znacznie by to zbliżyło MIDlety do aplikacji desktopowych. Jednak nadal mi brakuje większych (lub jakichkolwiek!) możliwości operowania telefonem - dostępu do książki telefonicznej, czy wiadomości tekstowych.
    W tym roku ma się także pojawić "wersja komórkowa" JavaFX (to może być hit!). Jestem ciekaw jak to zostanie zgrane z MIDP 3.0.

    Zapraszam do komentowania !

    wtorek, 3 lutego 2009

    Szkolenie z Glassfish - czas start !

    Dziś zakończyłem sesje na uczelni:) Ostatnia sesja na studiach pierwszego stopnia... ale jeszcze 3 będą na drugim stopniu więc nie jestem jakoś wielce wzruszony:P Do tego obrona pracy inżynierskiej 16 lutego. No ale wszystko ze spokojem, sporo czasu jeszcze jest na przygotowanie więc można zająć się czymś bardziej przyjemnym :)

    Zapisałem się właśnie na szkolenie z serwera aplikacyjnego Glassfish o którym pisałem wcześniej. Pierwszy punkt to: GlassFish(TM) Application Server: Introduction. Czeka mnie mały wstęp;) I dobrze, nigdy nie zgłębiałem wiedzy na temat serwerów aplikacji, więc czas się jakimś bardziej zainteresować. Jaką formę będzie miało to szkolenie to jeszcze nie wiem, nigdy w niczym takim nie brałem udziału, ale mam zamiar jak najwięcej z niego wynieść.
    Jest ambitny plan dzielenia się doświadczeniami na blogu, co by ktoś kto nie ma czasu na wzięcie udziału w szkoleniu mógł chociaż trochę liznąć z tematu (mam nadzieje, że nie będę przez to łamać czyiś praw autorskich) . Trzymajcie za mnie kciuki!

    wtorek, 27 stycznia 2009

    Dzisiejsze spotkanie Poznań JUG przesunięte !

    Niestety z powodu choroby prelegenta Jacka Pospychały dzisiejsze spotkanie o AspectJ musi zostać przesunięte.
    Znany już jest termin na który zostało przesunięte, jest to 10 lutego, godzina 18:00. Miejsce to samo co zwykle czyli siedziba Cognifide.
    Zapraszam na ten termin ! ;-)

    Proszę przekazać informację innym uczestnikom aby nie jechali na marne!

    poniedziałek, 26 stycznia 2009

    Walidacja wielu pól w jednym walidatorze w JSF

    Typowa sytuacja - mamy formularz zmiany hasła a w nim pola jak hasło i potwierdź hasło. Jak stworzyć do takich pół klasę walidującą skoro normalnie może ona operować na tylko jednym elemencie formularza ?
    To proste:) Musimy przekazać dodatkowo walidatorowi jako atrybut wartość z pierwszego pola.
    Posługując się powyższym przykładem mamy formularz:

    <h:form id="changepassform">
    <tr>
    <td>Nowe hasło:</td>
    <td>
    <h:inputSecret id="password" value="#{userRegistrationBean.password}"
    required="true" redisplay="false" />
    </td>
    </tr>
    <tr>
    <td>Powtórz:</td>
    <td>
    <h:inputSecret id="confirm" required="true" redisplay="false">
    <f:validator validatorId="passwordValidator" />
    <f:attribute name="passwordId" value="changepassform:password" />
    </h:inputSecret>
    </td>
    </tr>
    </h:form>
    W drugim polu formularza podajemy walidator którym jest passwordValidator - jego implementacja zajmiemy się za chwilę. Jako atrybut o nazwie passwordId podajemy z formularza changepassword (to nazwa aktualnego formularza) pole password, czyli to powyżej.
    Teraz czas na klasę walidującą.
    PasswordValidator.java
    package com.wookasz.blogspot.jsfmultivalidator;

    import javax.faces.application.FacesMessage;
    import javax.faces.component.UIComponent;
    import javax.faces.component.UIInput;
    import javax.faces.context.FacesContext;
    import javax.faces.validator.Validator;
    import javax.faces.validator.ValidatorException;

    public class PasswordValidator implements Validator {

    public void validate(FacesContext context, UIComponent component, Object value)
    throws ValidatorException {

    // pobranie atrybutu przekazanego w formularzu
    String passwordId = (String)component.getAttributes().get("passwordId");
    // odnalezienie odpowiedniego komponentu o tej nazwie
    UIInput passwordInput = (UIInput)context.getViewRoot().findComponent(passwordId);
    // pobranie wartości z tego komponentu
    String password = (String) passwordInput.getValue();
    String confirm = (String) value;

    // sprawdzanie poprawnosci i ew. zrzucenie wyjątku
    if (!password.equals(confirm)) {
    throw new ValidatorException(new FacesMessage("Hasła nie są identyczne"));
    }
    }
    }
    Mam nadzięję, że komentarze w kodzie wystarczą by wyjaśnić sprawę ;-)
    Pozostaje jeszcze rejestracja walidatora w faces-config.xml:
    <validator>
    <validator-id>passwordValidator</validator-id>
    <validator-class>
    com.wookasz.blogspot.jsfmultivalidator.PasswordValidator
    </validator-class>
    </validator>

    Wynik:

    sobota, 24 stycznia 2009

    NetBeans uznany produktem roku przez Developer.com !


    W głosowaniu przeprowadzonym przez serwis www.developer.com produktem roku 2008 został NetBeans! Wygrał w pięciu z dwunastu kategorii! Co więcej w tych kategoriach otrzymał znacząco większą liczbę głosów niż kolejne miejsca.



    Zwycięstwo odnotowano w następujących kategoriach:
    - Development Tool -> NetBeans Platform
    - Development Utilities -> NetBeans Profiler
    - Wireless/Mobile -> NetBeans Mobility Pack for Connected Device Configuration (CDC) 5.5
    - Java Tool -> NetBeans IDE
    - Open Source -> NetBeans

    Myślę, że to świetny wynik. W Polsce zauważam, że ze strony firm brakuje jakoś przekonania co do tego IDE. Większość korzysta z Eclipsa (co widać po publice na NetBeans day i Eclipse DemoCamp). Mam nadzieję, że takie nagrody zaczną przekonywać ludzi do korzystania z NetBeansa ;-)

    Pełną listę zwycięzców można przeczytać w artykule: Winners of the Developer.com Product of the Year 2009 Are Announced

    piątek, 23 stycznia 2009

    AspectJ na Poznań Java User Group [27.01.09]

    O programowaniu aspektowym w Javie za pomocą AspectJ na najbliższym spotkaniu Poznań Java User Group opowie nam Jacek Pospychała. Spotkanie odbędzie się 27 stycznia (wtorek) w siedzibie firmy Cognifide na ulicy Al. Wielkopolskie 4 - godzina 18:00.

    Tak jak ostatnim razem na spotkanie wymagana jest rejestracja [link].
    Ja niestety nie dotrę tym razem, ponieważ mam egzamin w tym czasie :-/ Ale wszystkich serdecznie ZAPRASZAM !

    Więcej szczegółów na grupie dyskusyjnej Poznań JUG.

    EDIT: A jednak udało mi się być zwolnionym z egzaminu to pojawię się na JUGu ^^

    czwartek, 22 stycznia 2009

    Placebo - Twenty Years, live at Rock Am Ring 06-04-06

    Nie wiem czy czytają mnie jacyś fani Placebo, ale uważam, że ten kawałek na tym koncercie zagrali zaj****** ! Końcówka wymiata !

    Szkoda tylko, że na YouTube jest taka słaba jakość dźwięku;/

    poniedziałek, 12 stycznia 2009

    Drobne poprawki w wyglądzie bloga

    Usiadłem dziś i poszerzyłem miejsce na posty na blogu. Wyleciały przez to zaokrąglenia ramek, ale mam nadzieje, że to mocno nie popsuło designu. Prosiłbym o komentarze co tu jeszcze psuje czytelność lub szpeci wygląd ;-) Nie mam niestety zdolności plastycznych żeby samemu to ocenić ;-/

    piątek, 9 stycznia 2009

    Kabaret Neonówka - niebo

    Dawno nic śmiesznego nie wrzucałem ;-)

    ^^

    Pierwszy MIDlet v2.0 -> LWUIT incoming!

    W czasach średniowiecznych opisałem tutaj jak napisać prosty midlet na urządzenie mobilne. Przedstawiłem to na standardowych kontrolkach z MIDP 2.0. Dziś chciałbym pokazać jak napisać pierwszy MIDLet ale już w dużo bardziej rozbudowanej i wszechstronnej bibliotece - Lightweight UI Toolkit (LWUIT).
    Co nam daje ta biblioteka ? Oto główne korzyści:
    - model MVC podobny do swingowego
    - aplikacja wygląda i działa identycznie na każdym urządzeniu
    - dużo większa liczba kontrolek
    - layouty jak w swingu (BoxLayout, GridLayout itd...)
    - Look and Feel oraz bardzo łatwa ich zmiana nawet podczas działania aplikacji
    - różnego rodzaju animacje i efekty przejścia
    - wszystkie komponenty UI mogą być w łatwy sposób modyfikowane (nie są oznaczone jako final - można dziedziczyć)
    - okienka modalne
    - obsługa ekranów dotykowych
    - internacjonalizacja
    - zmiana czcionek
    Hmmm... chciałem tylko kilka wymienić a tu się dość spora lista zrobiła ;P Jak wygląda LWUIT w akcji ? Możecie zobaczyć na filmiku poniżej:

    Już się wszystkim podoba ? Mnie bardzo! W połączeniu z licencją GPL jeszcze bardziej ^^
    No to czas coś napisać. Najpierw ściągnijmy bibliotekę : link. I tworzymy nowy projekt w ulubionym środowisku. Ja będę korzystać z NetBeans. Dodajemy klasę typu MIDlet do projektu, dodajemy bibliotekę LWUIT.jar oraz katalog resources do którego wrzucamy plik z motywem (link). Motyw pochodzi z przykładowego projektu LWUITDemo rozprowadzanego razem z biblioteką.
    Najpierw pokażę cały kod a później omówię najważniejsze elementy.
    LWUITDemo.java
    package com.blogspot.wookasz.lwuitdemo;

    import com.sun.lwuit.Command;
    import com.sun.lwuit.Display;
    import com.sun.lwuit.Form;
    import com.sun.lwuit.Label;
    import com.sun.lwuit.animations.CommonTransitions;
    import com.sun.lwuit.events.ActionEvent;
    import com.sun.lwuit.layouts.BorderLayout;
    import com.sun.lwuit.plaf.UIManager;
    import com.sun.lwuit.util.Resources;
    import javax.microedition.midlet.MIDlet;

    public class LWUITDemo extends MIDlet {
    private static final String THEME_FILE = "/businessTheme.res";
    public void startApp() {
    try {
    // inicjalizacja ekranu
    Display.init(this);

    // otwarcie i wczytanie motywu
    Resources r = Resources.open(THEME_FILE);
    UIManager.getInstance().setThemeProps(r.getTheme(r.getThemeResourceNames()[0]));

    // tworzenie formatek
    final Form firstForm = new Form("Pierwsza formatka");
    firstForm.setLayout(new BorderLayout());
    Label label1 = new Label("Hello world!");
    label1.getStyle().setBgTransparency(100);
    firstForm.addComponent(BorderLayout.CENTER, label1);

    final Form secondForm = new Form("Druga Formarka");
    secondForm.setLayout(new BorderLayout());
    Label label2 = new Label("and Hello LWUIT !!");
    label2.getStyle().setBgTransparency(100);
    secondForm.addComponent(BorderLayout.CENTER, label2);

    // przypisanie animacji przejść
    firstForm.setTransitionInAnimator(
    CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL,
    false, 1000));
    secondForm.setTransitionInAnimator(
    CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL,
    true, 1000));

    // dodawanie przycisków
    Command goBtn = new Command("Wciśnij mnie!", 1) {
    public void actionPerformed(ActionEvent evt) {
    secondForm.show();
    }
    };
    firstForm.addCommand(goBtn);

    Command backBtn = new Command("Powrót!", 1) {
    public void actionPerformed(ActionEvent evt) {
    firstForm.show();
    }
    };
    secondForm.addCommand(backBtn);
    // przycisk wyjścia
    Command exitCmd = new Command("Wyjście", 2) {
    public void actionPerformed(ActionEvent evt) {
    destroyApp(true);
    notifyDestroyed();
    }
    };
    firstForm.addCommand(exitCmd);
    secondForm.addCommand(exitCmd);

    // wyświetlenie formatki pierwszej
    firstForm.show();
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }

    public void pauseApp() {}
    public void destroyApp(boolean unconditional) {}
    }

    Pierwsza instrukcja inicjalizuje ekran, musi być ona wywołana przed wyświetleniem pierwszej formatki. Jako parametr należy podać obiekt dziedziczący po klasie MIDlet.
    Następne dwie linie
    Resources r = Resources.open(THEME_FILE);
    UIManager.getInstance().setThemeProps(r.getTheme(r.getThemeResourceNames()[0]));
    Załatwiają za nas całe wystylizowanie aplikacji:) Pierwszy wczytuje zbiór danych w którym znajduje się nasz motyw. W drugim go ustawiamy jako aktualny, szybkie i proste:) W jednym zbiorze może znajdować się wiele motywów dlatego odwołujemy się do tablicy w r.getThemeResourceNames()[0].
    final Form firstForm = new Form("Pierwsza formatka");
    firstForm.setLayout(new BorderLayout());
    Label label1 = new Label("Hello world!");
    label1.getStyle().setBgTransparency(100);
    firstForm.addComponent(BorderLayout.CENTER, label1);
    Tworzymy pierwszą formatkę. Parametrem jest napis jaki ma się pojawić na górnej belce, tak samo jako w standardowym formie. Następnie dla tej formatki ustawiamy layout typu BorderLayout, zgodnie z tym layoutem będą rozmieszczane wszystkie konponenty. W następnie dodajemy jeden komponent (napis) i dodajemy go na środek. Wcześniej jednak ustawiamy jego tło na całkowicie przezroczyste żebyśmy mogli widzieć tło aplikacji jakie jest zdefiniowane w motywie. W layoucie BorderLayout środkowa jego część zawsze zajmuje największą możliwą przestrzeń, gdybyśmy nie przypisali przezroczystego tła napisowi, nie zobaczylibyśmy tła aplikacji. Podobnie postępujemy z drugą formatką.
    firstForm.setTransitionInAnimator(
    CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL,
    false, 1000));
    Przypisujemy animacje dla sytuacji gdy formatka ma się pojawić. Trwać ona będzie 1000ms oraz będzie przesuwać się w stronę lewą. Podobnie tworzymy dla drugiej formatki, tylko animacja tam będzie przesuwać się w prawo.
    Command goBtn = new Command("Wciśnij mnie!", 1) {
    public void actionPerformed(ActionEvent evt) {
    secondForm.show();
    }
    };
    firstForm.addCommand(goBtn);
    Podczas tworzenia przycisków możemy od razu zdefiniować jaka akcja ma się wykonać podczas jego przyciśnięcia. Robimy to tworząc metodę actionPerformed dla tego przycisku. Co prawda nie jest to za bardzo zgodne z modelem MVC ale dla drobnych akcji takie podejście chyba nie jest aż tak złe. Akcja która zdefiowaliśmy wyświetla drugą formatkę. Oczywiście pojawia się ona z efektem przejścia który przypisaliśmy jej wcześniej.
    Dalej w kodzie przypisujemy kolejne przyciski o dość zrozumiałym działaniu, by na końcu wyświetlić pierwszą formatkę metodą show().
    Uruchamiamy!

    U mnie działa:) Zachęcam do przetestowania na telefonie, nie powinno być problemów raczej.
    Należy pamiętać, że jeśli użyjemy efektu przejścia jakim jest np. Transition3D.createRotation(int, bool) to jest wymagane od urządzenia obsługa 3D (pakiet javax.microedition.m3g).

    To by było na tyle mojego bardzo krótkiego wstępu do Lightweight UI Toolkit. Zachęcam do zapoznania się z API - bardzo proste i rozbudowane zarazem. Ja z pewnością napisze jeszcze trochę tutaj na ten temat. Pracuję już z LWUIT kilka miesięcy i trochę ciekawostek się nazbierało do opisania ^^

    Zapraszam do komentowania!

    Linki:
    Projekt NetBeans przykładu z wpisu: download
    Strona domowa - https://lwuit.dev.java.net/
    Oficjalne forum - http://forums.java.net/jive/forum.jspa?forumID=139
    Blog - http://lwuit.blogspot.com/

    wtorek, 6 stycznia 2009

    Darmowe szkolenia z Glassfish!

    Sun robi niespodzianki noworoczne i oferuje nam darmowe szkolenie (trial) z zakresu serwera aplikacji GlassFish. Żeby z niego skorzystać należy się zarejestrować by po tym otrzymać dostęp na 60 dni do serwisu szkoleniowego. Zakres programu jest dość wąski wg mnie bo obejmuje tylko informacje wstępne na temat serwera oraz różne aspekty tworzenia usług sieciowych: projektowanie, bezpieczeństwo, QoS, integracja z .NET, transakcyjność, praca z usługami. Jak to wygląda od środka jeszcze nie wiem, bo zarejestruje się gdzieś pod koniec stycznia dopiero gdy znajdę więcej czasu. Ale wszystkich zachęcam do skorzystania, zawsze można się czegoś nauczyć nowego ^^
    Co ciekawe rejestracja daje nam także zniżki np na certyfikaty SCWCD czy SCBCD.
    Z tego co wyczytałem to promocja kończy się 20 marca.
    Link do rejestracji (i większej ilości informacji): www.sun.com/training/glassfish_login.html


    EDIT:
    To jednak nie na certyfikaty są zniżki tylko na pakiety przygotowujące go egzaminu ! Przepraszam za pomyłkę ;-)

    czwartek, 1 stycznia 2009

    Dostęp do kontekstu utrwalania w niezarządzanych obiektach JSF

    Tworząc projekt z użyciem JSF i Spring Security musiałem w jednej z metod uwierzytelniających pobrać dane o użytkowniku z bazy danych. Problemem było to, że obiekt ten nie był zarządzanym przez kontener aplikacji więc nie mogłem wstrzyknąć sobie do niego referencji do kontekstu utrwalania. Samemu tworząc obiekt jak w przypadku platformy Java SE uzyskiwałem wyjątek braku informacji o jednostce utrwalania. Ostatecznie z rozwiązaniem problemu przyszła mi z pomocą grupa dyskusyjna pl.comp.lang.java a dokładniej użytkownik Jarek któremu bardzo dziękuje ^^

    Ok, żeby dostać się do kontekstu utrwalania należy wzbogacić nasz deskryptor wdrożenia web.xml o następujący wpis:
    <persistence-context-ref>
    <persistence-context-ref-name>
    persistence/[nazwa jednostki utrwalania z persistence.xml]
    </persistence-context-ref-name>
    <persistence-unit-name>
    [nazwa jednostki utrwalania z persistence.xml]
    </persistence-unit-name>
    </persistence-context-ref>
    Miedzy pierwszą parą znaczników wpisujemy gdzie będziemy mogli znaleźć naszą jednostkę utrwalania w JNDI, a w drugiej nazwę tej jednostki z pliku persistence.xml. Bardzo proste:) Należy tylko pamiętać aby wcześniej wszystko skonfigurować związanego z utrwalaniem.
    Teraz gdy to już mamy możemy dobrać się do tego czego szukamy:
    InitialContext ictx = new InitialContext();
    Context envCtx = (Context) ictx.lookup("java:comp/env");
    entityManager = (EntityManager) envCtx.lookup("persistence/[nazwa]");

    Działa :)