How can I set the encoding of a JavaFX WebView? - java

I'm having an encoding issue with JavaFX's WebView. When loading a UTF-8 encoded file, special characters are displayed incorrectly (e.g. ’ is displayed instead of ’). Here's an SSCCE:
WebViewTest.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewTest extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) {
WebView webView = new WebView();
webView.getEngine().load(getClass().getResource("/test.html").toExternalForm());
Scene scene = new Scene(webView, 500, 500);
stage.setScene(scene);
stage.setTitle("WebView Test");
stage.show();
}
}
test.html
<!DOCTYPE html>
<html>
<body>
<p>RIGHT SINGLE QUOTATION MARK: ’</p>
</body>
</html>
Output of file -bi test.html
src:$ file -bi test.html
text/plain; charset=utf-8
Result:
The same thing happens in Windows using Java 17 and the latest JavaFX (I used Linux and Java 8 for the demonstration).
I've tried:
Declaring the charset in the HTML: <meta charset="UTF-8">
(works, but I'm making an editor program, so I don't have control over the HTML)
Using the JVM argument -Dfile.encoding=UTF-8 (doesn't work)
Setting the charset using reflection (doesn't work, and throws an exception in newer Java versions):
System.setProperty("file.encoding","UTF-8");
Field charset = Charset.class.getDeclaredField("defaultCharset");
charset.setAccessible(true);
charset.set(null,null);
Declaring the charset after the page loads using the DOM API (doesn't work):
webView.getEngine().getLoadWorker().stateProperty().addListener((o, oldState, newState) -> {
if(newState == Worker.State.SUCCEEDED) {
Document document = webView.getEngine().getDocument();
Element meta = document.createElement("meta");
meta.setAttribute("charset", "UTF-8");
document.getElementsByTagName("html").item(0).appendChild(meta);
}
});
Using WebEngine.loadContent(String) instead of load(String) (wouldn't work; relative links would be broken)
It appears that WebView ignores file encodings, and uses ISO-8859-1 unless a charset is specified in the HTML.

WebView determines the encoding from either the HTML file or the HTTP header. This is as per the w3c specification, for information see:
Declaring character encodings in HTML
As you already noted in your question, you can declare the character encoding in the head element within the HTML document and the WebView will pick it up:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
...
But, you also note in your question that you don't have control over the input HTML files and whether it includes the necessary header for declaring the charset.
You can also have the HTTP protocol specify the encoding of the file using an appropriate header.
Content-Type: text/html; charset=UTF-8
If you do that, the HTML file content will be correctly UTF-8 decoded by the WebView, even if the input file does not include a charset header.
Here is an example:
import com.sun.net.httpserver.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import java.io.*;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;
public class WebViewTest extends Application {
private static final String TEST_HTML = "test.html";
private HttpServer server;
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void init() throws Exception {
server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
#Override
public void start(Stage stage) {
WebView webView = new WebView();
webView.getEngine().load("http://localhost:8000/" + TEST_HTML);
Scene scene = new Scene(webView, 500, 500);
stage.setScene(scene);
stage.setTitle("WebView Test");
stage.show();
}
#Override
public void stop() throws Exception {
server.stop(0);
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) {
try {
String path = httpExchange.getRequestURI().getPath().substring(1); // strips leading slash from path, so resource lookup will be relative to this class, not the root.
String testString = resourceAsString(path);
System.out.println("testString = " + testString);
if (testString != null) {
httpExchange.getResponseHeaders().put("Content-Type", List.of("text/html; charset=UTF-8"));
httpExchange.sendResponseHeaders(200, testString.getBytes(StandardCharsets.UTF_8).length);
try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(httpExchange.getResponseBody()))) {
writer.write(testString);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("Unable to find resource: " + path);
}
} catch (IOException e) {
e.printStackTrace();
}
}
private String resourceAsString(String fileName) throws IOException {
try (InputStream is = WebViewTest.class.getResourceAsStream(fileName)) {
if (is == null) return null;
try (InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr)) {
return reader.lines().collect(Collectors.joining(System.lineSeparator()));
}
}
}
}
}
For this example to work, place the HTML test file from your question in the same location as your compiled WebViewTest.class, so that it can be loaded from there as a resource.
To run the example as a modular app, add the following to your module-info.java (in addition to your javafx module requirements and any other app requirements you need):
requires jdk.httpserver;

While writing the question, I found a hacky solution:
webView.getEngine().getLoadWorker().stateProperty().addListener((o, oldState, newState) -> {
if(newState == Worker.State.SUCCEEDED) {
try {
String newContent = new String(Files.readAllBytes(Paths.get(new URI(getClass().getResource("/test.html").toExternalForm()))), "UTF-8");
webView.getEngine().executeScript("document.documentElement.innerHTML = '" + newContent.replace("'", "\\'").replace("\n", "\\n") + "'");
} catch(Exception e) {
e.printStackTrace();
}
}
});

I found another simple solution using Spark Java:
WebViewTest.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import spark.Spark;
import spark.staticfiles.StaticFilesConfiguration;
public class WebViewTest extends Application {
public static void main(String[] args) {
Application.launch(args);
}
#Override
public void start(Stage stage) {
Spark.port(8000);
StaticFilesConfiguration staticHandler = new StaticFilesConfiguration();
staticHandler.configure("/");
Spark.before((req, res) -> {
if(req.url().endsWith(".html")) staticHandler.putCustomHeader("Content-Type", "text/html; charset=UTF-8");
else staticHandler.putCustomHeader("Content-Type", null);
staticHandler.consume(req.raw(), res.raw());
});
Spark.init();
WebView webView = new WebView();
webView.getEngine().load("http://localhost:8000/test.html");
Scene scene = new Scene(webView, 500, 500);
stage.setScene(scene);
stage.setTitle("WebView Test");
stage.show();
}
}
test.html
<!DOCTYPE html>
<html>
<body>
<p>RIGHT SINGLE QUOTATION MARK: ’</p>
<p>Image:</p>
<img src="image.png">
</body>
</html>
image.png
Result:

Related

How to debug JavaFX webview in 2022

How to debug a JavaFX webview?
I find two ways,
one is to attach external chrome debugger to JavaFX webview.
Another is to inject firebug javascript.
Method#1 seems to use a bit of hacks like set access to private fields etc.
Method#2 depends on firebuglite which seems to be obsolete now.
How should this be done in 2022. Are there any other methods, or better methods?
I am trying firebug lite approach as of now, and have made the javascript part of the maven project and trying to inject it as a string versus an external URL, because firebug seems to be properly public hosted nowhere now.
Refering to https://stackoverflow.com/a/18396900/2448015
This is where I am right now :
package xyz.jphil.internal_browser;
import com.sun.net.httpserver.HttpContext;
import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
import javafx.scene.web.WebEngine;
import netscape.javascript.JSObject;
/**
*
* #author Ivan
*/
public class WebkitDebugUtils {
private static int resourcesPort = 0;
public static void createHttpServerForLocalFiles() {
int portStart = 64321, endPort = 65534;
resourcesPort = portStart + (int) ((endPort * 1d - portStart * 1d) * Math.random());
System.out.println("Starting internal server on " + resourcesPort);
try {
HttpServer server = HttpServer.create(new InetSocketAddress(resourcesPort), 0);
HttpContext context = server.createContext("/");
context.setHandler((req) -> {
try (req) {
var p = req.getRequestURI();
System.out.println("Serving # localhost:"+resourcesPort+" "+p);
var s = WebkitDebugUtils.class.getResourceAsStream(p.toString()).readAllBytes();
req.sendResponseHeaders(200, s.length);
req.getResponseBody().write(s);
}catch(Exception a){
a.printStackTrace();
}
});
server.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public static class JavaBridge {
public void log(String text) {
System.out.println(text);
}
}
// Maintain a strong reference to prevent garbage collection:
// https://bugs.openjdk.java.net/browse/JDK-8154127
private final static JavaBridge bridge = new JavaBridge();
public static void enableDebug(final WebEngine e) {
JSObject window = (JSObject) e.executeScript("window");
window.setMember("java", bridge);
e.executeScript("""
console.log = function(message)
{
java.log(message);
};""");
e.executeScript("console.log('console.log enabled');");
}
public static void enableFirebug(final WebEngine e) {
var firebugurl = "http://localhost:"+resourcesPort+"/firebug-lite/firebug-lite.js";
//https://raw.githubusercontent.com/stefanXO/firebug-lite/master/firebug-lite.js
//https://lupatec.eu/getfirebug/firebug-lite-compressed.js
var script= """
console.log("Inside script block");
if (!document.getElementById("FirebugLite")) {
E = document["createElement" + "NS"] && document.documentElement.namespaceURI;
E = E ?
document["createElement" + "NS"](E, "script") :
document["createElement"]("script");
E["setAttribute"]("id", "FirebugLite");
E["setAttribute"]("src", "{$firebugurl}#startOpened");
E["setAttribute"]("FirebugLite", "4");
(
document["getElementsByTagName"]("head")[0]
||
document["getElementsByTagName"]("body")[0]
).appendChild(E);
E = new Image();
E["setAttribute"]("src", "{$firebugurl}#startOpened");
}
console.log("executed script block");
""".replace("{$firebugurl}", firebugurl);
System.out.println("+++firebug thing+++");
System.out.println(script);
System.out.println("---firebug thing---");
e.executeScript(script);
}
}
Main method of the application
//...
public static void main(String[]args){
WebkitDebugUtils.createHttpServerForLocalFiles();
launch(args);
}
//...
In the JavaFx Stage initializing code section
#Override
public void start(final Stage primaryStage) throws Exception {
// ....
wv = new WebView();
// ....
javafx.scene.web.WebEngine e = wv.getEngine();
// ....
e.getLoadWorker().stateProperty().addListener((ov, t, t1) -> WebkitDebugUtils.enableDebug(e));
e.documentProperty().addListener((ov, t, t1) -> WebkitDebugUtils.enableFirebug(e));
// ....
}
I am serving the files for firebug from the resources folder of the jar
Snippter of the custom firebug.js file
console.log("inside firebug-lite");
(function(){
//...
//firebug lite 1.4.0 code
//..
})();
console.log("outside firebug-lite");
Output
Starting internal server on 65148
console.log enabled
console.log enabled
// some application specific output
+++firebug thing+++
if (!document.getElementById("FirebugLite")) {
E = document["createElement" + "NS"] && document.documentElement.namespaceURI;
E = E ?
document["createElement" + "NS"](E, "script") :
document["createElement"]("script");
E["setAttribute"]("id", "FirebugLite");
E["setAttribute"]("src", "http://localhost:65148/firebug-lite/firebug-lite.js#startOpened");
E["setAttribute"]("FirebugLite", "4");
(
document["getElementsByTagName"]("head")[0]
||
document["getElementsByTagName"]("body")[0]
).appendChild(E);
E = new Image();
E["setAttribute"]("src", "http://localhost:65148/firebug-lite/firebug-lite.js#startOpened");
}
---firebug thing---
Inside script block
executed script block
Serving # localhost:65148 /firebug-lite/firebug-lite.js
// some application specific output
console.log enabled
Summary:
nothing is happening, nothing is showing up in the console, I don't know the error, firebug is not even opening.
Update2:
I think I am using the wrong version of firebug 1.5 or something
and the old version I don't see any HTML file and thus it is dependent on the default website which is down at the moment.
You can simply inject firebug-lite after loading your webpage.
I've tested on windows 10 with correto 18.0.2 JDK.
Here's an example: (Page can take some time to load)
package com.example.demo;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.scene.web.WebEngine;
import javafx.concurrent.Worker.State;
public class HelloApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage myStage) {
System.out.println("Demo for firebugLite");
WebView myWebView = new WebView();
myWebView.minHeight(1050);
myWebView.prefWidth(1950);
myWebView.prefHeight(1070);
myWebView.minWidth(1050);
final WebEngine myWebEngine = myWebView.getEngine();
myWebEngine.getLoadWorker().stateProperty()
.addListener((obs, oldValue, newValue) -> {
if (newValue == State.SUCCEEDED) {
System.out.println("finished loading");
myWebEngine.executeScript("var firebug=document.createElement('script');firebug.setAttribute('src','https://lupatec.eu/getfirebug/firebug-lite-compressed.js');document.body.appendChild(firebug);(function(){if(window.firebug.version){firebug.init();}else{setTimeout(arguments.callee);}})();void(firebug);");
}
});
myWebEngine.load("https://lupatec.eu/getfirebug/");
VBox myBox = new VBox(myWebView);
Scene myScene = new Scene(myBox, 1050, 600);
myStage.setScene(myScene);
myStage.show();
}
}
Result:

How can to get content of file from local computer in GXT GWT in server part? (com.sencha.gxt.ui.GXT)

I have GXT GWT project (<inherits name='com.sencha.gxt.ui.GXT'/>). I need upload file from computer and get bytes array of file.
I wrote upload file in client part and all good, but I need added server part with get content of file, How can do it?
my client part:
public class FileUpload implements IsWidget {
private static FileUploadUiBinder fileUploadUiBinder = GWT.create(FileUploadUiBinder.class);
#UiTemplate("FileUpload.ui.xml")
interface FileUploadUiBinder extends UiBinder<Component, FileUpload> {
}
#UiField
FileUploadField uploadedFile;
private FieldLabel label;
#Override
public Widget asWidget() {
if (label == null) {
label = (FieldLabel) fileUploadUiBinder.createAndBindUi(this);
uploadedFile.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
Info.display("File Changed", "You selected " + uploadedFile.getValue());
}
});
}
return label;
}
}
and FileUpload.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder
xmlns:form="urn:import:com.sencha.gxt.widget.core.client.form"
xmlns:gxt="urn:import:com.sencha.gxt.widget.core.client"
xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns="urn:import:com.sencha.gxt.widget.core.client.container"
<form:FieldLabel>
<form:widget>
<form:FileUploadField ui:field="uploadedFile" name="metadataFile"/>
</form:widget>
</form:FieldLabel>
</ui:UiBinder>
so: I need added server part: How can to get bytes array (content of file) in server part? I need a example :) Maybe somebody give me link with working example? Help me, please.
Unfortunately a lot of changes should be done to your code in order to show some example of how file data could be sent to server side. And I should mention that it's only one of possible solutions. Client-server request here goes to HttpServlet rather than through standard GWT RPC though. Here are my changes:
1) Changed FileUpload.ui.xml:
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:form="urn:import:com.sencha.gxt.widget.core.client.form"
xmlns:gxt="urn:import:com.sencha.gxt.widget.core.client"
xmlns:ui='urn:ui:com.google.gwt.uibinder'
xmlns="urn:import:com.sencha.gxt.widget.core.client.container"
>
<form:FormPanel>
<form:FieldLabel>
<form:widget>
<form:FileUploadField ui:field="uploadedFile"
name="metadataFile" />
</form:widget>
</form:FieldLabel>
</form:FormPanel>
</ui:UiBinder>
2) Changed FileUpload.java:
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.widget.core.client.Component;
import com.sencha.gxt.widget.core.client.event.SubmitCompleteEvent;
import com.sencha.gxt.widget.core.client.form.FileUploadField;
import com.sencha.gxt.widget.core.client.form.FormPanel;
import com.sencha.gxt.widget.core.client.info.Info;
public class FileUpload implements IsWidget {
private static FileUploadUiBinder fileUploadUiBinder = GWT.create(FileUploadUiBinder.class);
#UiTemplate("FileUpload.ui.xml")
interface FileUploadUiBinder extends UiBinder<Component, FileUpload> {
}
#UiField
FileUploadField uploadedFile;
private FormPanel formPanel;
#Override
public Widget asWidget() {
if (formPanel == null) {
formPanel = (FormPanel) fileUploadUiBinder.createAndBindUi(this);
formPanel.setEncoding(FormPanel.Encoding.MULTIPART);
formPanel.setMethod(FormPanel.Method.POST);
formPanel.setAction("file.upload"); // This action should
// point to servlet registered in WEB_INF/web.xml
formPanel.addSubmitCompleteHandler(new SubmitCompleteEvent.SubmitCompleteHandler() {
public void onSubmitComplete(SubmitCompleteEvent event) {
String resultHtml = event.getResults();
Info.display("Upload Response", resultHtml);
}
});
uploadedFile.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
Info.display("File Changed", "You selected " +
uploadedFile.getValue());
formPanel.submit(); // It's better to do it by
// clicking on submitting button or something.
}
});
}
return formPanel;
}
}
3) web.xml (only added parts, use your own package instead of home.test.uploadtest):
<... other servlet blocks ...>
<servlet>
<servlet-name>fileUploadServlet</servlet-name>
<servlet-class>home.test.uploadtest.server.FileUploadServlet</servlet-class>
</servlet>
<... other servlet-mapping blocks ...>
<servlet-mapping>
<servlet-name>fileUploadServlet</servlet-name>
<url-pattern>/file.upload</url-pattern>
</servlet-mapping>
4) FileUploadServlet.java (mostly dummy example of server-side operation):
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = -1L;
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
File tempDir = new File(System.getProperty("java.io.tmpdir"));
FileItemFactory factory = new DiskFileItemFactory(1000000, tempDir);
ServletFileUpload upload = new ServletFileUpload(factory);
File target = null;
try {
try {
List<?> items = upload.parseRequest(request);
Iterator<?> it = items.iterator();
while (it.hasNext()) {
FileItem item = (FileItem) it.next();
if (item.isFormField()) {
throw new ServletException("Unsupported non-file property [" +
item.getFieldName() + "] with value: " + item.getString());
} else {
target = File.createTempFile("temp_", ".data", tempDir);
item.write(target);
item.delete();
System.out.println("Temp file: " + target.getAbsolutePath());
}
}
} catch (ServletException e) {
throw e;
} catch (Exception e) {
throw new IllegalStateException(e);
}
response.getWriter().write("File length: " + target.length());
response.getWriter().close();
} finally {
if (target != null && target.exists())
target.delete();
}
}
}
So as you can see there is a dependency to https://commons.apache.org/proper/commons-fileupload/
PS: I think that because of large size of code I might forget something. In this case just let me know.

