- Calling Java from JavaScript
- Setting up the project
- Creating an empty web page
- Calling JavaScript
- Calling Java
- What’s next?
- How to call Java applet’s methods and variables from Javascript
- 1. Javascript call Java Applet Quick Example
- 2. Invoking Java applet’s methods
- 3. Accessing Java applet’s variables
- About the Author:
- Add comment
- Comments
Calling Java from JavaScript
In this step-by-step tutorial, you will learn how to use Vaadin to call server-side Java code from client-side JavaScript code. All you need to follow this tutorial is a basic understanding of the Java Programming Language, the fundamentals of JavaScript, JDK 8 or later, and a Java IDE.
Typically, applications make server-side Java methods available to the client side by exposing them as endpoints in a REST web service. Although this is a perfectly valid approach, this tutorial shows an alternative way to call Java methods on the server without having to implement web services. This is possible thanks to Vaadin, a framework that incorporates a set of Java classes that allows you to build web UIs in plain Java and includes an automated communication mechanism that makes calling Java methods from JavaScript straightforward.
Although in Vaadin applications, you typically don’t need to think about client-server communication at all, this lower-level functionality will be handy when integrating to existing JS features or building custom components.
You can find the source code for this tutorial on GitHub.
Setting up the project
- Download a “Plain Java” hello world starter template. Alternatively, you can pick any of the other hello world templates, but you might need to adapt a bit.
- The ZIP contains a Maven project. Import the project into your favorite IDE (see the instructions).
- The starter creates a simple «Hello, World» application we don’t need right now. We want to keep the project as simple as possible, so go ahead and delete all Java files and the resources, frontend/src, and frontend/styles directories (keep the frontend directory).
Now we have a clean starting point with no distracting code. Let’s start hacking!
Creating an empty web page
Java web applications are implemented through Servlets. A Servlet is a class that enhances the functionality of a web server (which usually only serves files such as HTML documents and images). This enhancement could include server-side logic, for example, dynamically creating an HTML document to include content from a database. When you include Vaadin in your project, a VaadinServlet is automatically created for you. This servlet allows us to create a web page using pure Java.
To see this in action, create a new class with the name MainView inside the com.example package:
packagecom.example; public class MainView
We want to expose this class as a web page in the browser. Since we have Vaadin in our project and it creates a VaadinServlet all we need to do is annotate the previous class with @Route and make it extend a UI component such as Div. Also, add an H1 component into the Div with some text so that you get something else than an empty screen:
import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.H1; import com.vaadin.flow.router.Route; @Route public class MainView extends Div < public MainView() < add(new H1("It works!")); >>
By default, the @Route annotation makes Vaadin map the class with the context root when the annotated class is named MainView . So when http://localhost:8080/ is requested, the MainView class will have the chance to perform any logic on the server side. If we wanted to map the class, we would need to say it explicitly with @Route(«example») .
If you run the project at this point, you will get an empty web page. Let’s confirm this by executing the Maven Jetty Plugin. If you have Maven installed in your machine, just run mvn jetty:run in the command line. If you are using an IDE, create a run configuration for the jetty:run goal. See the detailed instructions for IntelliJ IDEA, Eclipse, and NetBeans.
The Jetty Maven Plugin is configured in the pom.xml file. This plugin allows us to easily deploy the web application to a Jetty server without having to install it manually.
Point your browser to http://localhost:8080 to see the empty web page. Nothing exciting just yet, but you have a running Java web application ready.
Calling JavaScript
Although Vaadin allows you to execute JavaScript directly from the Java code, it is often better to create a separate JavaScript file. Create a new file with the name script.js in the frontend/directory and code a simple function in it:
window.greet = function greet(name, element)
To get the greet function defined in the browser window, we need to import this file in the Java class. Annotate the MainView class with @JavaScript as follows:
@JavaScript("./script.js") @Route public class MainView extends Div < public MainView() < add(new H1("It works!")); >>
The frontend directory is used as the default directory for static resources.
With the JavaScript file loaded, we can call the greet function in the constructor as follows:
public MainView() < add(new H1("It works!")); callJsMethodInTheBrowser(); >private void callJsMethodInTheBrowser()
The getElement() method returns a Java representation of the element in the DOM. There is a small improvement we can make to this line of code. We can separate the argument values from the function call and get the same behavior:
Try the application now. Stop the server and rerun it (using the run configuration in your IDE or mvn jetty:run in the command line).
If you right-click your browser and choose Inspect Element , you should see the greeting in the browser’s console:
Calling Java
Now that Java to JavaScript is working let’s complete the circle by calling a Java method from a JavaScript function. First, we need a Java method. Let’s implement a server-side Java version of a greeting by adding the following to the MainView class:
public class MainView extends Div < . public void greet(String name) < System.out.println("Hi, " + name); >>
By default, all methods are safely inaccessible from the client-side and only exist in the JVM. However, to build integrations with native browser technology, we may need to expose some. We just need to pay extra attention to data handling, as this escapes the secure default development model of Vaadin. To make the greet method in the JVM available for the client-side, annotate it with @ClientCallable :
@ClientCallable public void greet(String name)
The DOM element of the corresponding Java component now has a proxy to the actual Java method. We need the reference that the Java getElement() method returns to invoke it from the client side. We can send it to the JavaScript function by modifying the callJsMethodInTheBrowser method as follows:
private void callJsMethodInTheBrowser()
Notice how we added the argument to the function call ( $1 ) and how we added the actual value as an extra argument in the call to the executeJavaScript method.
Now we can accept this value in the client-side JavaScript by adding a parameter to the greet function in the JS file as follows:
window.greet = function greet(name, element)
The element object includes a $server member that we can use to call the server-side Java greet method. Here’s how:
window.greet = function greet(name, element)
Restart the Jetty server again and try the application to see the greeting in the server’s log:
What’s next?
So, the circle is closed–we called JavaScript from Java and Java from JavaScript without using REST Web Services. If you follow this tutorial, you might already have ideas on what to try next. You might want to try adding some CSS (you can do it with something like @StyleSheet(«frontend://styles.css»)) , or you might want to add your own JavaScript and Java business logic.
However, Vaadin is much more than a library to connect JavaScript with Java. As you can imagine, Vaadin’s automated communication mechanism can be used to generate powerful web user interfaces. Well, Vaadin allows you to do so in pure Java! For example, try modifying the MainView class to the following:
@Route public class MainView extends Div < public MainView() < Button button = new Button("Greet"); button.addClickListener(event ->< LocalTime now = LocalTime.now(); Notification.show("Hi! The time in the server is " + now); >); add(button); > >
Without coding any JavaScript at all, you get this HTML-based web application in the browser:
If you want to learn more about this, try this tutorial next!
How to call Java applet’s methods and variables from Javascript
Javascript can talk to Java applet in the same HTML page through LiveConnect technology. We can write Javascript code to invoke methods (including arguments) and access objects which are exposed by the applet. Here are the rules:
returnValue = AppletID.appletMethod(arg1, arg2, …)
returnValue = AppletID.publicVar
returnValue = AppletID.publicVar.publicMethod(arg1, arg2, …)
Where AppletID is the id attribute of the tag:
-
- Javascript code can access only public methods and variables.
- Both static or instance methods/variables can be accessed.
1. Javascript call Java Applet Quick Example
Following is a pretty simple example that demonstrates invoking a Java applet’s method from Javascript code. Here is code of the applet ( QuickApplet.java ):
import java.awt.*; import javax.swing.*; public class QuickApplet extends JApplet < private JLabel label = new JLabel("This is a Java applet"); public void init() < setLayout(new FlowLayout()); label.setFont(new Font("Arial", Font.BOLD, 18)); label.setForeground(Color.RED); add(label); >public void drawText(String text) < label.setText(text); >>
This applet shows only label and declare a public method drawText(String) which updates the label’s text.
Here is code of the HTML page ( QuickAppletTest.html ):
This HTML page embeds the above applet and displays a button which will invoke the applet’s method when clicked. The Javascript method callApplet() invokes the drawText() method of the applet and passes a time string as an argument. The applet, in turn, updates the label’s text by the string passed from Javascript code. Here is a screenshot of the page:
2. Invoking Java applet’s methods
-
- Because variables in Javascript are untyped, so they will be converted to Java equivalents based on signature of Java methods.
- Return values from Java methods are converted to closest Javascript equivalents (for primitive types) or Javascript wrapper object (for Object types).
public int sum(int x, int y)
var sum = sampleApplet.sum(10, 20);
public String changeCase(String text)
var returnText = sampleApplet.changeCase("code java");
var returnText = sampleApplet.changeCase(123456);
public boolean toggleVisible(boolean visible)
var booleanReturn = sampleApplet.toggleVisible(true);
var booleanReturn = sampleApplet.toggleVisible(""); // return true var booleanReturn = sampleApplet.toggleVisible("visible"); // return false
public int sum(int[] numbers) < int sum = 0; for (int i = 0 ; i < numbers.length; i++) < sum += numbers[i]; >return sum; >
var numbers = new Array(); numbers[0] = 10; numbers[1] = 20; numbers[2] = 30; var sum = sampleApplet.sum(numbers);
3. Accessing Java applet’s variables
Javascript code can access only public variables (both instance and static) declared in the applet. If the variable is of type Object, we can invoke methods on the returned object (and pass arguments) like the above section.
- Access primitive variables:Code in Java applet:
var email = sampleApplet.email; email = email.substring(5, 18); email = "info@codejava.net"; email = email.toUpperCase();
In this example, we obtain a String object from the applet and call String’s substring(int, int) and toUpperCase() methods. The similar can be applied for other Object types.
Other Java Applet Tutorials:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.
Add comment
Comments
Hi,
It’s 2015 and I’m still trying to embed a java applet! There doesn’t seem to be a lot of expertise out there these days (or nobody wants to admit to knowing).Everything seems to work, expect occasionally, under certain circumstance a call into the applet does not return in a timely fashion and causes the entire browser to hang. is there a way to get the call to throw an exception after some time if it does not a response?