- Scilab Help
- Java from Scilab
- Getting started - Beginning
- Getting started - Second step
- jallowClassReloading
- jarray
- jautoTranspose
- jautoUnwrap
- jcast
- jcompile
- jcreatejar
- jdeff
- jdisableTrace
- jenableTrace
- jexists
- jgetclassname
- jgetfield
- jgetfields
- jgetinfo
- jgetmethods
- jimport
- jinvoke
- jinvoke_db
- jnewInstance
- jnull
- jremove
- jsetfield
- junwrap
- junwraprem
- jvoid
- jwrap
- jwrapinchar
- jwrapinfloat
- new
Please note that the recommended version of Scilab is 2025.0.0. This page might be outdated.
See the recommended documentation of this function
Getting started - Second step
How to use the Java Scilab binding?
Description
This tutorial follows the First step.
Example 3: Working with Java objects in Scilab
For this example, we define a set of higher abstraction Java objects. Then we will use Scilab as a sort of Java scripting language apply various operations on these objects. A wide variation of Java functionality will be showcased such as; static methods (Factory construct), Enums, simple polymorphism, and scope of members/methods.
This wide variety of functionality will be demonstrated using a set of 7 simple classes that describe a simple house;
// Save under the name House.java package com.foo; import java.util.Arrays; import java.util.LinkendList; import java.util.List; public class House { private Color color; private Door door; private List<IWindow> windows = new LinkendList<IWindow>(); public House(Color color, Door door, IWindow... windows) { this.color = color; this.door = door; this.windows.addAll(Arrays.asList(windows)); } public void repaint() { swapDoorHouseColor(); } private void swapDoorHouseColor() { Color doorColor = door.getColor(); door.repaint(color); color = doorColor; } public void addWindow(IWindow window) { windows.add(window); } public void replaceDoor(Door newDoor) { this.door = newDoor; } @Override public String toString() { return String.format( "This is a house painted in %s, has a %s door, and %d windows", color.getDescr(), door.getColor().getDescr(), windows.size()); } }
package com.foo; public class HouseFactory { public static House basicHouse() { Door door = new Door(Color.WHITE); IWindow window = new RectangularWindow(2, 0.8); return new House(Color.WHITE, door, window); } public static House flashyHouse() { Door door = new Door(Color.random()); IWindow window = new CircularWindow(1.2); return new House(Color.random(), door, window); } }
package com.foo; import java.util.Random; public enum Color { BLACK("black"), BLUE("blue"), BROWN("brown"), GREEN("green"), ORANGE("orange"), RED("red"), WHITE("white"), YELLOW("yellow"); public String descr; private Color(String s) { descr = s; } public String getDescr() { return descr; } public static Color random() { Color[] allColors = values(); return allColors[new Random().nextInt(values().length)]; } }
package com.foo; public class Door { private Color color; public Door(Color color) { this.color = color; } public Color getColor() { return color; } public void repaint(Color newColor) { color = newColor; } }
package com.foo; public interface IWindow { double getWindowArea(); }
package com.foo; public class RectangularWindow implements IWindow { double length; double width; public RectangularWindow(double length, double width) { this.length = length; this.width = width; } public double getWindowArea() { return length * width; } }
package com.foo; public class CircularWindow implements IWindow { double radius; public CircularWindow(double radius) { this.radius = radius; } public double getWindowArea() { return Math.PI * radius * radius; } }
// The examples are shipped in the Scilab distribution. directory=SCI+"/modules/external_objects_java/examples/com/foo/" // Compile of all them jcompile(ls(directory + "/*.java"))
First, let's construct a basic factory house. For this, the HouseFactory should be imported and the static method basicHouse() should be invoked.
--> jimport("com.foo.HouseFactory") --> house = HouseFactory.basicHouse() house = This is a house painted in white, has a white door, and 1 windows
This shows that static methods can be called as one would in Java. Also keep in mind that this is equivalent to "jinvoke(HouseFactory, 'basicHouse')" Also the message of the object has changed from something like:
com.foo.House@ae8022 To This is a house painted in white, has a white door, and 1 windows
toString
is used to generate this representation.
We can still get the actual type (class) of our House object by invoking
jgetclassname
--> jgetclassname(house) ans = com.foo.House
addWindow(IWindow)
. IWindow
is an
abstract description of what a window should be and cannot be instantiated directly.
There are however two implementations available that we can construct;
RectangularWindow
and CircularWindow
.
Since the house starts with a RectangularWindow
from the factory,
a new CircularWindow
shall be made.
--> jimport("com.foo.IWindow") --> IWindow.new() !--error 999 Method invocation: An error occurred: Exception when calling Java method : No such constructor in the class com.foo.IWindow. --> jimport("com.foo.CircularWindow") --> newWindow = CircularWindow.new(0.5) newWindow = com.foo.CircularWindow@3e389405 --> house.addWindow(newWindow); --> house house = This is a house painted in white, has a white door, and 2 windows
A new window was made, and it's reference stored in the "newWindow" variable. Next, the window was directly added to the house, without any need to wrap the variable. It basically works as one would expect it to work. Finally, we notice that our house now has 2 windows.
However, we don't like the door, so let's change the door. To create a door, a color for that door needs to be picked. Color is of the Java Enum class type. Again as before, first the required variables need to be imported, new instances created and then the door of the house needs to be swapped out.
--> jimport("com.foo.Color") --> jimport("com.foo.Door") --> newDoor = Door.new(Color.RED) newDoor = com.foo.Door@54a5f709 --> house.replaceDoor(newDoor); --> house house = This is a house painted in white, has a red door, and 2 windows
Using Enum types is as straightforward as using classes! Their methods and members are subject to the same principles:
--> c = Color.random() c = BLACK --> c = Color.random() c = BLUE --> c.getDescr() ans = blue
The list of windows kept by that house is of type IWindow
.
From this it follows that under normal circumstances only windows may be added to the list.
To test this, let's see what happens when a Door
is added in Scilab.
--> house.addWindow(newDoor); !--error 999 Method invocation: An error occurred: Exception when calling Java method : No method addWindow in the class com.foo.House or bad arguments type.
The same as using Java Reflection, the JVM security measures prevent us from disobeying the Java polymorthism rules. The same goes for private methods and members.
--> c.descr ans = blue --> house.door !--error 999 %_EObj_e: An error occurred: Exception when calling Java method : Invalid field door --> house.repaint(); --> house house = This is a house painted in red, has a white door, and 2 windows --> house.swapDoorHouseColor() !--error 999 %_EObj_e: An error occurred: Exception when calling Java method : Invalid field swapDoorHouseColor
Concluding, the JIMS package does the job of hiding the Java JNI interface with Scilab, and make it very clear and transparent to use Java libraries under Scilab. All the normal JVM functionality is present and the Scilab syntax is clear and natural to use.
From this point you should understand how to interface Scilab and Java libraries, utilize the full power of Java under the Scilab scripting environment.
History
Version | Description |
5.5.0 | Function introduced. Based on the 'JIMS' module. The main difference in the behavior compared to the JIMS module is that jautoUnwrap is enabled by default. |
Report an issue | ||
<< Getting started - Beginning | Java from Scilab | jallowClassReloading >> |