Inleiding

Vanaf versie 1.5 is het mogelijk om nieuwe functies aan Sweet Home 3D toe te voegen met plug-in bestanden die in je plug-ins map worden geplaatst. Dit stelt Java-programmeurs in staat om nieuwe functies voor Sweet Home 3D te ontwikkelen en te distribueren zonder de bronbestanden van de huidige versie te wijzigen (wat goed is voor opwaartse compatibiliteit), en zonder een volledige versie van het programma te leveren (wat goed is voor de omvang van de levering).
Dit document beschrijft de tools die nodig zijn om plug-ins te maken, laat vervolgens zien hoe je een plug-in kunt programmeren die het maximale volume van het verplaatsbare meubilair berekent dat aan een huis is toegevoegd, en geeft ten slotte wat aanvullende informatie die je helpt om verder te gaan.

Ontwikkeltools installeren

Hoewel Sweet Home 3D zich richt op een algemeen publiek, vereist het ontwikkelen van plug-ins speciale vaardigheden, en je moet weten hoe je in Java moet programmeren met een IDE, voordat je verder gaat. Deze handleiding laat zien hoe je een plug-in kunt bouwen met Eclipse, maar je kunt de IDE van je keuze gebruiken, of helemaal geen IDE.

Download en installeer Eclipse

Download eerst Eclipse van https://www.eclipse.org/. De versie genaamd Eclipse IDE for Java Developers is voldoende om een plug-in te ontwikkelen, maar je kunt elke versie voor Java-ontwikkeling downloaden.
Eenmaal gedownload, is het installeren van Eclipse zeer eenvoudig: pak gewoon het archief dat je krijgt uit, open de eclipse map en voer, afhankelijk van je systeem, het bestand uit met de naam eclipse.exe (onder Windows), eclipse.app (onder Mac OS X) of eclipse (onder Linux).
Bij de eerste keer opstarten zal Eclipse je vragen om een workspace map te kiezen, waar plug-in projecten zullen worden opgeslagen.
Kies vervolgens File > New > Project uit het menu om een nieuw project te maken, selecteer Java > Java project in de New project wizard die wordt weergegeven, voer VolumePlugin in als projectnaam en klik op de knop Finish. Sluit ten slotte het tabblad Welcome om je workspace te ontdekken zoals weergegeven in figuur 1.

Figuur 1. Eclipse workspace

Download en installeer Sweet Home 3D bibliotheek

De ontwikkeling van een plug-in is gebaseerd op enkele klassen van Sweet Home 3D die Eclipse moet kennen om je project te kunnen bouwen. De eenvoudigste manier om Sweet Home 3D klassen aan Eclipse toe te voegen is door de JAR uitvoerbare versie van Sweet Home 3D te downloaden die beschikbaar is op https://sourceforge.net/projects/sweethome3d/files/SweetHome3D/SweetHome3D-7.5/SweetHome3D-7.5.jar/download. Eenmaal gedownload, sleep en zet het bestand SweetHome3D-7.5.jar neer op het pictogram van het VolumePlugin project in de Package Explorer weergave van Eclipse, en kies het item Build Path > Add to Build Path in het contextmenu van het SweetHome3D-7.5.jar bestand, zoals weergegeven in figuur 2.

Figuur 2. SweetHome3D-7.5.jar
toevoegen aan Build Path

Een plug-in programmeren

Nu je de vereiste tools hebt geïnstalleerd, laten we eens kijken hoe je je eerste plug-in voor Sweet Home 3D kunt programmeren.

De plug-in klasse maken

Maak eerst een nieuwe subklasse van com.eteks.sweethome3d.plugin.Plugin door File > New > Class menu-item te kiezen in Eclipse.

Figuur 3. Een nieuwe klasse maken

Voer in het dialoogvenster New Java Class VolumePlugin in als de klassenaam, voer een pakket in (hier is het gekozen pakket com.eteks.test), en kies com.eteks.sweethome3d.plugin.Plugin als de superklasse van VolumePlugin. Klik vervolgens op Finish. Eclipse zal het bestand van de nieuwe klasse maken met de volgende inhoud:

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;
}
}

Zoals je kunt raden uit de TODO-opmerking, moet je nu de implementatie van de getActions methode wijzigen om een plug-in actie te retourneren die het volume van het verplaatsbare meubilair kan berekenen. Vervang return null; door de volgende verklaring:

  return new PluginAction [] {new VolumeAction()};  

