Wprowadzenie
Od wersji 1.5 możliwe jest dodawanie nowych funkcji do Sweet Home 3D za pomocą plików wtyczek umieszczonych w folderze wtyczek. Pozwala to programistom Java na tworzenie i rozpowszechnianie nowych funkcji dla Sweet Home 3D bez modyfikowania plików źródłowych bieżącej wersji (co jest dobre dla zgodności wstecznej) i bez dostarczania pełnej wersji programu (co jest korzystne ze względu na rozmiar).
Ten dokument opisuje narzędzia wymagane do tworzenia wtyczek, następnie pokazuje jak zaprogramować wtyczkę, która oblicza maksymalną objętość ruchomych mebli dodanych do domu, a na końcu podaje dodatkowe informacje, które pomogą Ci pójść dalej.
Instalacja narzędzi programistycznych
Chociaż Sweet Home 3D jest przeznaczony dla ogólnego odbiorcy, tworzenie wtyczek wymaga specjalnych umiejętności i powinieneś wiedzieć, jak programować w Java używając IDE, zanim pójdziesz dalej. Ten przewodnik pokazuje, jak zbudować wtyczkę w Eclipse, ale możesz użyć dowolnego IDE według własnego wyboru lub nie używać IDE wcale.
Pobierz i zainstaluj Eclipse
Najpierw pobierz Eclipse z https://www.eclipse.org/. Wersja nazwana Eclipse IDE for Java Developers jest wystarczająca do tworzenia wtyczek, ale możesz pobrać dowolną wersję do programowania w Java.
Po pobraniu, instalacja Eclipse jest bardzo prosta: wystarczy rozpakować archiwum, otworzyć folder eclipse i w zależności od systemu uruchomić plik o nazwie eclipse.exe (w Windows), eclipse.app (w Mac OS X) lub eclipse (w Linux).
Przy pierwszym uruchomieniu Eclipse poprosi Cię o wybranie folderu workspace, w którym będą przechowywane projekty wtyczek.
Po zakończeniu wybierz File > New > Project z menu, aby utworzyć nowy projekt, wybierz Java > Java project w kreatorze New project, który zostanie wyświetlony, wpisz VolumePlugin jako nazwę projektu i kliknij przycisk Finish. Na koniec zamknij zakładkę Welcome, aby zobaczyć swój workspace jak pokazano na rysunku 1.

Pobierz i zainstaluj bibliotekę Sweet Home 3D
Tworzenie wtyczki opiera się na niektórych klasach Sweet Home 3D, które Eclipse musi znać, aby móc zbudować Twój projekt. Najłatwiejszym sposobem dodania klas Sweet Home 3D do Eclipse jest pobranie wersji JAR Sweet Home 3D dostępnej pod adresem

do Build Path
Programowanie wtyczki
Teraz, gdy zainstalowałeś wymagane narzędzia, zobaczmy jak możesz zaprogramować swoją pierwszą wtyczkę dla Sweet Home 3D.
Tworzenie klasy wtyczki
Najpierw utwórz nową podklasę com.eteks.sweethome3d.plugin.Plugin wybierając z menu Eclipse pozycję File > New > Class.

W oknie dialogowym New Java Class wpisz VolumePlugin jako nazwę klasy, wprowadź pakiet (tutaj wybrany pakiet to com.eteks.test) i wybierz com.eteks.sweethome3d.plugin.Plugin jako klasę nadrzędną dla VolumePlugin. Po zakończeniu kliknij Finish. Eclipse utworzy plik nowej klasy z następującą zawartością:
package com.eteks.test;
import com.eteks.sweethome3d.plugin.Plugin;
import com.eteks.sweethome3d.plugin.PluginAction;
public class VolumePlugin extends Plugin {
@Override
public PluginAction[] getActions() {
// TODO Auto-generated method stub
return null;
}
}
Jak możesz się domyślić z komentarza TODO, musisz teraz zmienić implementację metody getActions, aby zwracała akcję wtyczki zdolną do obliczenia objętości ruchomych mebli. Zastąp return null; następującą instrukcją:
return new PluginAction [] {new VolumeAction()};
i wybierz Edition > Quick Fix z menu Eclipse, aby utworzyć brakującą klasę VolumeAction, jak pokazano na rysunku 4.