How do I use Java to launch a local HTML page that uses Javascript to load a local json file and display its contents?

I have a java application that reports on the up/down status of several websites and creates a .json file with the data. I have an HTML page that uses javascript to take a .json file and display a nice little grid with red or green lights telling you if a website is up or down. I have no idea how to make the java app tell the html page exactly what the .json file is named (i create a new timestamped .json file every app run). Is there any way to pass a parameter or something to the HTML page on load (currently using Desktop.getDesktop().browse(URI.create("file://blah");), or am I stuck to overwriting my .json file every time I run the app?
How about using a query parameter? Like file://blah.html?json=foo.json Or a fragment: file://blah.html#foo.json.
You could create a tiny local server and register the url /json to any file you want:
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
public class main {
static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
server.createContext("/", new IndexHandler());
server.createContext("/json", new JsonHandler());
server.start();
}
static class IndexHandler implements HttpHandler {
#Override
public void handle(HttpExchange httpExchange) throws IOException {
String response = readFile("index.html", StandardCharsets.UTF_8);
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
static class JsonHandler implements HttpHandler {
#Override
public void handle(HttpExchange httpExchange) throws IOException {
String response = readFile("whatEverJsonYouWant.json", StandardCharsets.UTF_8);
httpExchange.sendResponseHeaders(200, response.length());
OutputStream os = httpExchange.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
Now the JS can be changed to fetch /json

Retrieving access token of OAuth 2.0 (implicit grant) from java Desktop Client using SkyDrive REST API.

I am trying to implement OAuth 2.0 implicit grant from java desktop client application using SkyDrive REST API. I use the following code:
Desktop.getDesktop().browse(new URL(st.toString()).toURI());
JOptionPane.showMessageDialog(null, "Press ok to continue once you have authenticated.");
my code opens web browser and ask users to signin and then SkyDrive sends access token to the browser url in the following form:
https://login.live.com/oauth20_desktop.srf?lc=1033#access_token=EwAwAq1DBAAUlbRW.....
What I want to do is to read this access token from my java program.
I tried to read httpconnection from console:
HttpURLConnection con = (HttpURLConnection) url.openConnection();
BufferedReader reader = new BufferedReader( new InputStreamReader(url.openStream()));
while(reader.readLine()!=null){
System.out.println(reader.readLine());
but it seems that java httpurlconnection does not handle javascript response. It replies:
<html dir="..... Windows Live ID requires JavaScript to sign in. This web browser either does not support JavaScript, or scripts are being blocked......<body onload="evt_LoginHostMobile_onload(event);">
So, Is there any way to retrieve the access token directly from java?
I had the same problem. After hours of brainstorming, I have finally found a solution. I use the JavaFX library to create a WebView. Then you can intercept location change.
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class Authenticate extends Application {
static final String APP_ID = "...";
static final String REDIRECT_URL = "https://login.live.com/oauth20_desktop.srf";
static final String RESPONSE_TYPE = "token";
static final String SCOPE = "wl.signin%20wl.offline_access";
private Scene scene;
#Override
public void start(final Stage stage) throws Exception {
final String url = "https://login.live.com/oauth20_authorize.srf?client_id="+APP_ID
+"&scope="+SCOPE+"&response_type="+RESPONSE_TYPE+"&oauth_callback=oob&redirect_uri="+REDIRECT_URL;
BorderPane borderPane = new BorderPane();
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.load(url);
borderPane.setCenter(browser);
webEngine.setOnStatusChanged(new EventHandler<WebEvent<String>>() {
public void handle(WebEvent<String> event) {
if (event.getSource() instanceof WebEngine) {
WebEngine we = (WebEngine) event.getSource();
String location = we.getLocation();
if (location.startsWith(REDIRECT_URL) && location.contains("access_token")) {
try {
URL url = new URL(location);
String[] params = url.getRef().split("&");
Map<String, String> map = new HashMap<String, String>();
for (String param : params) {
String name = param.split("=")[0];
String value = param.split("=")[1];
map.put(name, value);
}
System.out.println("The access token: "+map.get("access_token"));
stage.hide();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
}
});
// create scene
stage.setTitle("Skydrive");
scene = new Scene(borderPane, 750, 500);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Code fails to show image - java.io.IOException at Image.createImage

I'm trying to create a splash screen using LWUIT. I want a form to load and display text and an imagefor 5 seconds then continue to the next form. I have a code but fails to show the image. The class and the image are stored together int he same package. Instead, it shows an error.
java.io.IOException
What could be the problem? This is the code
package tungPackage;
import com.sun.lwuit.Display;
import com.sun.lwuit.Form;
import com.sun.lwuit.Image;
import com.sun.lwuit.Label;
import javax.microedition.midlet.MIDlet;
public class photoMidlet extends MIDlet {
public void startApp() {
Display.init(this);
try {
Form splashscreen = new Form();
// Label splashText = new Label("Baldy");
Image image = Image.createImage("/splash.png");
Label pictureLabel = new Label(image);
splashscreen.addComponent(pictureLabel);
splashscreen.show();
} catch (Exception ex) {
Form x = new Form("ERROR");
String y = ex.toString();
Label g = new Label(y);
x.addComponent(g);
x.show();
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}
Open your JAR file using a ZIP utility (e.g. 7-zip) and look in the root of the file. If splash.png isn't in the root of the jar that's your problem!
Place splash.png so it is in the root of the jar.

Categories