en kies Edition > Quick Fix uit het Eclipse-menu om de ontbrekende klasse VolumeAction te maken, zoals weergegeven in figuur 4.

Figuur 4. Quick fix gebruiken om een ontbrekende klasse te genereren

Selecteer in het dialoogvenster New Java Class dat verschijnt het selectievakje Enclosing type om een inner class van VolumePlugin te maken en klik op Finish. Dit zal de klasse VolumeAction maken die overerft van de klasse com.eteks.sweethome3d.plugin.PluginAction en een lege execute methode bevat:

  public class VolumeAction extends PluginAction {
@Override
public void execute() {
// TODO Auto-generated method stub
}
}

Dit is de methode die Sweet Home 3D zal aanroepen wanneer de gebruiker de plug-in actie start; dit is dus de plek waar je moet implementeren hoe het volume van het meubilair moet worden berekend en weergegeven:

  public class VolumeAction extends PluginAction {  
@Override
public void execute() {
float volumeInCm3 = 0;
// Bereken de som van het volume van de bounding box van
// elk verplaatsbaar meubelstuk in het huis
for (PieceOfFurniture piece : getHome(). getFurniture()) {
if (piece. isMovable()) {
volumeInCm3 += piece. getWidth()
* piece. getDepth()
* piece. getHeight();
}
}

// Toon het resultaat in een berichtvenster (³ is voor 3 in superscript)
String message = String. format(
"Het maximale volume van het verplaatsbare meubilair in het huis is %.2f m³.",
volumeInCm3 / 1000000);
JOptionPane. showMessageDialog(null, message);
}
}

Nu je hebt gespecificeerd wat je wilt dat de plug-in doet, moet je beschrijven hoe de gebruiker deze nieuwe actie zal starten. Je hebt de keuze tussen het toevoegen van een nieuw menu-item aan een menu, en/of een nieuwe knop aan de werkbalk. Deze keuze wordt gemaakt door de juiste eigenschappen van de plug-in actie in te stellen bij de creatie ervan. Als je bijvoorbeeld wilt dat gebruikers de volume-actie starten met het menu-item Volume berekenen in het menu Tools, voeg je de volgende constructor toe aan de VolumnAction klasse:

  public VolumeAction() {
putPropertyValue(Property.NAME, "Volume berekenen");
putPropertyValue(Property.MENU, "Tools");
// Schakelt de actie standaard in
setEnabled(true);
}

De VolumePlugin plug-in klasse is nu geprogrammeerd en bijna klaar om als plug-in in Sweet Home 3D te werken. De twee laatste dingen die je moet doen zijn:

  • een ApplicationPlugin.properties beschrijvingsbestand maken,
  • de bestanden samenvoegen in een JAR-bestand.

Het plug-in beschrijvingsbestand maken

Een ApplicationPlugin.properties bestand beschrijft de plug-in naam, zijn klasse, de minimale versies van Sweet Home 3D en Java waaronder het wordt ondersteund, en juridische zaken. Kies File > New > File uit het Eclipse-menu, voer de bestandsnaam ApplicationPlugin.properties in en klik op Finish, zoals weergegeven in figuur 5.

Figuur 5. Een nieuw bestand maken

Voer vervolgens de volgende beschrijving in het nieuwe bestand in en sla het op:

name=Volume verplaatsbaar meubilair
class=com.eteks.test.VolumePlugin
description=Berekent het volume van het verplaatsbare meubilair in het huis
version=1.0
license=GNU GPL
provider=(C) Copyrights 2024 Space Mushrooms
applicationMinimumVersion=1.5
javaMinimumVersion=1.5

De plug-in JAR maken

De plug-in JAR bevat de class bestanden die zijn gemaakt bij het compileren van het VolumePlugin.java bestand, en het ApplicationPlugin.properties bestand. Aangezien Eclipse een Java-bestand compileert zodra je het opslaat, hoef je alleen maar File > Export… uit het menu te kiezen en Java > JAR file te selecteren in het Export dialoogvenster dat wordt weergegeven. Selecteer in de Jar Export wizard die verschijnt, zoals weergegeven in figuur 6, het project selectievakje en voer het pad in van een JAR-bestand dat in de Sweet Home 3D plug-ins map is geplaatst. Deze juiste map is afhankelijk van je systeem als volgt:

  • onder Windows Vista / 7 / 8 / 10 / 11 is deze map C:\Users\gebruiker\AppData\Roaming\eTeks\Sweet Home 3D\plugins,
  • onder Windows XP en eerdere versies van Windows is deze map C:\Documents and Settings\gebruiker\Application Data\eTeks\Sweet Home 3D\plugins,
  • onder macOS is het de submap Library/Application Support/eTeks/Sweet Home 3D/plugins van je gebruikersmap,
  • onder Linux en andere Unix-systemen is het de submap .eteks/sweethome3d/plugins van je gebruikersmap.