W oknie dialogowym New Java Class, które się pojawi, zaznacz pole wyboru Enclosing type, aby utworzyć klasę wewnętrzną VolumePlugin i kliknij Finish. Spowoduje to utworzenie klasy VolumeAction, która dziedziczy po klasie com.eteks.sweethome3d.plugin.PluginAction i zawiera pustą metodę execute:
public class VolumeAction extends PluginAction {
@Override
public void execute() {
// TODO Auto-generated method stub
}
}
Ta metoda zostanie wywołana przez Sweet Home 3D, gdy użytkownik uruchomi akcję wtyczki; to właśnie tutaj musisz zaimplementować sposób obliczania objętości mebli i wyświetlania jej:
public class VolumeAction extends PluginAction {
@Override
public void execute() {
float volumeInCm3 = 0;
// Oblicz sumę objętości prostopadłościanu ograniczającego
// każdy ruchomy mebel w domu
for (PieceOfFurniture piece : getHome(). getFurniture()) {
if (piece. isMovable()) {
volumeInCm3 += piece. getWidth()
* piece. getDepth()
* piece. getHeight();
}
}
// Wyświetl wynik w oknie komunikatu (³ to 3 w indeksie górnym)
String message = String. format(
"Maksymalna objętość ruchomych mebli w domu wynosi %.2f m³.",
volumeInCm3 / 1000000);
JOptionPane. showMessageDialog(null, message);
}
}
Teraz, gdy określiłeś, co ma robić wtyczka, musisz opisać, jak użytkownik będzie uruchamiał tę nową akcję. Masz do wyboru dodanie nowej pozycji menu do menu i/lub nowego przycisku do paska narzędzi. Wyboru dokonuje się ustawiając odpowiednie właściwości akcji wtyczki przy jej tworzeniu. Na przykład, jeśli chcesz, aby użytkownicy uruchamiali akcję obliczania objętości za pomocą pozycji menu Oblicz objętość znajdującej się w menu Narzędzia, dodasz następujący konstruktor do klasy VolumeAction:
public VolumeAction() {
putPropertyValue(Property.NAME, "Oblicz objętość");
putPropertyValue(Property.MENU, "Narzędzia");
// Domyślnie włącza akcję
setEnabled(true);
}
Klasa wtyczki VolumePlugin jest teraz zaprogramowana i prawie gotowa do działania jako wtyczka w Sweet Home 3D. Pozostały dwie ostatnie rzeczy do zrobienia:
- utworzenie pliku opisu ApplicationPlugin.properties
- umieszczenie plików razem w pliku JAR.
Tworzenie pliku opisu wtyczki
Plik ApplicationPlugin.properties opisuje nazwę wtyczki, jej klasę, minimalne wersje Sweet Home 3D i Java, pod którymi jest obsługiwana, oraz kwestie prawne. Wybierz File > New > File z menu Eclipse, wprowadź nazwę pliku ApplicationPlugin.properties i kliknij Finish, jak pokazano na rysunku 5.

Następnie wprowadź następujący opis w nowym pliku i zapisz go:
name=Objętość ruchomych mebli
class=com.eteks.test.VolumePlugin
description=Oblicza objętość ruchomych mebli w domu
version=1.0
license=GNU GPL
provider=(C) Prawa autorskie 2024 Space Mushrooms
applicationMinimumVersion=1.5
javaMinimumVersion=1.5
Tworzenie pliku JAR wtyczki
Plik JAR wtyczki zawiera pliki class utworzone z kompilacji pliku VolumePlugin.java, oraz plik ApplicationPlugin.properties. Ponieważ Eclipse kompiluje plik Java zaraz po jego zapisaniu, wystarczy wybrać File > Export… z menu i wybrać Java > JAR file w oknie dialogowym Export, które zostanie wyświetlone. W kreatorze Jar Export, który pojawi się jak pokazano na rysunku 6, zaznacz pole wyboru projektu i wprowadź ścieżkę do pliku JAR umieszczonego w folderze wtyczek Sweet Home 3D. Odpowiedni folder zależy od Twojego systemu w następujący sposób:
- w Windows Vista / 7 / 8 / 10 / 11, ten folder to C:UsersużytkownikAppDataRoamingeTeksSweet Home 3Dplugins,
- w Windows XP i poprzednich wersjach Windows, ten folder to C:Documents and SettingsużytkownikApplication DataeTeksSweet Home 3Dplugins,
- w macOS, to podfolder Library/Application Support/eTeks/Sweet Home 3D/plugins w Twoim folderze użytkownika,
- w Linux i innych systemach Unix, to podfolder .eteks/sweethome3d/plugins w Twoim folderze użytkownika.

