Motivation: I have a periodic call to server to supply fresh data to user. But my program can be run in multiply tabs. I want to decrease the load on the server by detecting which tab is active. If I can reach the state direcly or put the state of visibility of the tab to a variable, my periodic code can check that variable and decide not to call server.
Javascript code: I have found relevant code on javascipt at here
document.addEventListener("visibilitychange", () => {
var tabIsVisible = !document.hidden;
console.log("tabIsVisible: " + tabIsVisible);
});
In GWT I can rewrite the code as this
public static native void addEventListener_visibilityChange(){
$doc.addEventListener("visibilitychange", () => {
var tabIsVisible = !document.hidden;
console.log("tabIsVisible: " + tabIsVisible);
});
}
But it gives compile error
Compiling module com.tugalsan.app.table.App
Tracing compile failure path for type 'com.tugalsan.api.gui.client.browser.TGC_BrowserTabUtils'
[ERROR] Errors in 'jar:file:/C:/Users/me/.m2/repository/com/tugalsan/com.tugalsan.api.gui/1.0-SNAPSHOT/com.tugalsan.api.gui-1.0-SNAPSHOT.jar!/com/tugalsan/api/gui/client/browser/TGC_BrowserTabUtils.java'
[ERROR] Line 8: syntax error
> $doc.addEventListener("visibilitychange", () => {
And, how can I even reach the tabIsVisible variable?
The =>
arrow syntax is not supported in JSNI. That said, JSNI is discouraged for the last 10 or so years, prefer JsInterop instead.
Javascript event handling like this translates pretty easily to JsInterop with Java 8+ syntax. I'm also going to assume you have elemental2-dom
in your project, a set of bindings to DOM apis that the browser provides. With one import for elemental2.dom.DomGlobal
we can now write
DomGlobal.document.addEventListener("visibilitychange", event -> {
// most coding styles prefer boolean over var:
var tabIsVisible = !DomGlobal.document.hidden;
DomGlobal.console.log("tabIsVisible: " + tabIsVisible);
});
The only differences are:
DomGlobal.
prefix for document
and console
- technically these are optional, since you could add static imports for those two fields, but many company code standards discourage that.=>
JS token needs to be changed to Java's ->
.event
parameter for the lambda but be explicitly declared, even though it isn't used.Technically you can keep var
and not use boolean
, but many coding styles prefer being more specific in simple cases like this. I like to stick with var
for the first pass of translating from JS to Java, but will usually replace with types before committing any code.