Figuur 6. Exporteren naar een JAR-bestand

De plug-in testen

De plug-in die je hebt ontwikkeld zal draaien in Sweet Home 3D, ofwel met de Java Web Start versie, de installers versie, of de SweetHome3D-7.5.jar die je eerder hebt gedownload. Aangezien de laatste een uitvoerbare JAR is, kun je deze uitvoeren door er dubbel op te klikken of met het volgende commando:

De plug-in die je hebt ontwikkeld zal draaien in Sweet Home 3D, ofwel met de Java Web Start versie, de installers versie, of de SweetHome3D-7.5.jar die je eerder hebt gedownload. Aangezien de laatste een uitvoerbare JAR is, kun je deze uitvoeren door er dubbel op te klikken of met het volgende commando:

java -jar /pad/naar/SweetHome3D-7.5.jar

Zolang je aan het testen bent, zul je waarschijnlijk de voorkeur geven aan het uitvoeren van Sweet Home 3D met dit commando, om in de console de stack trace van de uitzonderingen te kunnen lezen die tijdens de uitvoering van je plug-in worden gegooid.

Zodra Sweet Home 3D is gestart, zie je het nieuwe menu en het bijbehorende item verschijnen zoals weergegeven in figuur 7:

Figuur 7. Plug-in menu

Als je het nieuwe menu-item kiest voor het voorbeeld huis gemaakt in de gebruikershandleiding, krijg je het volgende resultaat:

Figuur 8. Plug-in in actie

De plug-in debuggen

Als je je plug-in vanuit Eclipse moet debuggen, maak dan een debug-configuratie door deze stappen te volgen:

  • Kies Run > Debug Configurations… uit het menu, selecteer het item Java Application in de lijst met beschikbare configuraties van het Debug configurations dialoogvenster, klik op de New knop linksboven en voer een naam in voor de configuratie.
  • Klik op de Search… knop rechts van het Main class tekstveld en dubbelklik op de SweetHome3DBootstrap klasse
    tussen de voorgestelde klassen.
Figuur 9. Een debug-configuratie aanmaken
  • Klik op het tabblad Classpath, selecteer het sub-item VolumePlugin (default classpath) van het item User Entries in de Classpath lijst en klik op de Remove knop.
  • Klik op het item User Entries in de Classpath lijst, klik op de Add JARs… knop, selecteer het SweetHome3D-7.5.jar item en bevestig je keuze.
Figuur 10. De classpath van de debug-configuratie instellen
  • Selecteer het tabblad Source, klik op de Add… knop, dubbelklik op het Java Project item in het Add Source dialoogvenster, selecteer het VolumePlugin item in de Project Selection popup en bevestig je keuze.
Figuur 11. Het bronpad van de debug-configuratie instellen
  • Klik ten slotte op de Debug knop om Sweet Home 3D in debug-modus te starten. Zodra het programma draait, open je het VolumePlugin.java bestand, zet een breakpoint in de execute methode en kies Tools Compute volume uit het Sweet Home 3D menu. Eclipse zal stoppen op het geselecteerde breakpoint om je het programma stap voor stap te laten uitvoeren en variabelen te inspecteren.
Figuur 12. Eclipse debug perspectief

Elke keer dat je de broncode van je plug-in wijzigt, vergeet dan niet om de plug-in JAR te genereren voordat je de debug-configuratie start die je hebt gemaakt. Om het JAR-exportproces in Eclipse te versnellen, ga je naar de tweede stap van de JAR-exportwizard en selecteer je de optie Save the description of this JAR in the workspace. Dit voegt een nieuw item toe aan het project met een contextueel Create JAR menu-item.

De plug-in implementeren