Testowanie wtyczki
Wtyczka, którą stworzyłeś, będzie działać w Sweet Home 3D, zarówno w wersji Java Web Start, wersji instalacyjnej, jak i w SweetHome3D-7.5.jar, który pobrałeś wcześniej. Ponieważ ten ostatni jest wykonywalnym plikiem JAR, możesz go uruchomić przez podwójne kliknięcie lub za pomocą następującego polecenia:
Wtyczka, którą stworzyłeś, będzie działać w Sweet Home 3D, zarówno w wersji Java Web Start, wersji instalacyjnej, jak i w SweetHome3D-7.5.jar, który pobrałeś wcześniej. Ponieważ ten ostatni jest wykonywalnym plikiem JAR, możesz go uruchomić przez podwójne kliknięcie lub za pomocą następującego polecenia:
java -jar /ścieżka/do/SweetHome3D-7.5.jar
Dopóki testujesz, prawdopodobnie będziesz wolał uruchamiać Sweet Home 3D za pomocą tego polecenia, aby móc odczytać w konsoli ślad stosu wyjątków rzucanych podczas wykonywania Twojej wtyczki.
Po uruchomieniu Sweet Home 3D zobaczysz nowe menu i jego pozycję, jak pokazano na rysunku 7:

Jeśli wybierzesz nową pozycję menu dla przykładowego domu utworzonego w przewodniku użytkownika, otrzymasz następujący wynik:

Debugowanie wtyczki
Jeśli potrzebujesz debugować swoją wtyczkę z Eclipse, utwórz konfigurację debugowania wykonując następujące kroki:
- Wybierz Run > Debug Configurations… z menu, wybierz pozycję Java Application z listy dostępnych konfiguracji w oknie dialogowym Debug configurations, kliknij przycisk New w lewym górnym rogu i wprowadź nazwę dla konfiguracji.
- Kliknij przycisk Search… po prawej stronie pola tekstowego Main class i kliknij dwukrotnie klasę SweetHome3DBootstrap
spośród proponowanych klas.

- Kliknij na zakładkę Classpath, wybierz podelement VolumePlugin (domyślna ścieżka klas) elementu User Entries na liście Classpath i kliknij przycisk Usuń.
- Kliknij na element User Entries na liście Classpath, kliknij przycisk Dodaj pliki JAR…, wybierz element SweetHome3D-7.5.jar i potwierdź swój wybór.

- Wybierz zakładkę Źródło, kliknij przycisk Dodaj…, kliknij dwukrotnie na element Projekt Java w oknie dialogowym Dodaj źródło, wybierz element VolumePlugin w wyskakującym okienku Wybór projektu i potwierdź swój wybór.

- Na koniec kliknij przycisk Debuguj, aby uruchomić Sweet Home 3D w trybie debugowania. Gdy program zostanie uruchomiony, otwórz plik VolumePlugin.java, ustaw punkt przerwania w metodzie execute i wybierz Narzędzia > Oblicz objętość z menu Sweet Home 3D. Eclipse zatrzyma się na wybranym punkcie przerwania, umożliwiając wykonanie programu krok po kroku i sprawdzenie wartości zmiennych.


Za każdym razem, gdy modyfikujesz kod źródłowy swojej wtyczki, nie zapomnij wygenerować pliku JAR wtyczki przed uruchomieniem utworzonej konfiguracji debugowania. Aby przyspieszyć proces eksportu JAR w Eclipse, przejdź do drugiego kroku kreatora eksportu JAR i wybierz opcję Zapisz opis tego pliku JAR w przestrzeni roboczej. Spowoduje to dodanie nowego elementu w projekcie z kontekstowym elementem menu Utwórz JAR.
Wdrażanie wtyczki
Po przygotowaniu, twoja wtyczka może być wdrożona na komputerach innych użytkowników Sweet Home 3D poprzez proste skopiowanie jej do ich folderu wtyczek. Od wersji 1.6, plik wtyczki może być również zainstalowany w folderze wtyczek Sweet Home 3D poprzez dwukrotne kliknięcie na nim, jeśli jego rozszerzenie to SH3P (wystarczy zmienić rozszerzenie pliku z .zip na .sh3p). Jeśli dwukrotne kliknięcie na pliku .sh3p nie uruchamia Sweet Home 3D (co jest najbardziej prawdopodobne w systemie Linux), możesz również zainstalować wtyczkę za pomocą następującego polecenia w oknie Terminala (gdzie SweetHome3D to nazwa pliku wykonywalnego dostarczonego z instalatorami Sweet Home 3D):
/ścieżka/do/SweetHome3D /ścieżka/do/wtyczka.sh3p
Aby przestać używać wtyczki, usuń jej plik z folderu wtyczek i uruchom ponownie Sweet Home 3D.

