blog.grejpfrut.org

VisualVM Java IDE wars plugin

without comments

Pobierz :
- NetBeans IDE 6.1 ub 6.5
- Visual VM .

Potrzebny będzie również kod źródłowy gry Shootout autorstwa Dawida Weissa, orginalna wersja nie pozwalała na osadzenie gry w kontenerach Swingowych, musiałem więc wprowadzić kilka poprawek :) . Kod źródłowy dostępny jest tutaj. Aby zbudować jar’a wystarczy rozpakować archiwum i w katalogu shootout wydać polecenie: ant jar-netbeans w shootout/build znajdziecie finalnego jar’a.

Po zainstalowaniu Visual VM (można też użyć tego który znajduje się w Waszym JDK) i uruchomieniu NetBeans IDE możemy przystąpić do pracy. W niektórych miejscach korzystałem z wizardów NetBeansowych więc samo spojrzenie w kod tych próbek może nie dać wam pełnego obrazu jak najszybciej dojść do finalnego efektu

Visual VM to aplikacja stworzona w oparciu o NetBeans Paltform, przeglądając zawartość folderu aplikacji możecie natknąć się na charakterystyczne dla aplikacji NBP nazwy plików i katalogów. Zanim zaczniemy właściwą pracę musimy zarejestrować instację platformy NB, która znajduje się w Visual VM. Oprócz standardowych elementów NB są tam również moduły specyficzne dla Visual VM jak np. VisualVM-Application czy VisualVM-Core.

Aby zarejestrować instancje platformy należy wybrać z menu Tools>NetBeans Plaform i dodać nową platformę (przycisk Add Platform) – wskazujemy na katalog w którym został zainstalowany VisualVM

Rejestracja platformy umożliwi nam nie tylko zapewnienie pełnej zgodności z platformą na której uruchamiany będzie plugin, ale pozwoli również na debugowanie i szybkie uruchamianie tworzonego przez nas rozszerzenia w docelowym środowisku.

Tworzymy nowy projekt wybierając File>New Project>NetBeans Modules i z listy o prawej stronie wybrać Module Suite klikamy Next.

W następnym kroku kreatora wpisujemy nazwę projektu i wybieramy platformę w oparciu o którą będziemy rozwijali nasz zestaw modułów. W poprzednich krokach zarejestrowaliśmy instancję należącą do Visual VM i to właśnie ją wybieramy z listy rozwijanej.

Module Suite jest kontenerem dla modułów które są z jakichś względów są ze sobą powiązane, w wyniku naszych działań powstaną dwa moduły: właściwa wtyczka do VisualVM i drugi będący owijką na shootout.jar. Dlaczego tak? Scenariusz jest bardzo prosty wyobraźcie sobie, że została wydana nowa wersja Shooout i chcielibyśmy mieć ją w naszej wtyczce. Po dokonaniu niezbędnych zmian przez nas, użytkownicy wtyczki musieliby ściągać nie tylko nową wersję gry, ale i samą wtyczkę, którą już przecież mają. Aby więc w pełni wykorzystać zalety modułowości każda biblioteka wykorzystywana przez naszą wtyczkę powinna zostać opakowana w pewne dodatkowe informacje, które pozwolą instancji NetBeans Platform na aktualizację tylko tej konkretnej biblioteki.

Czas więc stworzyć Library Wrapper Module dla Shootout.jar. Klikamy File>New Project>NetBeans Module>Library Wrapper Module w pierwszym kroku kreatora trzeba podać ścieżkę do pliku jar, który opakowujemy i do pliku z licencją na której biblioteka jest/ma być udostępniania. W ostatnim kroku kreatora pojawia się pytanie o codebase, wpisujemy com.dawidweiss.shootout.

O czym jeszcze warto wspomnieć, pierwotnie Shootout.jar miał w manifeście ustawiony parameter Main-Class, który wskazywał na klasę posiadającą metodę main w której uruchamiana była gra. Powodowało to, że wtyczka po umieszczeniu w VisualVM nie działała. Wywalenie tego atrybutu z manifestu załatwiło sprawę. Niestety nie znam się na wnętrznościach NetBeans Platform więc nie jestem w stanie tego sobie wytłumaczyć bardziej racjonalnie.

Zależności w formie LWM mogą być deklarowane przez wszystkie moduły wchodzące w skład nadrzędnego Module Suite.

Mamy już jeden moduł, teraz czas przejść do najważniejszej części tego artykułu – tworzenia właściwej wtyczki do VisualVM.

Tworzymy nowy projekt File>New Project>NetBeans Module>Module, moduł powinien zostać dodany do stworzonego wcześniej Module Suite. W kolejnym kroku wpisujemy codebase : org.grejpfrut.vvm, w NetBeans 6.5 wpisanie poprawnego codebase uzupełnia również pozostałe pola formularza.

Kolejny krok to dodanie zależności, w oknie Projects klikamy prawym na węzeł reprezentujący moduł i wybieramy Properties. Następnie zakładka Libraries musimy mieć zadeklarowane następujące zależności: Module System API, shootout, Utilities API, VisualVM-Application i VisualVM-Core.

W oknie Projects klikamy prawym przyciskiem myszy na węzeł reprezentujący stworzony przed chwilą moduł i wybieramy New>Module Installer. Stworzona klasa Installer i jej dwie metody restored i uninstalled umożliwiają nam wpięcie się w cykl życia tworzonej właśnie wtyczki. Kod z metody restored jest wykonywany w chwili załadowania modułu, jest to najwłaściwsze miejsce aby zarejestrować klasy implementujące rozszerzenia. Natomiast metoda uninstalled jest wywoływana w momentcie gdy moduł jest usuwany ze środowiska lub gdy jest ono wyłączane.