Eenmaal klaar kan je plug-in worden geïmplementeerd op de computer van andere Sweet Home 3D-gebruikers door deze simpelweg te kopiëren naar hun plug-ins map. Vanaf versie 1.6 kan een plug-in bestand ook worden geïnstalleerd in de plug-ins map van Sweet Home 3D door er dubbel op te klikken, als de extensie SH3P is (verander simpelweg de bestandsextensie van .zip naar .sh3p). Als dubbelklikken op een .sh3p bestand Sweet Home 3D niet start (grote kans onder Linux), kun je ook een plug-in installeren met het volgende commando in een Terminal venster (waarbij SweetHome3D de naam is van het uitvoerbare bestand dat bij Sweet Home 3D installatieprogramma’s wordt geleverd):

/pad/naar/SweetHome3D /pad/naar/plugin.sh3p

Om een plug-in niet meer te gebruiken, verwijder je het bestand uit de plug-ins map en start je Sweet Home 3D opnieuw.

Als je wilt dat je plug-in kan draaien met alle Sweet Home 3D installatieprogramma’s die beschikbaar zijn op deze website, zorg er dan voor dat deze compatibel blijft met Java 5, door 1.5 te selecteren in het veld Compiler compliance level beschikbaar in de Java Compiler sectie van het dialoogvenster dat wordt getoond door het Project > Properties menu-item van Eclipse.
Als je een Java compiler versie gebruikt waar Java 1.5 compatibiliteit niet meer beschikbaar is, probeer dan ten minste Java 1.8 te targeten die nog steeds wordt gebruikt in recente versies van Sweet Home 3D en stel javaMinimumVersion in het ApplicationPlugin.properties bestand van je plug-in dienovereenkomstig in.

Verder gaan

Het programmeren van de eerste plug-in gaf je een overzicht. Hier is wat aanvullende informatie die je zal helpen om verder te gaan.

Sweet Home 3D API – Javadoc

De meest nuttige documentatie voor het ontwikkelen van een nieuwe plug-in is de Sweet Home 3D API (Application Programming Interface), gegenereerd met het javadoc-tool.
Gebruik in je plug-in alleen de klassen van com.eteks.sweethome3d.plugin, com.eteks.sweethome3d.model, com.eteks.sweethome3d.tools en com.eteks.sweethome3d.viewcontroller pakketten als je wilt dat deze compatibel blijft met toekomstige versies van Sweet Home 3D. Dit is ruim voldoende om elke plug-in te programmeren die werkt met de beschikbare huisgegevens in Sweet Home 3D.
De pakketten die overeenkomen met de andere lagen van het programma zijn alleen ter informatie opgenomen in de Javadoc. Vertrouw niet op hun API, aangezien deze in de toekomst nog kan veranderen zonder garantie op opwaartse compatibiliteit (je zult trouwens geen verwijzing zien naar een klasse van com.eteks.sweethome3d.swing, com.eteks.sweethome3d.j3d, com.eteks.sweethome3d.io of com.eteks.sweethome3d pakketten in de eerder genoemde pakketten).

Architectuur van modelklassen

Sweet Home 3D is gebaseerd op een MVC (Model View Controller) architectuur, dus het begrijpen van hoe de Model-laag is georganiseerd is essentieel. Figuur 13 (ook beschikbaar in PDF-formaat) toont bijna alle klassen en interfaces die beschikbaar zijn in versie 1.5 van het com.eteks.sweethome3d.model pakket dat overeenkomt met deze Model-laag.

[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)”]

De centrale klasse in de Model-laag is de HomeApplication klasse (10), de abstracte superklasse van de SweetHome3D applicatie hoofdklasse. De instantie van deze klasse geeft toegang tot de momenteel bewerkte Home instanties (7), en tot het UserPreferences object (11) dat de gebruikte lengte-eenheid (12), de meubel catalogus (14) en de texturencatalogus (15) opslaat waaruit de gebruiker meubelstukken (17) en texturen (18) kiest.
Een Home instantie (7) slaat alle objecten op die de gebruiker in het huisplan heeft gemaakt:

Deze objecten implementeren de Selectable interface (1) evenals het ObserverCamera object (4), dat de locatie van de camera in de Virtuele bezoeker modus opslaat. Alle externe informatie die wordt beheerd door Model objecten, zoals het pictogram en het 3D-model van een meubelstuk (16), of de afbeelding van een textuur (20) wordt benaderd via de Content interface (19), geïmplementeerd door de URLContent klasse en andere klassen van het com.eteks.sweethome3d.tools pakket.

