Incomplete and not reliable yet!
- Intro
- The plugin directory
- API overview
- Setting up a plugin project
- Plugin development tutorials & examples
Boomega allows you to develop plugins in order to add more features/functionality to the app.
Plugins can be written in both java and kotlin.
The recommended language for writing plugins is kotlin because most of the Plugin API entities are written in it. This guide will provide you both kotlin and java examples tough.
You can view the loaded plugins and their impact on the app. Read about the plugin manager in the user guide.
On the JVM (Java Virtual Machine) it's possible to load classes dynamically at runtime with the help
of Class Loaders.
Since Boomega is a JVM application, it takes full advantage of this.
Boomega automatically loads plugin archives (.jar
s) from the default plugin directory.
- Path on Windows:
%APPDATA%\Dansoftware\boomega\plugin
- Path on Linux & macOS:
<User directory>/boomega/plugin
If you want to load your plugin into Boomega, you should place the jar file into this directory.
You can open the plugin directory from the Boomega menu-bar: File > Open plugin directory
The root of the Boomega plugin hierarchy is:
com.dansoftware.boomega.plugin.api.BoomegaPlugin
.
All other plugin classes should implement this interface.
BoomegaPlugin subtypes:
com.dansoftware.boomega.plugin.LanguagePlugin
- for adding support for a new languagecom.dansoftware.boomega.plugin.ThemePlugin
- for adding a new UI themecom.dansoftware.boomega.plugin.RecordExporterPlugin
- for adding new record exporting optioncom.dansoftware.boomega.plugin.ModulePlugin
- for adding new UI modulescom.dansoftware.boomega.plugin.DatabaseProviderPlugin
- for adding custom database support
The DisabledPlugin annotation:
The @DisabledPlugin
annotation can be used
for preventing Boomega to load a plugin class.
Example:
Kotlin | Java |
---|---|
@DisabledPlugin // make Boomega ignore this plugin
class MonokaiThemePlugin : ThemePlugin {
...
} |
@DisabledPlugin // make Boomega ignore this plugin
public class MonokaiThemePlugin implements ThemePlugin {
...
} |
When the application starts running, it searches for all BoomegaPlugin
implementations and instantiates them. Every
plugin class will be instantiated only once during the application lifetime, meaning they behave practically as
singletons. After a BoomegaPlugin
is instantiated, Boomega invokes the init()
method on it. When the application
shuts down, the destroy()
method is invoked on the plugin instance.
Every BoomegaPlugin
should provide this
information:
name
:String
- defines the plugin's nameauthor
:Person
- information about the plugin's authorversion
:String
- defines the plugin's version- Optional:
icon
:Image
- the plugin's icon (as a JavaFX image)
Example:
Kotlin | Java |
---|---|
class MonokaiThemePlugin : ThemePlugin {
// General BoomegaPlugin meta-data
override val name: String = "Mononokai Theme Plugin"
override val author = Person(firstName = "FirstName", lastName = "LastName", "myemail@example.com")
override val version: String = "1.0.0"
override val description: String? = "Adds a Monokai Theme scheme."
...
} |
public class MonokaiThemePlugin implements ThemePlugin {
@Override
public @NotNull String getName() {
return "Monokai Theme Plugin";
}
@Override
public @NotNull Person getAuthor() {
return new Person("LastName", "FirstName", "myemail@example.com");
}
@Override
public @NotNull String getVersion() {
return "1.0.0";
}
@Override
public @Nullable String getDescription() {
return "Adds a Monokai Theme scheme.";
}
...
} |
Requirements:
- JDK 17 (recommended: OpenJDK)
- Recommended build system: Gradle
- Recommended IDE: Intellj Idea
Not available yet
For testing your plugins in action, you can run a test application instance easily.
Not available yet
If your plugin project doesn't include additional dependencies, you can use the basic gradle jar
task.
If your plugin requires dependencies, you might use an additional gradle plugin like Shadow for building a fat jar. But in this case you have to make sure that the fat jar doesn't include the Boomega (plugin-kit) binaries, because it might reduce performance when Boomega loads the plugin.
An alternative solution is to simply place the dependency jars also into the plugin directory.
Note: Don't include dependencies already present in Boomega itself.
You can view the dependencies used by Boomega in the acknowledgements.
Before we start, make sure you have read the language guide that helps you understand the basic concepts.
To make your LanguagePack recognized by Boomega you have to supply it in your LanguagePlugin implementation:
Kotlin | Java |
---|---|
class PortugueseLanguagePlugin : LanguagePlugin {
...
// Here you have to return your LanguagePack
override val languagePack get() = PortugueseLanguagePack()
} |
public class PortugueseLanguagePlugin implements LanguagePlugin {
...
@NotNull
@Override
public LanguagePack getLanguagePack() {
return new PortugueseLanguagePack();
}
} |
Before we start, make sure you have read the theme guide that helps you understand the basic concepts.
To make Boomega recognize your theme, you have to implement
the ThemePlugin
interface and provide your previously
created Theme.
Kotlin | Java |
---|---|
class NordThemePlugin : ThemePlugin {
...
// Here, you have to return your instantiated theme
override val theme get() = NordTheme()
} |
public class NordThemePlugin implements ThemePlugin {
...
@NotNull
@Override
public Theme getTheme() {
// Here, you have to return your instantiated theme
return new NordTheme();
}
} |
Read the ui module guide before you go forward.
To make Boomega recognize the plugin, you have to implement the ModulePlugin
interface
where you supply your newly created Module:
Kotlin | Java |
---|---|
class HelloModule : ModulePlugin {
// Here you have to supply your module's instance
override fun getModule(context: Context, database: Database): Module = HelloModule()
} |
public class HelloModule extends ModulePlugin {
@NotNull
@Override
public Module getModule(@NotNull Context context, @NotNull Database database) {
// Here you have to supply your module's instance
return new HelloModule();
}
} |
You might have noticed that the getModule
method takes two arguments:
- context:
Context
- you can use it for interacting with the UI (making alerts, notifications, etc..) - database:
Database
- the object can be used to communicate with the opened database; might be just read-only
If your module doesn't need these, you can simply ignore them.
Read the record export guide before you go forward.
If you want to add your record-exporter through a plugin, you have to implement the RecordExporterPlugin interface.
Look at the txt-table-export-plugin, a record export plugin allows to export records into text tables.
Read the databases guide before you continue.
Documentation in progress