getMapDivCssClass() {
throw new Error("Abstract method");
}
+
+ newObject(js) {
+ const func = new Function(js);
+ return (func());
+ }
}
+++ /dev/null
-
-import WMTS from 'ol/source/WMTS.js';
-import WMTSTileGrid from 'ol/tilegrid/WMTS';
-import { getTopLeft } from 'ol/extent';
-import { getWidth } from 'ol/extent';
-import { get as getProjection } from 'ol/proj';
-
-export class SentinelCloudless extends WMTS {
- static source_s2CL2019;
- static EPSG4326 = getProjection('EPSG:4326');
-
- static resolutions;
- static matrixIds;
-
- static {
- let min_zoom = 6;
- let max_zoom = 17;
- let zoomOffset = 1;
-
- // from https://s2maps.eu/
- let size = getWidth(this.EPSG4326.getExtent()) / 512;
- this.resolutions = new Array(max_zoom + zoomOffset);
- this.matrixIds = new Array(max_zoom + zoomOffset);
- for (let z = min_zoom; z <= max_zoom; ++z) {
- // generate resolutions and matrixIds arrays for this WMTS
- this.resolutions[z] = size / Math.pow(2, z);
- this.matrixIds[z] = z;
- }
- }
-
- constructor() {
- super({
- urls: [
- "//a.s2maps-tiles.eu/wmts/",
- "//b.s2maps-tiles.eu/wmts/",
- "//c.s2maps-tiles.eu/wmts/",
- "//d.s2maps-tiles.eu/wmts/",
- "//e.s2maps-tiles.eu/wmts/"
- ],
- layer: 's2cloudless-2021',
- matrixSet: 'WGS84',
- format: 'image/jpeg',
- projection: SentinelCloudless.EPSG4326,
- tileGrid: new WMTSTileGrid({
- origin: getTopLeft(SentinelCloudless.EPSG4326.getExtent()),
- resolutions: SentinelCloudless.resolutions,
- matrixIds: SentinelCloudless.matrixIds,
- }),
- style: 'default',
- transition: 0,
- wrapX: true
- });
- }
-}
\ No newline at end of file
import * as SLDReader from '@nieuwlandgeo/sldreader';
import MapPart from './MapPart.js';
-import { SentinelCloudless } from './OpenLayerTileSources.js';
/** OpenLayers implementation of MapPart. */
export default class OpenLayersMapPart extends MapPart {
// new TileLayer({
// source: new SentinelCloudless(),
// }),
- new TileLayer({
- source: new OSM(),
- opacity: 0.4,
- transition: 0,
- }),
+// new TileLayer({
+// source: new OSM(),
+// opacity: 0.4,
+// transition: 0,
+// }),
],
+// view: new View({
+// center: [0, 0],
+// zoom: 2,
+// }),
target: this.getMapName(),
});
}
this.#map.addLayer(vectorLayer);
}
+ addLayer(js) {
+ const func = new Function(js);
+ const layer = (func)();
+ this.#map.addLayer(layer);
+ }
+
+ getMap() {
+ return this.#map;
+ }
/* CALLBACKS */
enableFeatureSingleClick() {
--- /dev/null
+
+import WMTS from 'ol/source/WMTS.js';
+import WMTSTileGrid from 'ol/tilegrid/WMTS';
+import { getTopLeft } from 'ol/extent';
+import { getWidth } from 'ol/extent';
+import { get as getProjection } from 'ol/proj';
+
+export default class SentinelCloudless extends WMTS {
+ static source_s2CL2019;
+ static EPSG4326 = getProjection('EPSG:4326');
+
+ static resolutions;
+ static matrixIds;
+
+ static {
+ let min_zoom = 6;
+ let max_zoom = 17;
+ let zoomOffset = 1;
+
+ // from https://s2maps.eu/
+ let size = getWidth(this.EPSG4326.getExtent()) / 512;
+ this.resolutions = new Array(max_zoom + zoomOffset);
+ this.matrixIds = new Array(max_zoom + zoomOffset);
+ for (let z = min_zoom; z <= max_zoom; ++z) {
+ // generate resolutions and matrixIds arrays for this WMTS
+ this.resolutions[z] = size / Math.pow(2, z);
+ this.matrixIds[z] = z;
+ }
+ }
+
+ constructor() {
+ super({
+ urls: [
+ "//a.s2maps-tiles.eu/wmts/",
+ "//b.s2maps-tiles.eu/wmts/",
+ "//c.s2maps-tiles.eu/wmts/",
+ "//d.s2maps-tiles.eu/wmts/",
+ "//e.s2maps-tiles.eu/wmts/"
+ ],
+ layer: 's2cloudless-2021',
+ matrixSet: 'WGS84',
+ format: 'image/jpeg',
+ projection: SentinelCloudless.EPSG4326,
+ tileGrid: new WMTSTileGrid({
+ origin: getTopLeft(SentinelCloudless.EPSG4326.getExtent()),
+ resolutions: SentinelCloudless.resolutions,
+ matrixIds: SentinelCloudless.matrixIds,
+ }),
+ style: 'default',
+ transition: 0,
+ wrapX: true
+ });
+ }
+}
\ No newline at end of file
import OpenLayersMapPart from './OpenLayersMapPart.js';
+import SentinelCloudless from './SentinelCloudless.js';
+
+import Map from 'ol/Map.js';
+import View from 'ol/View.js';
+import OSM from 'ol/source/OSM.js';
+import TileLayer from 'ol/layer/Tile.js';
+import VectorSource from 'ol/source/Vector.js';
+import VectorLayer from 'ol/layer/Vector.js';
+import GeoJSON from 'ol/format/GeoJSON.js';
// PSEUDO PACKAGE
if (typeof globalThis.argeo === 'undefined')
if (typeof globalThis.argeo.app.geo === 'undefined')
globalThis.argeo.app.geo = {};
+// THIRD PARTY
+if (typeof globalThis.argeo.tp === 'undefined')
+ globalThis.argeo.tp = {};
+if (typeof globalThis.argeo.tp.ol === 'undefined')
+ globalThis.argeo.tp.ol = {};
+
// PUBLIC CLASSES
globalThis.argeo.app.geo.OpenLayersMapPart = OpenLayersMapPart;
+globalThis.argeo.app.geo.SentinelCloudless = SentinelCloudless;
+
+globalThis.argeo.tp.ol.Map = Map;
+globalThis.argeo.tp.ol.View = View;
+globalThis.argeo.tp.ol.TileLayer = TileLayer;
+globalThis.argeo.tp.ol.OSM = OSM;
+globalThis.argeo.tp.ol.VectorSource = VectorSource;
+globalThis.argeo.tp.ol.VectorLayer = VectorLayer;
+globalThis.argeo.tp.ol.GeoJSON = GeoJSON;
"use strict";
+
--- /dev/null
+package org.argeo.app.ux.js;
+
+import java.util.Optional;
+
+public abstract class AbstractJsObject {
+ /**
+ * JavaScript expression returning a reference to the object. It can be either a
+ * variable or a function call. If it is not set the object is assumed to be a
+ * new.
+ */
+ private String reference;
+
+ private JsClient jsClient;
+
+ private Object[] jsConstructorArgs;
+
+// public AbstractJsObject(JsClient jsClient, String reference) {
+// Objects.requireNonNull(jsClient);
+// Objects.requireNonNull(reference, "JS reference cannot be null");
+// this.jsClient = jsClient;
+// this.reference = reference;
+// }
+
+ public AbstractJsObject(Object... args) {
+ if (args.length == 2 && args[0] instanceof JsClient jsClient) {
+ this.jsClient = jsClient;
+ this.reference = args[1].toString();
+ } else {
+ this.jsConstructorArgs = args;
+ }
+ }
+
+ public abstract String getJsPackage();
+
+ public void create(JsClient jsClient, String varName) {
+ if (!isNew())
+ throw new IllegalStateException("JS object " + getJsClassName() + " is not new");
+ if (isFunctionReference())
+ throw new IllegalStateException(
+ "JS object " + getJsClassName() + " cannot be created since it is a function reference");
+ jsClient.execute(jsClient.getJsVarName(varName) + " = " + newJs() + ";");
+ reference = varName;
+ this.jsClient = jsClient;
+ }
+
+ public void delete() {
+ if (isNew())
+ throw new IllegalStateException(
+ "JS object " + getJsClassName() + " cannot be deleted since it is anonymous");
+ if (isFunctionReference())
+ throw new IllegalStateException(
+ "JS object " + getJsClassName() + " cannot be deleted since it is a function reference");
+ jsClient.execute(reference + " = undefined; delete " + reference + ";");
+ }
+
+ public boolean isNew() {
+ return reference == null;
+ }
+
+ public boolean isFunctionReference() {
+ return !isNew() && !getReference().endsWith(")");
+ }
+
+ public String getReference() {
+ return reference;
+ }
+
+ String getJsReference() {
+ return jsClient.getJsVarName(reference);
+ }
+
+ protected String newJs() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("new ");
+ sb.append(getJsClassName());
+ sb.append("(");
+ sb.append(JsClient.toJsArgs(jsConstructorArgs));
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public String getJsClassName() {
+ return getJsPackage() + "." + getClass().getSimpleName();
+ }
+
+ public Object callMethod(String methodName, Object... args) {
+ return jsClient.callMethod(getJsReference(), methodName + "(" + JsClient.toJsArgs(args) + ")");
+ }
+
+ public void executeMethod(String methodName, Object... args) {
+ jsClient.executeMethod(getJsReference(), methodName + "(" + JsClient.toJsArgs(args) + ")");
+ }
+
+ protected String getMethodName() {
+ StackWalker walker = StackWalker.getInstance();
+ Optional<String> methodName = walker.walk(frames -> {
+ return frames.skip(1).findFirst().map(StackWalker.StackFrame::getMethodName);
+ });
+ return methodName.orElseThrow();
+ }
+
+ protected JsClient getJsClient() {
+ return jsClient;
+ }
+
+ protected Object[] getJsConstructorArgs() {
+ return jsConstructorArgs;
+ }
+
+ protected void setJsConstructorArgs(Object[] jsConstructorArgs) {
+ this.jsConstructorArgs = jsConstructorArgs;
+ }
+
+}
--- /dev/null
+package org.argeo.app.ux.js;
+
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.Map;
+import java.util.StringJoiner;
+import java.util.function.Function;
+
+/**
+ * A remote JavaScript view (typically in a web browser) which is tightly
+ * integrated with a local UX part.
+ */
+public interface JsClient {
+
+ /*
+ * TO IMPLEMENT
+ */
+
+ /**
+ * Execute this JavaScript on the client side after making sure that the page
+ * has been loaded and the map object has been created.
+ *
+ * @param js the JavaScript code, possibly formatted according to
+ * {@link String#format}, with {@link Locale#ROOT} as locale (for
+ * stability of decimal separator, as expected by JavaScript.
+ * @param args the optional arguments of
+ * {@link String#format(String, Object...)}
+ */
+ Object evaluate(String js, Object... args);
+
+ /**
+ * Executes this JavaScript without expecting a return value.
+ *
+ * @param js the JavaScript code, possibly formatted according to
+ * {@link String#format}, with {@link Locale#ROOT} as locale (for
+ * stability of decimal separator, as expected by JavaScript.
+ * @param args the optional arguments of
+ * {@link String#format(String, Object...)}
+ */
+ void execute(String js, Object... args);
+
+ /** @return the globally usable function name. */
+ String createJsFunction(String name, Function<Object[], Object> toDo);
+
+ /** Get a global variable name. */
+ public String getJsVarName(String name);
+
+ /*
+ * DEFAULTS
+ */
+
+ default Object callMethod(String jsObject, String methodCall, Object... args) {
+ return evaluate(jsObject + '.' + methodCall, args);
+ }
+
+ default void executeMethod(String jsObject, String methodCall, Object... args) {
+ execute(jsObject + '.' + methodCall, args);
+ }
+
+ /*
+ * UTILITIES
+ */
+
+ static String toJsValue(Object o) {
+ if (o instanceof CharSequence)
+ return '\"' + o.toString() + '\"';
+ else if (o instanceof Number)
+ return o.toString();
+ else if (o instanceof Boolean)
+ return o.toString();
+ else if (o instanceof Map map)
+ return toJsMap(map);
+ else if (o instanceof Object[] arr)
+ return toJsArray(arr);
+ else if (o instanceof int[] arr)
+ return toJsArray(arr);
+ else if (o instanceof long[] arr)
+ return toJsArray(arr);
+ else if (o instanceof double[] arr)
+ return toJsArray(arr);
+ else if (o instanceof AbstractJsObject jsObject) {
+ if (jsObject.isNew())
+ return jsObject.newJs();
+ else
+ return jsObject.getJsReference();
+ } else
+ return '\"' + o.toString() + '\"';
+ }
+
+ static String toJsArgs(Object... arr) {
+ StringJoiner sj = new StringJoiner(",");
+ for (Object o : arr) {
+ sj.add(toJsValue(o));
+ }
+ return sj.toString();
+ }
+
+ static String toJsArray(Object... arr) {
+ StringJoiner sj = new StringJoiner(",", "[", "]");
+ for (Object o : arr) {
+ sj.add(toJsValue(o));
+ }
+ return sj.toString();
+ }
+
+ static String toJsArray(String... arr) {
+ return toJsArray((Object[]) arr);
+ }
+
+ static String toJsArray(double... arr) {
+ return Arrays.toString(arr);
+ }
+
+ static String toJsArray(long... arr) {
+ return Arrays.toString(arr);
+ }
+
+ static String toJsArray(int... arr) {
+ return Arrays.toString(arr);
+ }
+
+ static String toJsMap(Map<?, ?> map) {
+ StringJoiner sj = new StringJoiner(",", "{", "}");
+ // TODO escape forbidden characters
+ for (Object key : map.keySet()) {
+ sj.add("'" + key + "':" + toJsValue(map.get(key)));
+ }
+ return sj.toString();
+ }
+
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import org.argeo.app.ux.js.AbstractJsObject;
+
+public class AbstractGeoJsObject extends AbstractJsObject {
+ public AbstractGeoJsObject(Object... args) {
+ super(args);
+ }
+
+ @Override
+ public String getJsPackage() {
+ return "argeo.app.geo";
+ }
+
+}
/** Known JavaScript implementations for this package. */
public enum JsImplementation {
- OPENLAYERS_MAP_PART("globalThis.argeo.app.geo.OpenLayersMapPart");
+ OPENLAYERS_MAP_PART("argeo.app.geo.OpenLayersMapPart");
private String jsClass;
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import org.argeo.app.ol.OlMap;
+import org.argeo.app.ux.js.AbstractJsObject;
+import org.argeo.app.ux.js.JsClient;
+
+public class OpenLayersMapPart extends AbstractGeoJsObject {
+ private String mapPartName;
+
+ public OpenLayersMapPart(JsClient jsClient, String mapPartName) {
+ super(mapPartName);
+ this.mapPartName = mapPartName;
+ create(jsClient, mapPartName);
+ }
+
+ public OlMap getMap() {
+ return new OlMap(getJsClient(), getReference() + ".getMap()");
+ }
+}
--- /dev/null
+package org.argeo.app.geo.ux;
+
+import org.argeo.app.ol.Source;
+
+public class SentinelCloudless extends Source {
+
+ public SentinelCloudless(Object... args) {
+ super(args);
+ }
+
+ @Override
+ public String getJsPackage() {
+ return "argeo.app.geo";
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.argeo.app.ux.js.AbstractJsObject;
+
+public abstract class AbstractOlObject extends AbstractJsObject {
+
+ public AbstractOlObject(Object... args) {
+ super(args.length > 0 ? args : new Object[] { new HashMap<String, Object>() });
+ }
+
+ public AbstractOlObject(Map<String, Object> options) {
+ super(options);
+ }
+
+ public String getJsPackage() {
+ return "argeo.tp.ol";
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Map<String, Object> getNewOptions() {
+ if (!isNew())
+ throw new IllegalStateException("Object " + getJsClassName() + " is not new");
+ Object[] args = getJsConstructorArgs();
+ if (args.length != 1 || !(args[0] instanceof Map))
+ throw new IllegalStateException("Object " + getJsClassName() + " has no available options");
+ return (Map<String, Object>) args[0];
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+import java.util.Objects;
+
+public abstract class Layer extends AbstractOlObject {
+
+ public Layer(Object... args) {
+ super(args);
+ }
+
+ public void setOpacity(double opacity) {
+ if (opacity < 0 || opacity > 1)
+ throw new IllegalArgumentException("Opacity must be between 0 and 1");
+ if (isNew())
+ getNewOptions().put("opacity", opacity);
+ else
+ executeMethod(getMethodName(), opacity);
+ }
+
+ public void setSource(Source source) {
+ Objects.requireNonNull(source);
+ if (isNew())
+ getNewOptions().put("source", source);
+ else
+ executeMethod(getMethodName(), source);
+ }
+
+ public void setMinResolution(long minResolution) {
+ if (isNew())
+ getNewOptions().put("minResolution", minResolution);
+ else
+ executeMethod(getMethodName(), minResolution);
+ }
+
+ public void setMaxResolution(long maxResolution) {
+ if (isNew())
+ getNewOptions().put("maxResolution", maxResolution);
+ else
+ executeMethod(getMethodName(), maxResolution);
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class OSM extends Source {
+
+ public OSM(Object... args) {
+ super(args);
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class OlMap extends AbstractOlObject {
+
+ public OlMap(Object... args) {
+ super(args);
+ }
+
+ public void addLayer(Layer layer) {
+ executeMethod(getMethodName(), layer);
+ }
+
+ public View getView() {
+ return new View(getJsClient(), getReference() + ".getView()");
+ }
+
+ @Override
+ public String getJsClassName() {
+ return getJsPackage() + ".Map";
+ }
+
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class Source extends AbstractOlObject {
+
+ public Source(Object... args) {
+ super(args);
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class TileLayer extends Layer {
+ public TileLayer(Object... args) {
+ super(args);
+ }
+
+ public TileLayer(Source source) {
+ setSource(source);
+ }
+}
--- /dev/null
+package org.argeo.app.ol;
+
+public class View extends AbstractOlObject {
+ public View(Object... args) {
+ super(args);
+ }
+
+ public void setCenter(int[] coord) {
+ if (isNew())
+ getNewOptions().put("center", coord);
+ else
+ executeMethod(getMethodName(), new Object[] { coord });
+ }
+
+ public void setZoom(int zoom) {
+ if (isNew())
+ getNewOptions().put("zoom", zoom);
+ else
+ executeMethod(getMethodName(), zoom);
+ }
+}
package org.argeo.app.geo.swt;
import org.argeo.api.acr.Content;
+import org.argeo.app.geo.ux.OpenLayersMapPart;
+import org.argeo.app.geo.ux.SentinelCloudless;
+import org.argeo.app.ol.Layer;
+import org.argeo.app.ol.OSM;
+import org.argeo.app.ol.TileLayer;
+import org.argeo.app.swt.js.SwtBrowserJsPart;
+import org.argeo.app.ux.js.JsClient;
import org.argeo.cms.swt.acr.SwtUiProvider;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
@Override
public Control createUiPart(Composite parent, Content context) {
- SwtJsMapPart map = new SwtJsMapPart("defaultOverviewMap", parent, 0);
- map.setCenter(13.404954, 52.520008); // Berlin
-// map.setCenter(-74.00597, 40.71427); // NYC
-// map.addPoint(-74.00597, 40.71427, null);
- map.setZoom(6);
- // map.addUrlLayer("https://openlayers.org/en/v4.6.5/examples/data/geojson/countries.geojson",
- // Format.GEOJSON);
- return map.getControl();
+ JsClient jsClient = new SwtBrowserJsPart(parent, 0, "/pkg/org.argeo.app.js/geo.html");
+ OpenLayersMapPart mapPart = new OpenLayersMapPart(jsClient, "defaultOverviewMap");
+ mapPart.getMap().getView().setCenter(new int[] { 0, 0 });
+ mapPart.getMap().getView().setZoom(6);
+
+ Layer satelliteLayer = new TileLayer(new SentinelCloudless());
+ satelliteLayer.setMaxResolution(200);
+ mapPart.getMap().addLayer(satelliteLayer);
+ TileLayer baseLayer = new TileLayer();
+ baseLayer.setSource(new OSM());
+ baseLayer.setOpacity(0.5);
+ mapPart.getMap().addLayer(baseLayer);
+
+// SwtJsMapPart map = new SwtJsMapPart("defaultOverviewMap", parent, 0);
+// map.setCenter(13.404954, 52.520008); // Berlin
+//// map.setCenter(-74.00597, 40.71427); // NYC
+//// map.addPoint(-74.00597, 40.71427, null);
+// map.setZoom(6);
+// // map.addUrlLayer("https://openlayers.org/en/v4.6.5/examples/data/geojson/countries.geojson",
+// // Format.GEOJSON);
+ return parent;
}
}
executeMapMethod("addUrlLayer('%s', '%s', '%s', true)", url, format.name(), style);
}
+ public void addLayer() {
+ //executeMapMethod("addLayer(\"return new argeo.app.geo.TileLayer({source: new argeo.app.geo.OSM()})\")");
+ executeMapMethod("getMap().addLayer(new argeo.tp.ol.TileLayer({source: new argeo.tp.ol.OSM()}))");
+ }
+
@Override
public void setZoom(int zoom) {
executeMapMethod("setZoom(%d)", zoom);
import java.io.StringWriter;
+import org.argeo.app.ux.js.JsClient;
import org.eclipse.swt.widgets.Composite;
import jakarta.json.Json;
}
public void setLabels(String[] labels) {
- executeChartMethod("setLabels(%s)", toJsArray(labels));
+ executeChartMethod("setLabels(%s)", JsClient.toJsArray(labels));
}
public void addDataset(String label, int[] values) {
- executeChartMethod("addDataset('%s', %s)", label, toJsArray(values));
+ executeChartMethod("addDataset('%s', %s)", label, JsClient.toJsArray(values));
}
public void setData(String[] labels, String label, int[] values) {
- executeChartMethod("setData(%s, '%s', %s)", toJsArray(labels), label, toJsArray(values));
+ executeChartMethod("setData(%s, '%s', %s)", JsClient.toJsArray(labels), label, JsClient.toJsArray(values));
}
public void setDatasets(String[] labels, String[] label, int[][] values) {
- executeChartMethod("setDatasets(%s, %s)", toJsArray(labels), toDatasets(label, values));
+ executeChartMethod("setDatasets(%s, %s)", JsClient.toJsArray(labels), toDatasets(label, values));
}
protected String toDatasets(String[] label, int[][] values) {
package org.argeo.app.swt.js;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Locale;
-import java.util.StringJoiner;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import java.util.function.Supplier;
import org.argeo.api.cms.CmsLog;
+import org.argeo.app.ux.js.JsClient;
import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.BrowserFunction;
* A part using a {@link Browser} and remote JavaScript components on the client
* side.
*/
-public class SwtBrowserJsPart {
+public class SwtBrowserJsPart implements JsClient {
private final static CmsLog log = CmsLog.getLog(SwtBrowserJsPart.class);
private final static String GLOBAL_THIS_ = "globalThis.";
* JAVASCRIPT ACCESS
*/
- /**
- * Execute this JavaScript on the client side after making sure that the page
- * has been loaded and the map object has been created.
- *
- * @param js the JavaScript code, possibly formatted according to
- * {@link String#format}, with {@link Locale#ROOT} as locale (for
- * stability of decimal separator, as expected by JavaScript.
- * @param args the optional arguments of
- * {@link String#format(String, Object...)}
- */
- protected Object evaluate(String js, Object... args) {
+ @Override
+ public Object evaluate(String js, Object... args) {
assert browser.getDisplay().equals(Display.findDisplay(Thread.currentThread())) : "Not the proper UI thread.";
if (!readyStage.isDone())
throw new IllegalStateException("Methods returning a result can only be called after UI initilaisation.");
return result;
}
- protected void execute(String js, Object... args) {
+ @Override
+ public void execute(String js, Object... args) {
if (readyStage.isDone()) {
boolean success = browser.execute(String.format(Locale.ROOT, js, args));
if (!success)
}
}
- /** @return the globally usable function name. */
- protected String createJsFunction(String name, Function<Object[], Object> toDo) {
+ @Override
+ public String createJsFunction(String name, Function<Object[], Object> toDo) {
// browser functions must be directly on window (RAP specific)
new BrowserFunction(browser, name) {
browser.execute(String.format(Locale.ROOT, js, args));
}
- protected Object callMethod(String jsObject, String methodCall, Object... args) {
- return evaluate(jsObject + '.' + methodCall, args);
- }
-
- protected void executeMethod(String jsObject, String methodCall, Object... args) {
- execute(jsObject + '.' + methodCall, args);
- }
-
- protected String getJsVarName(String name) {
+ @Override
+ public String getJsVarName(String name) {
return GLOBAL_THIS_ + name;
}
- protected static String toJsArray(int... arr) {
- return Arrays.toString(arr);
- }
-
- protected static String toJsArray(long... arr) {
- return Arrays.toString(arr);
- }
-
- protected static String toJsArray(double... arr) {
- return Arrays.toString(arr);
- }
-
- protected static String toJsArray(String... arr) {
- return toJsArray((Object[]) arr);
- }
-
- protected static String toJsArray(Object... arr) {
- StringJoiner sj = new StringJoiner(",", "[", "]");
- for (Object o : arr) {
- sj.add(toJsValue(o));
- }
- return sj.toString();
- }
-
- protected static String toJsValue(Object o) {
- if (o instanceof CharSequence)
- return '\"' + o.toString() + '\"';
- else if (o instanceof Number)
- return o.toString();
- else if (o instanceof Boolean)
- return o.toString();
- else
- return '\"' + o.toString() + '\"';
- }
-
/*
* ACCESSORS
*/
import org.argeo.cms.util.LangUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
} else {
if (this.workArea != null) {
Composite area = new Composite(parent, SWT.NONE);
+ // we set fill layout by default but it can be overridden
+ area.setLayout(new FillLayout());
this.workArea.createUiPart(area, context);
return area;
}