Dit UML-diagram zou je moeten helpen begrijpen welke klassen beschikbaar zijn in het Sweet Home 3D model en hoe je ze kunt benaderen, maar je zult waarschijnlijk opmerken dat er geen constructors en geen mutators (of setters als je dat liever hebt) worden genoemd. Dit komt alleen door ruimtegebrek, maar je kunt ze zonder problemen gebruiken in een plug-in klasse. Merk ook op dat elke wijziging van een bestaand object van het model wordt gemeld aan de weergegeven componenten via PropertyChangeEvents, CollectionEvents (8) of SelectionEvents (6), waardoor alle wijzigingen direct op het scherm worden weergegeven.

Het Sweet Home 3D model is niet thread-safe om prestatieredenen. Alle wijzigingen van een object dat tot het model behoort, moeten worden uitgevoerd in de Event Dispatch Thread.

Architectuur van plug-in klassen

De architectuur van plug-in klassen is veel eenvoudiger te begrijpen dan die van de Model-laag. Het com.eteks.sweethome3d.plugin pakket bevat slechts drie klassen waarvan je alleen de Plugin en PluginAction klassen wordt geacht te gebruiken, zoals getoond in figuur 14 (ook beschikbaar in PDF-formaat).

[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)”]

Een PluginManager instantie (1) wordt bij het opstarten van de applicatie gemaakt en zoekt naar de plug-ins die zijn geïnstalleerd in de plug-ins map van de gebruiker. Elke keer dat een nieuw huis wordt bewerkt, instantieert deze manager een Plugin object (3) voor elke plug-in die bij het opstarten is gevonden en configureert deze. Vervolgens roept het de getActions methode aan om alle acties (4) op te halen die als menu-items en/of werkbalk knoppen aan het huisvenster worden toegevoegd. Elke actie is een instantie van PluginAction, die lijkt op de Action klasse, met zijn execute methode en zijn aanpasbare eigenschappen (2).

Merk op dat de Plugin klasse je toegang geeft tot een UndoableEditSupport instantie via de getUndoableEditSupport methode. Zodra je een huis of zijn objecten (meubels, muren…) wijzigt in de execute methode van een PluginAction instantie, moet je ook een UndoableEdit object posten naar de undoable edit support die wordt teruggegeven door de getUndoableEditSupport methode, anders kunnen gebruikers de aangebrachte wijzigingen niet correct ongedaan maken/opnieuw uitvoeren.

Lokalisatie

Als je van plan bent een plug-in te ontwikkelen voor de Sweet Home 3D gebruikersgemeenschap, probeer dan de strings die het weergeeft te lokaliseren, zowel in actienamen en menu’s als in dialoogvensters die je maakt (of bereid op zijn minst de lokalisatie voor). Twee constructors van de PluginAction klasse helpen je om de vertaling van actie-eigenschappen te organiseren met .properties bestanden, en als je andere strings in je plug-in moet vertalen (zoals die in het dialoogvenster dat wordt getoond door de geteste plug-in) hergebruik dan deze .properties bestanden met de Java ResourceBundle klasse.
Als je het aantal property bestanden wilt beperken, kun je de waarden van de actie-eigenschappen en andere strings zelfs schrijven in het ApplicationPlugin.properties beschrijvingsbestand van je plug-in.

Als je een voorbeeld wilt dat deze architectuur gebruikt, download dan de Export to SH3F plug-in beschikbaar op https://test.sweethome3d.eu/plugins/ExportToSH3F-1.0.sh3p, en pak het uit (dit plug-in bestand bevat ook de broncode van de plug-in).
Zoals beschreven in het Help forum, maakt deze plug-in een SH3F-bestand dat alle meubels bevat die je hebt geïmporteerd in de meubelcatalogus van Sweet Home 3D.

Plug-ins bijdragen

Je kunt de plug-ins die je hebt geprogrammeerd plaatsen in het Plug-ins Contributions Tracking System om ze te delen met de Sweet Home 3D gebruikersgemeenschap.
Veel functies kunnen aan Sweet Home 3D worden toegevoegd via plug-ins, van importeurs tot exporteurs, maar ook plug-ins die de gegevens van een huis kunnen wijzigen zoals de Home Rotator Plug-in ontwikkeld door Michel Mbem en anderen die zijn vermeld in de Tutorial voor Plug-ins en Extensies (PDF) geschreven door Hans Dirkse en op de Plug-ins en tools pagina.