Jeśli chcesz, aby twoja wtyczka mogła działać ze wszystkimi instalatorami Sweet Home 3D dostępnymi na tej stronie internetowej, zadbaj o to, aby była zgodna z Java 5, wybierając 1.5 w polu Poziom zgodności kompilatora dostępnym w sekcji Kompilator Java okna dialogowego wyświetlanego po wybraniu opcji menu Projekt > Właściwości w Eclipse.
Jeśli używasz wersji kompilatora Java, w której zgodność z Java 1.5 nie jest już dostępna, spróbuj celować co najmniej w Java 1.8, która jest nadal używana w najnowszych wersjach Sweet Home 3D i ustaw javaMinimumVersion w pliku ApplicationPlugin.properties twojej wtyczki odpowiednio.
Idąc dalej
Programowanie pierwszej wtyczki pokazało ci ogólny obraz. Oto dodatkowe informacje, które pomogą ci pójść dalej.
API Sweet Home 3D – Javadoc
Najbardziej przydatną dokumentacją do tworzenia nowej wtyczki jest API Sweet Home 3D (Application Programming Interface), wygenerowane za pomocą narzędzia javadoc.
Używaj w swojej wtyczce tylko klas z pakietów com.eteks.sweethome3d.plugin, com.eteks.sweethome3d.model, com.eteks.sweethome3d.tools i com.eteks.sweethome3d.viewcontroller, jeśli chcesz, aby była zgodna z przyszłymi wersjami Sweet Home 3D. To będzie w zupełności wystarczające do zaprogramowania dowolnej wtyczki, która działa na danych domu dostępnych w Sweet Home 3D.
Pakiety odpowiadające innym warstwom programu są zawarte w Javadoc tylko w celach informacyjnych. Nie polegaj na ich API, ponieważ może ono ulec zmianie w przyszłości bez gwarancji zgodności wstecznej (w każdym razie nie zobaczysz żadnego odniesienia do klasy z pakietów com.eteks.sweethome3d.swing, com.eteks.sweethome3d.j3d, com.eteks.sweethome3d.io lub com.eteks.sweethome3d w wyżej wymienionych pakietach).
Architektura klas modelu
Sweet Home 3D opiera się na architekturze MVC (Model-Widok-Kontroler), więc zrozumienie, jak zorganizowana jest jej warstwa Modelu, jest kluczowe. Rysunek 13 (dostępny również w formacie PDF) przedstawia prawie wszystkie klasy i interfejsy dostępne w wersji 1.5 pakietu com.eteks.sweethome3d.model, który odpowiada tej warstwie Modelu.
[uml_diagram slug=”model-classes-diagram” map_name=”model-classes-diagram” caption=”Figure 13. UML diagram of com.eteks.sweethome3d.model package” caption_small=”(click on a class to view its javadoc)”]
Centralną klasą w warstwie Modelu jest klasa HomeApplication (10), abstrakcyjna nadklasa głównej klasy aplikacji SweetHome3D. Instancja tej klasy daje dostęp do aktualnie edytowanych instancji Home (7) oraz do obiektu UserPreferences (11), który przechowuje używaną jednostkę długości (12), katalog mebli (14) i katalog tekstur (15), z których użytkownik wybiera meble (17) i tekstury (18).
Instancja Home (7) przechowuje wszystkie obiekty, które użytkownik utworzył w planie domu:
- listę obiektów HomePieceOfFurniture (13), które implementują interfejs PieceOfFurniture (16),
- kolekcję obiektów Wall (9),
- listę obiektów Room (5),
- kolekcję obiektów DimensionLine (2),
- kolekcję obiektów Label (3).
Te obiekty implementują interfejs Selectable (1), podobnie jak obiekt ObserverCamera (4), który przechowuje lokalizację kamery w trybie Wirtualnego zwiedzającego. Wszystkie zewnętrzne informacje zarządzane przez obiekty Modelu, takie jak ikona i model 3D mebla (16) lub obraz tekstury (20), są dostępne przez interfejs Content (19), implementowany przez klasę URLContent i inne klasy pakietu com.eteks.sweethome3d.tools.
Ten diagram UML powinien pomóc ci zrozumieć, jakie klasy są dostępne w modelu Sweet Home 3D i jak możesz uzyskać do nich dostęp, ale prawdopodobnie zauważysz, że nie są w nim wymienione żadne konstruktory ani mutatory (lub settery, jeśli wolisz). To tylko z braku miejsca, ale możesz ich bez problemu używać w klasie wtyczki. Zauważ też, że każda modyfikacja istniejącego obiektu modelu będzie zgłaszana do wyświetlanych komponentów albo za pomocą PropertyChangeEventów, CollectionEventów (8) lub SelectionEventów (6), co pozwala na natychmiastowe odzwierciedlenie wszystkich zmian na ekranie.
Architektura klas wtyczek
Architektura klas wtyczek jest znacznie prostsza do zrozumienia niż architektura warstwy Modelu. Pakiet com.eteks.sweethome3d.plugin zawiera tylko trzy klasy, z których powinieneś używać tylko klas Plugin i PluginAction, jak pokazano na rysunku 14 (dostępnym również w formacie PDF).
[uml_diagram slug=”plugin-classes-diagram” map_name=”plugin-classes-diagram” caption=”Figure 14. UML diagram of com.eteks.sweethome3d.plugin package” caption_small=”(click on a class to view its javadoc)”]
Instancja PluginManager (1) jest tworzona przy uruchomieniu aplikacji i wyszukuje wtyczki zainstalowane w folderze wtyczek użytkownika. Za każdym razem, gdy edytowany jest nowy dom, ten menedżer tworzy instancję i konfiguruje obiekt Plugin (3) dla każdej wtyczki znalezionej w momencie uruchomienia. Następnie wywołuje metodę getActions, aby pobrać wszystkie akcje (4), które zostaną dodane jako elementy menu i/lub przyciski paska narzędzi w oknie domu. Każda akcja jest instancją PluginAction, która przypomina klasę Action, z jej metodą execute i modyfikowalnymi właściwościami (2).
Zauważ, że klasa Plugin daje ci dostęp do instancji UndoableEditSupport poprzez jej metodę getUndoableEditSupport. Gdy tylko zmodyfikujesz dom lub jego obiekty (meble, ściany…) w metodzie execute instancji PluginAction, powinieneś również wysłać obiekt UndoableEdit do obsługi edycji cofania zwróconej przez metodę getUndoableEditSupport, w przeciwnym razie użytkownicy nie będą mogli prawidłowo cofać/ponawiać wprowadzonych przez ciebie zmian.
Lokalizacja
Jeśli planujesz opracować wtyczkę dla społeczności użytkowników Sweet Home 3D, postaraj się zlokalizować wyświetlane przez nią ciągi znaków, zarówno w nazwach akcji i menu, jak i w tworzonych dialogach (lub przynajmniej przygotuj jej lokalizację). Dwa konstruktory klasy PluginAction pomogą Ci zorganizować tłumaczenie właściwości akcji za pomocą plików .properties, a jeśli potrzebujesz przetłumaczyć inne ciągi znaków w swojej wtyczce (jak te w oknie dialogowym pokazanym przez testowaną wtyczkę), wykorzystaj ponownie te pliki .properties z klasą Java ResourceBundle.
Jeśli wolisz ograniczyć liczbę plików właściwości, możesz nawet zapisać wartości właściwości akcji i inne ciągi znaków w pliku opisu ApplicationPlugin.properties swojej wtyczki.
Jeśli chcesz zobaczyć przykład wykorzystujący tę architekturę, pobierz wtyczkę Export to SH3F dostępną pod adresem https://test.sweethome3d.eu/plugins/ExportToSH3F-1.0.sh3p i rozpakuj ją (ten plik wtyczki zawiera również kod źródłowy wtyczki).
Jak opisano na forum pomocy, ta wtyczka tworzy plik SH3F, który zawiera wszystkie meble zaimportowane do katalogu mebli Sweet Home 3D.
Udostępnianie wtyczek
Możesz opublikować zaprogramowane przez siebie wtyczki w systemie śledzenia Plug-ins Contributions, aby podzielić się nimi ze społecznością użytkowników Sweet Home 3D.
Wiele funkcji można dodać do Sweet Home 3D dzięki wtyczkom, od importerów po eksportery, ale także wtyczki zdolne do modyfikowania danych domu, jak Home Rotator Plug-in opracowany przez Michela Mbema i inne wymienione w Poradniku dla wtyczek i rozszerzeń (PDF) napisanym przez Hansa Dirkse oraz na stronie Wtyczki i narzędzia.
