daJLab
With new LEGO devices, daJLab became a core project to provide common resources for JControlLab (Control Lab Interface project), JToyPad (LEGO Dimensions toypad project) and JPowUp (PoweredUp project).
DaJLab's main purpose is to be a platform for graphical applications with easy integration.
Check out the related projects for more information about them.
Installation
Requirements
- Latest version of Java 1.8 or greater
Download
Download the following archive and add jars to your classpath.
dajlab-core-0.0.1.zip (2.9 Mo)
Or use the following Maven artifact:
<dependency>
<groupId>org.dajlab</groupId>
<artifactId>dajlab-core</artifactId>
<version>0.0.1</version>
</dependency>
API Tutorial
Caution: API may change with time with the inclusion of new features.
DaJLab API allows you to extend the Graphical User Interface. GUI uses JavaFX.
DaJLab applications may be extended by three ways:
- Menu bar extension : to add menus or items to the menu bar
- Tab extension : to add tabs
- Controller extension : to add control over model
The complete source code of this tutorial is available in the source code of the project.
Create a new application
Let's create an new application which extends AbstractDajlabApplication.
public class SimpleApplication extends AbstractDajlabApplication {
/**
* Constructor.
*/
public SimpleApplication() {
}
/**
* {@inheritDoc}
*/
@Override
public AbstractDajlabTab selectDefaultTab(AbstractDajlabTab[] tabsList) {
//Allow to select the default tab. Null is accepted.
return null;
}
/**
* Main application.
*
* @param args
* args
*/
public static void main(String[] args) {
// We start the application SimpleApplication called "My simple app"
startApplication(SimpleApplication.class, "My simple app");
}
}
The model
Now, the model. The model implements DajlabModelInterface. For this example, it contains one boolean property and a title.
public class SimpleModel implements DajlabModelInterface {
/**
* Simple check boolean.
*/
private BooleanProperty simpleCheck = new SimpleBooleanProperty();
/**
* Tab title.
*/
private StringProperty tabTitle = new SimpleStringProperty("My simple tab");
...
// JavaFX getters/setters
}
The view
After the model, let's create the view to display the model. The tab extends AbstractDajlabTab. It contains one checkbox bound to the model boolean property. The tab title is bound to the model title.
The updateTitle inherited method must be implemented only if you set the enableRenaming method from the AbstractDajlabTab. This method allows you to rename a tab title with a double-click.
public class SimpleTab extends AbstractDajlabTab {
/**
* Model.
*/
private SimpleModel model;
/**
* Constructor.
*
* @param model
* model
*/
public SimpleTab(final SimpleModel model) {
this.model = model;
textProperty().bind(model.tabTitleProperty());
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.add(new Text("My simple panel"), 0, 0);
CheckBox cb = new CheckBox("A simple check box");
cb.selectedProperty().bindBidirectional(model.simpleCheckProperty());
grid.add(cb, 0, 1);
setContent(grid);
}
/**
*
* {@inheritDoc}
*/
@Override
public void updateTitle(String title) {
// As the model is bound to the tab title, updating directly the model
// is enough.
model.setTabTitle(title);
}
}
The controller
After model and view, the controller. The controller implements DajlabControllerExtensionInterface parameterized with the model class. In this example, the controllers implements also TabExtensionInterface to interract with the view.
public class SimpleController implements TabExtensionInterface, DajlabControllerExtensionInterface< SimpleModel> {
/**
* Model.
*/
private SimpleModel myModel = new SimpleModel();
/**
* {@inheritDoc}
*/
@Override
public List< AbstractDajlabTab> getTabs() {
// Create one simple tab
SimpleTab simpleTab1 = new SimpleTab(myModel);
simpleTab1.setClosable(false);
simpleTab1.enableRenaming(null);
List< AbstractDajlabTab> list = new ArrayList<>();
list.add(simpleTab1);
return list;
}
/**
* {@inheritDoc}
*/
@Override
public void connect() {
// Nothing to do
}
/**
* {@inheritDoc}
*/
@Override
public void disconnect() {
// Nothing to disconnect
}
/**
* {@inheritDoc}
*/
@Override
public SimpleModel getModel() {
return myModel;
}
/**
* {@inheritDoc}
*/
@Override
public void updateModel(SimpleModel model) {
if (model != null) {
myModel.setSimpleCheck(model.isSimpleCheck());
myModel.setTabTitle(model.getTabTitle());
}
}
/**
* {@inheritDoc}
*/
@Override
public String getLocalization() {
return null;
}
}
The menu bar
We can add items to the File menu or to the About menu, and also create new menus. The class must implement MenuExtensionInterface.
In this example, we just add an extra item in the About menu to open an information box.
public class SimpleMenu implements MenuExtensionInterface {
/**
* {@inheritDoc}
*/
@Override
public Collection< MenuItem> getFileItems() {
// no extra file items.
return null;
}
/**
* {@inheritDoc}
*/
@Override
public Collection< MenuItem> getAboutItems() {
// We add an item which open an alert.
List< MenuItem> lists = new ArrayList<>();
MenuItem item = new MenuItem("A simple item");
item.setOnAction(e -> {
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Simple alert");
alert.setHeaderText("Simple header");
alert.setContentText("Simple content");
alert.showAndWait();
});
lists.add(item);
return lists;
}
/**
* {@inheritDoc}
*/
@Override
public Collection< Menu> getMenus() {
// no extra menus
return null;
}
}
Back to the Application
We have all our classes, just complete the application.
public SimpleApplication() {
// Create the controller.
SimpleController simpleController = new SimpleController();
// Register the controller.
registerPlugin(simpleController);
// Create a menu. In this example, the menu is separated from the
// controller, but the controller may implements MenuExtensionInterface
// too.
SimpleMenu simpleMenu = new SimpleMenu();
// Register the menu.
registerPlugin(simpleMenu);
}
/**
* {@inheritDoc}
*/
@Override
public AbstractDajlabTab selectDefaultTab(AbstractDajlabTab[] tabsList) {
// Select the last tab
if (tabsList.length > 0) {
return tabsList[tabsList.length - 1];
} else {
return null;
}
}
The result
Start the application.
Simple use case:
- Check the box, rename the tab title (double-click on the icon of the tab).
- Save the settings (menu File > Save as...)
- Restart the application
- Load the settings (menu File > Open...). See how the previous path is kept.
- The box and the title are updated.
Localization
If you want to localize your application, daJLab offers basic tools for that:
- Create a directory named "messages" in your classpath (into "resources" for a standard Maven project). Create the properties file projectname_messages.properties or projectname_messages_country.properties. Implement getLocalization() method of the controller by returning projectname.
- Then, to access to the messages, call the static methods MessagesUtil.getString(final String key) or MessagesUtil.getString(final String key, final Object... params)
- Caution: in the properties file, the key must not start with projectname. But when calling getString, the key must start with projectname followed by a dot.
myKey=A value to display: {0}
MessagesUtil.getString("SimpleApplication.myKey", aValue);
@Override
public String getLocalization() {
return "SimpleApplication";
}
When create an application?
Let's imagine... You built a big LEGO creation (aka a MOC) with 2 or 3 ToyPads from LEGO Dimensions and maybe one Control Lab Interface to control motors or interract with sensors. Now, you need a GUI with buttons to start sequences (of lights or motors) you wrote thanks to the APIs. Just implement a new tab with the buttons and a new controller to listen to these buttons and interact with the others controllers. Look at the following simple example.
public class MocApplication extends AbstractDajlabApplication {
public MocApplication() {
// My MOC uses one Control Lab Interface, I need JControlLabController from JControlLab API
JControlLabController controlLabController = new JControlLabController();
registerPlugin(controlLabController);
// My MOC uses 2 ToyPads, I need JToyPadController from JToyPad API
JToyPadController jtoyPadController = new JToyPadController();
registerPlugin(jtoyPadController);
// My MOC requires some buttons to start sequences, I write dedicated Tab and Controller
MocController mocController = new MocController(controlLabController, jtoyPadController);
registerPlugin(mocController);
}
@Override
public AbstractDajlabTab selectDefaultTab(AbstractDajlabTab[] tabsList) {
// Select the tab for my MOC
return tabsList[tabsList.length - 1];
}
public static void main(String[] args) {
startApplication(MocApplication.class, "My Own Creation");
}
}
Translation
All daJLab projects are translated into french and english. If you want to add translations for other languages, just submit translated version of the file projectname_messages_country.properties contained into each jar.