public class Installer extends ModuleInstall {
    @Override
    public void restored() {
        FirstExamplePluginViewProvider.initialize();
    }
    @Override
    public void uninstalled() {
        FirstExamplePluginViewProvider.unregister();
    }
}

W mojej prezentacji z NetBeans Day możecie znaleźć krótkie omówienie tego co można rozszerzyć w VisualVM, więcej o tym piszę Geertjan w
dokumentacji VisualVM i na swoim blogu. FirstExamplePlugin będzie tworzył dodatkową zakładką, którą użytkownicy będą mogli zobaczyć po połączeniu się do jakiegoś JVMa. W zakładce tej będą się działy rzeczy różne :D .

Należy teraz stworzyć klasę FirstExamplePluginViewProvider, jak sugeruje nazwa, klasa ta będzie odpowiedzialna za “produkcję” instancji klasy FirstExamplePluginView.

class FirstExamplePluginViewProvider extends DataSourceViewProvider {
    //prosty singleton
    private static DataSourceViewProvider instance = new FirstExamplePluginViewProvider();

    static void initialize() {
        //rejestrujemy instancję FirstExamplePluginViewProvider w zarządcy widoków
        DataSourceViewsManager.sharedInstance().addViewProvider(instance, Application.class);
    }

    static void unregister() {
        //wyrejestrowujemy instancję FirstExamplePluginViewProvider w zarządcy widoków
	//metoda jest wywoływana podczas odinstalowywania modułu i wyłączania środowiska
        DataSourceViewsManager.sharedInstance().removeViewProvider(instance);
    }

    @Override
    protected DataSourceView createView(Application app) {
        //tworzy instancję widoku
        return new FirstExamplePluginView(app);
    }
}

Klasa ta to prosty singleton, który w czasie inicjalizacji modułu (initialize) dodaje do DataSourceViewManager’a swoją instancję. Najważniejszą metodą w tej klasie jest createView, która to tworzy naszą zakładkę.

Kopiując poniższy kod należy pamiętać o wskazaniu poprawnej ścieżki do ikonki wyświetlanej w etykiecie zakładki:
org/grejpfrut/vvmnbd/example/grejpfrut.png – szczegóły będą widoczne w źródłach.

public class FirstExamplePluginView extends DataSourceView {

    private DataViewComponent dvc;

    //sciezka do ikony, ktora bedzie wyswietlana w zakładce zakładki
    public final static String IMAGE_PATH = "org/grejpfrut/vvmnbd/example/grejpfrut.png";

    public FirstExamplePluginView(Application app) {
        //tytuł zakładki i ikona
        super(app, "Java IDE wars plugin", new ImageIcon(Utilities.loadImage(IMAGE_PATH)).getImage(), 3, true);
    }

    @Override
    protected DataViewComponent createComponent() {
    	//tworzenie elementów widoku
        JEditorPane generalDataArea = new JEditorPane();
        generalDataArea.setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8));

        JPanel details1Panel = new JPanel(new BorderLayout());
        ShootoutBoard board = new ShootoutBoard(new ShootoutUtilities().getEnemyFactory(), details1Panel);
        details1Panel.add(board, BorderLayout.CENTER);
        details1Panel.setBackground(Color.GRAY);
        details1Panel.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));

	//osadzanie stworzonych kontrolek w kontenerze VisualVM
        DataViewComponent.MasterView masterView = new DataViewComponent.MasterView("Java IDE wars plugin", null, generalDataArea);
	//konfiguracja widoku
        DataViewComponent.MasterViewConfiguration masterViewConfiguration = new DataViewComponent.MasterViewConfiguration(false);

	//tworzymy właściwy komponent, który bedzie wyswietlany w VVM
        dvc = new DataViewComponent(masterView, masterViewConfiguration);

	//tworzymy panel z planszą gry
        DataViewComponent.DetailsView details = new DataViewComponent.DetailsView("", "Detale tego okienka", 10, details1Panel, null);
	//umieszczamy go w odpowiednim miejscu
        dvc.addDetailsView(details, DataViewComponent.TOP_LEFT);
	//gra ma być domyślnie ukryta
        dvc.hideDetailsArea(DataViewComponent.TOP_LEFT);
        return dvc;
    }
}

Po uzupełnieniu importów, możemy uruchomić nasz plugin aby tego dokonać należy w oknie Projects kliknąć prawym na węzeł reprezentujący nasz Module Suite i wybrać “Run” lub “Debug”. NetBeans uruchomi teraz nasz plugin w platformie która wybraliśmy dla naszych modułów. Teraz klikamy w dowolny proces JVM, który jest wyświetlany na drzewku Applications i powinna się naszym oczom ukazać zakładka z grejpfrutem, po kliknięciu “Details” powinna już rozpocząć się strzelanina :) .

java-ide-warss

Kompletne źródła już wkrótce, po tym jak skończe drugą cześć “Własny ApplicationType”.

Wszystko oparte na serii artykułów Getting Started Extending VisualVM autorstwa Geertjana Wielengi.

Written by admin

Grudzień 3rd, 2008 at 6:49 pm

Posted in java, po polsku

Tagged with , ,

Leave a Reply