Przewodnik dla twórców wtyczek
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 tworzyć i rozpowszechniać nowe funkcje 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 dla rozmiaru dystrybucji).
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 ze strony 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 systemie Windows), eclipse.app (w systemie Mac OS X) lub eclipse (w systemie 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 się wyświetli, 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 https://sourceforge.net/projects/sweethome3d/files/SweetHome3D/SweetHome3D-7.5/SweetHome3D-7.5.jar/download. Po pobraniu przeciągnij i upuść plik SweetHome3D-7.5.jar na ikonę projektu VolumePlugin w widoku Package Explorer w Eclipse i wybierz pozycję Build Path > Add to Build Path z menu kontekstowego pliku SweetHome3D-7.5.jar, jak pokazano na rysunku 2.

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 (³ oznacza 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 Javy, pod którymi jest obsługiwana, oraz informacje 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 się wyświetli. 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 systemie Windows Vista / 7 / 8 / 10 / 11, ten folder to C:UsersużytkownikAppDataRoamingeTeksSweet Home 3Dplugins,
- w systemie Windows XP i wcześniejszych wersjach Windows, ten folder to C:Documents and SettingsużytkownikApplication DataeTeksSweet Home 3Dplugins,
- w systemie macOS, to podfolder Library/Application Support/eTeks/Sweet Home 3D/plugins twojego folderu użytkownika,
- w systemie Linux i innych systemach Unix, to podfolder .eteks/sweethome3d/plugins twojego folderu 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 zgłaszanych 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 Szukaj… po prawej stronie pola tekstowego Klasa główna i kliknij dwukrotnie klasę SweetHome3DBootstrap
spośród proponowanych klas.

- Kliknij zakładkę Classpath, wybierz element podrzędny VolumePlugin (default classpath) elementu User Entries na liście Classpath i kliknij przycisk Remove.
- Kliknij element User Entries na liście Classpath, kliknij przycisk Add JARs…, wybierz element SweetHome3D-7.5.jar i potwierdź swój wybór.

- Wybierz zakładkę Source, kliknij przycisk Add…, kliknij dwukrotnie element Java Project w oknie dialogowym Add Source, wybierz element VolumePlugin w oknie popup Project Selection i potwierdź swój wybór.

- Na koniec kliknij przycisk Debug, żeby uruchomić Sweet Home 3D w trybie debugowania. Gdy program już działa, otwórz plik
VolumePlugin.java ,ustaw punkt przerwania w metodzie execute i wybierzNarzędzia z menu Sweet Home 3D. Eclipse zatrzyma się na wybranym punkcie przerwania, żeby umożliwić ci wykonywanie programu krok po kroku i sprawdzanie wartości zmiennych.Oblicz objętość


Za każdym razem, gdy modyfikujesz kod źródłowy swojej wtyczki, nie zapomnij wygenerować pliku JAR wtyczki przed uruchomieniem utworzonej konfiguracji debugowania. Żeby przyspieszyć proces eksportu JAR w eclipse, przejdź do drugiego kroku kreatora eksportu JAR i wybierz opcję Zapisz opis tego pliku JAR w obszarze roboczym. To doda nowy element w projekcie z kontekstowym elementem menu Utwórz JAR.
Wdrażanie wtyczki
Gdy będzie gotowa, twoja wtyczka może zostać wdrożona na komputerach innych użytkowników Sweet Home 3D przez zwykłe skopiowanie jej do ich folderu wtyczek. Od wersji 1.6 plik wtyczki może być również zainstalowany w folderze wtyczek Sweet Home 3D przez dwukrotne kliknięcie na nim, jeśli jego rozszerzenie to SH3P (po prostu zmień rozszerzenie pliku z .zip na .sh3p). Jeśli dwukrotne kliknięcie na plik .sh3p nie uruchamia Sweet Home 3D (najczęściej pod Linuksem), możesz również zainstalować wtyczkę za pomocą następującego polecenia w oknie Terminal (gdzie SweetHome3D to nazwa pliku wykonywalnego dostarczonego z instalatorami Sweet Home 3D):
/ścieżka/do/SweetHome3D /ścieżka/do/plugin.sh3p
Żeby przestać używać wtyczki, usuń jej plik z folderu wtyczek i uruchom ponownie Sweet Home 3D.

Jeśli chcesz, żeby twoja wtyczka mogła działać ze wszystkimi instalatorami Sweet Home 3D dostępnymi na tej stronie internetowej, zadbaj o zachowanie zgodności z Java 5, wybierając 1.5 w polu Poziom zgodności kompilatora dostępnym w sekcji Java Compiler okna dialogowego pokazywanego przez element menu Project > Properties 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ć przynajmniej w Java 1.8 nadal używaną w najnowszych wersjach Sweet Home 3D i ustaw javaMinimumVersion w pliku ApplicationPlugin.properties swojej wtyczki odpowiednio.
Dalsze kroki
Programowanie pierwszej wtyczki pokazało ci ogólny obraz. Oto dodatkowe informacje, które pomogą ci pójść dalej.
Sweet home 3D API – javadoc
Najbardziej przydatną dokumentacją do tworzenia nowej wtyczki jest Sweet Home 3D API (Application Programming Interface), wygenerowane narzędziem javadoc.
Używaj tylko klas z pakietów com.eteks.sweethome3d.plugin, com.eteks.sweethome3d.model, com.eteks.sweethome3d.tools i com.eteks.sweethome3d.viewcontroller w swojej wtyczce, jeśli chcesz, żeby 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 pracuje na danych domu dostępnych w Sweet Home 3D.
Pakiety odpowiadające innym warstwom programu są dołączone do Javadoc tylko w celach informacyjnych. Nie polegaj na ich API, ponieważ może się jeszcze zmienić w przyszłości bez gwarancji zgodności wstecznej (i tak nie zobaczysz żadnego odniesienia do klasy z pakietów com.eteks.sweethome3d.swing, com.eteks.sweethome3d.j3d, com.eteks.sweethome3d.io czy com.eteks.sweethome3d w wymienionych wcześniej pakietach).
Architektura klas modelu
Sweet Home 3D opiera się na architekturze MVC (Model View Controller), więc zrozumienie organizacji warstwy Model 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 Model.
(click on a class to view its javadoc)
Centralną klasą w warstwie Model jest klasa HomeApplication (10), abstrakcyjna klasa nadrzędna 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 elementy wyposażenia (17) i tekstury (18).
Instancja Home (7) przechowuje wszystkie obiekty utworzone przez użytkownika 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 położenie kamery w trybie Wirtualny zwiedzający. Wszystkie zewnętrzne informacje zarządzane przez obiekty Model, jak ikona i model 3D elementu wyposażenia (16) czy 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ć, które klasy są dostępne w modelu Sweet Home 3D i jak możesz do nich uzyskać dostęp, ale prawdopodobnie zauważysz, że nie ma w nim konstruktorów ani mutatorów (lub setterów, jeśli wolisz). To tylko z braku miejsca, ale możesz ich używać bez problemu w klasie wtyczki. Zauważ również, że każda modyfikacja istniejącego obiektu modelu zostanie powiadomiona do wyświetlanych komponentów za pomocą PropertyChangeEventów, CollectionEventów (8) lub SelectionEventów (6), umożliwiając natychmiastowe odzwierciedlenie wszystkich zmian na ekranie.

Model Sweet Home 3D nie jest bezpieczny wątkowo ze względów wydajnościowych. Wszystkie modyfikacje obiektu należącego do modelu powinny być wykonywane w Event Dispatch Thread.
Architektura klas wtyczek
Architektura klas wtyczek jest znacznie prostsza do zrozumienia niż architektura warstwy Model. 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 (również dostępnym w formacie PDF).
(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 przy uruchomieniu. Następnie wywołuje metodę getActions, żeby 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 ze swoją metodą execute i modyfikowalnymi właściwościami (2).
Zauważ, że klasa Plugin daje ci dostęp do instancji UndoableEditSupport przez swoją metodę getUndoableEditSupport. Gdy tylko modyfikujesz dom lub jego obiekty (meble, ściany…) w metodzie execute instancji PluginAction, powinieneś również wysłać obiekt UndoableEdit do wsparcia edycji cofania zwróconego przez metodę getUndoableEditSupport, w przeciwnym razie użytkownicy nie będą mogli poprawnie cofnąć/ponowić wprowadzonych przez ciebie zmian.
Lokalizacja
Jeśli planujesz opracować wtyczkę dla społeczności użytkowników Sweet Home 3D, spróbuj zlokalizować wyświetlane przez nią ciągi znaków zarówno w nazwach akcji i menu, jak i w tworzonych oknach dialogowych (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 pokazywanym przez testowaną wtyczkę), użyj ponownie tych plików .properties z klasą Java ResourceBundle.
Jeśli wolisz ograniczyć liczbę plików properties, możesz nawet napisać wartości właściwości akcji i innych ciągów znaków w pliku opisu ApplicationPlugin.properties swojej wtyczki.
Jeśli chcesz przykład, który używa tej architektury, pobierz wtyczkę Export to SH3F dostępną pod adresem https://www.sweethome3d.com/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 publikować zaprogramowane przez siebie wtyczki w systemie śledzenia Plug-ins Contributions, żeby dzielić 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 opracowana przez Michela Mbema i inne wymienione w Tutorial for Plug-ins and Extensions (PDF) napisanym przez Hansa Dirkse oraz na stronie Plug-ins and tools.