Codenameone BrowserComponent.setProperty giving NullPointerException - codenameone

Until today, my code has been working great. However, I've just started getting NPE when using the Crisp CN1lib. It turns out that BrowserComponent.setProperty() is the culprit. Here is my stacktrace
java.lang.NullPointerException
at com.codename1.impl.javase.JavaSEPort.setBrowserProperty(JavaSEPort.java:11340)
at com.codename1.ui.BrowserComponent.setProperty(BrowserComponent.java:607)
Looks like the JavaSEPort.setBrowserProperty() is causing it. Github shows the code was edited 2 days ago so maybe something broke.
My code is pretty basic:
import static com.codename1.ui.CN.*;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.ui.BrowserComponent;
import com.codename1.ui.Toolbar;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.layouts.BorderLayout;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
// use two network threads instead of one
updateNetworkThreadCount(2);
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
addNetworkErrorListener(err -> {
// prevent the event from propagating
err.consume();
if(err.getError() != null) {
Log.e(err.getError());
}
Log.sendLogAsync();
Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
});
}
public void start() {
if(current != null){
current.show();
return;
}
BrowserComponent browser = new BrowserComponent();
browser.addWebEventListener(BrowserComponent.onLoad, new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
}
});
browser.setProperty("UseWideViewPort", true);
browser.setProperty("LoadWithOverviewMode", true);
browser.setProperty("DatabaseEnabled", true);
browser.setProperty("BuiltInZoomControls", true);
browser.setProperty("DisplayZoomControls", false);
browser.setProperty("WebContentsDebuggingEnabled", true);
browser.setFireCallbacksOnEdt(true);
browser.setURL("https://www.instagram.com/brianabette/");
Form hi = new Form("Hi World", new BorderLayout());
hi.add(BorderLayout.CENTER, browser);
hi.show();
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
}
Any pointers? Bug maybe?

We just made some performance improvements to BrowserComponent. Looks like we missed a spot here, so there is a regression. It is already fixed in Git and will be included in the next update next Friday.

Related

Error in a Hello World CodenameOne Java program

I'm trying to run a simple Hello World program with CodenameOne in Java. I'm trying to add a button to the app. I get two compiler errors, both of them:
java: cannot find symbol
symbol: class Button
Here is the code:
//ORIGIONAL CODE
package CodenameOneHelloWorld;
import static com.codename1.ui.CN.*;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.ui.Toolbar;
import java.io.IOException;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.io.NetworkEvent;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
// use two network threads instead of one
updateNetworkThreadCount(2);
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
addNetworkErrorListener(err -> {
// prevent the event from propagating
err.consume();
if(err.getError() != null) {
Log.e(err.getError());
}
Log.sendLogAsync();
Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
});
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
Button b = new Button("Show Dialog"); // LINE HAND-TYPED ACCORDING TO TUTORIAL
hi.add(b); // LINE HAND-TYPED ACCORDING TO TUTORIAL
b.addActionListener((e) -> Dialog.show("Dialog Title", "Hi", "OK", null)); // LINE HAND-TYPED ACCORDING TO TUTORIAL
hi.show();
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
}
After following the compiler's directions, I have the new following code:
// CODE MODIFIED BY SUGGESTION FROM COMPILER
package CodenameOneHelloWorld;
import static com.codename1.ui.CN.*;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.ui.Toolbar;
import java.awt.*; // ADDED IMPORT LINE
import java.io.IOException;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.io.NetworkEvent;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
// use two network threads instead of one
updateNetworkThreadCount(2);
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
addNetworkErrorListener(err -> {
// prevent the event from propagating
err.consume();
if(err.getError() != null) {
Log.e(err.getError());
}
Log.sendLogAsync();
Dialog.show("Connection Error", "There was a networking error in the connection to " + err.getConnectionRequest().getUrl(), "OK", null);
});
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World", BoxLayout.y());
hi.add(new Label("Hi World"));
Button b = new Button("Show Dialog");
hi.add(String.valueOf(b)); // CHANGED LINE AS SUGGESTED BY COMPILER
b.addActionListener((e) -> Dialog.show("Dialog Title", "Hi", "OK", null));
hi.show();
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
}
The new code compiles clean, but when run in the simulator, the app displays an error message instead of the button.
Does anybody have any idea on how to get the button to display properly in the Hello World app?
AWT won't work here. The IDE offers more than one option when you try to import and the other option should be import com.codename1.ui.Button;. You can see the full list of supported classes in the JavaDocs here: https://www.codenameone.com/javadoc/

Request thread interrupt not working on Ios

I create a new thread, and y need to interrupt, I use the thread.interrup(), but when I throw request thread interrupt is not working on ios, works fine on simulator or in Android device.
I Attach code to try it.
My temporal solution is use a Flag to break while, but I want to use the InterruptedException
package com.kandy.forms;
import com.codename1.io.Log;
import com.codename1.ui.Button;
import com.codename1.ui.Dialog;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BoxLayout;
public class Interrup extends Form {
private Form previous;
private Thread thread = null;
public Interrup() {
setLayout(new BoxLayout(BoxLayout.Y_AXIS));
Button newThread = new Button ("Start Thread");
newThread.addActionListener((e) -> {
thread = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
Log.p("thread working");
} catch (InterruptedException ie) {
Dialog.show("Message", "Interruption received", "Ok", null);
break;
}
}
}
});
//thread start
thread.start();
});
Button interruptTreath = new Button ("Interrupt");
interruptTreath.addActionListener((e) -> {
Log.p("Interrupt Sended");
thread.interrupt();
});
add(newThread);
add(interruptTreath);
}
public void show() {
previous = Display.getInstance().getCurrent();
super.show();
}
public void goBack(){
previous.showBack();
}
}
This isn't supported on iOS. Neither is stop etc. as those are pretty hard to get working consistently across platforms. This is especially true for iOS and the thread implementation in the JavaScript port.

Open gallery and display selected picture back Codename One

IDE:
Eclipse
Desktop Windows 7
Simulator Nexus 5
Device
I want to open the gallery of the device and display the image selected bythe user back. I make a button and and an ActionListener should deflect me to the device's gallery. But the simulator shows a blank screen even if I omit the opening of the gallery part and just add the button. Also, It gives the following exception in the log:-
Jul 20, 2017 4:11:00 PM java.util.prefs.WindowsPreferences <init>
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(...) returned error code 5.
java.io.UTFDataFormatException: malformed input around byte 64
at java.io.DataInputStream.readUTF(Unknown Source)
at java.io.DataInputStream.readUTF(Unknown Source)
at com.codename1.ui.util.Resources.loadTheme(Resources.java:1270)
at com.codename1.ui.util.Resources.openFileImpl(Resources.java:303)
at com.codename1.ui.util.Resources.openFile(Resources.java:269)
at com.codename1.ui.util.Resources.<init>(Resources.java:189)
at com.codename1.ui.util.Resources.open(Resources.java:768)
at com.codename1.ui.util.Resources.open(Resources.java:688)
at com.codename1.impl.javase.JavaSEPort$4.run(JavaSEPort.java:1720)
at com.codename1.ui.Display.processSerialCalls(Display.java:1056)
at com.codename1.ui.Display.mainEDTLoop(Display.java:873)
at com.codename1.ui.RunnableWrapper.run(RunnableWrapper.java:120)
at com.codename1.impl.CodenameOneThread.run(CodenameOneThread.java:176)
The following is my main java file made on an empty new bare bone project:-
package com.mycompany.myapp;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Image;
import com.codename1.ui.Button;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.components.ImageViewer;
import com.codename1.io.Log;
import com.codename1.media.MediaManager;
import com.codename1.ui.Toolbar;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import java.io.IOException;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MyApplication {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Hi World");
hi.addComponent(new Label("Hi World"));
Button gallery = new Button("Browse");
hi.add(gallery);
gallery.addActionListener(new ActionListener<ActionEvent>() {
#Override
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
Display.getInstance().openGallery((e) -> {
if(e != null && e.getSource() != null) {
// String file = (String)e.getSource();
// try {
// Label path = new Label(file);
// hi.add(path);
//
// } catch(Exception err) {
// Log.e(err);
// }
}
}, Display.GALLERY_IMAGE);
}
});
}
public void stop() {
current = Display.getInstance().getCurrent();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = Display.getInstance().getCurrent();
}
}
public void destroy() {
}
}
It seems you have several issues. The first is a preferences issue which you should fix with your JDK install:
Resolving the problem The work around is to login as the administrator
and create the key HKEY_LOCAL_MACHINE\Software\JavaSoft\Prefs
From Java: java.util.Preferences Failing
Next it seems your resource file is corrupted. It's hard to tell what went wrong there... Is it 0 length?
Check out this article for tracking designer tool issues.
A large image from the camera will take some time to process on some devices. You can capture a smaller image (see the various capture methods) but I'm guessing that you just didn't revalidate after adding to the ui and incorrectly assumed this is slow.

BrowserComponent doesn't work on CodenameOne 3.7.2?

the following code doesn't work in the Simulator (on NetBeans 8.2 + CodenameOne 3.7.2 + Skin Iphone3gs) and doesn't work in my Android 4.1.2 device. It blocks the Simulator and it shows a blank screen on the real device (with a blinking "Loading..."). What's the problem? Thank you
import static com.codename1.ui.CN.*;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.ui.BrowserComponent;
import com.codename1.ui.Toolbar;
import com.codename1.ui.layouts.BorderLayout;
import java.io.IOException;
import com.codename1.ui.layouts.BoxLayout;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class Gmail {
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature
Log.bindCrashProtection(true);
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Form title Example", new BorderLayout());
BrowserComponent browser = new BrowserComponent();
browser.setURL("https://students.uninettunouniversity.net/");
hi.add(BorderLayout.CENTER, browser);
}
public void stop() {
current = getCurrentForm();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = getCurrentForm();
}
}
public void destroy() {
}
}
You deleted the hi.show() line at the end

CN1 Library - No code fires in runOnUiThread

No code is firing in runOnUiThread in the native implementation. Codes before runOnUiThread does fire. I am sure I am not doing something right.
I created the CodenameOne Library like this
package com.uithread.test;
import com.codename1.system.NativeInterface;
public interface UIThreadNative extends NativeInterface {
public void runNativeCode();
}
package com.uithread.test;
import com.codename1.system.NativeLookup;
import com.codename1.ui.Dialog;
public class UIThreadManager {
private static UIThreadNative uithreadNative;
public UIThreadManager() {
if (uithreadNative == null) {
uithreadNative = (UIThreadNative) NativeLookup.create(UIThreadNative.class);
if (uithreadNative == null) {
Dialog.show("Null implementation", " UIThread is not implemented yet in this platform.", "Ok", null);
throw new RuntimeException("UIThread is not implemented yet in this platform.");
}
}
if (!uithreadNative.isSupported()) {
Dialog.show("Unsupported", " UIThread is not supported in this platform.", "Ok", null);
throw new RuntimeException("UIThread is not supported in this platform.");
}
}
public void runNativeCode() {
uithreadNative.runNativeCode();
}
}
Native implementation for android
package com.uithread.test;
import android.content.Context;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.codename1.impl.android.*;
import com.codename1.ui.Dialog;
public class UIThreadNativeImpl {
private static Context context() {
return com.codename1.impl.android.AndroidNativeUtil.getActivity().getApplicationContext();
}
private static Activity activity() {
return com.codename1.impl.android.AndroidNativeUtil.getActivity();
}
public void runNativeCode() {
final Activity convenientActivity = activity();//AndroidNativeUtil.getActivity();
final CodenameOneActivity codenameoneActivity = (CodenameOneActivity) AndroidNativeUtil.getActivity();
final android.app.Activity app = (Activity) AndroidNativeUtil.getActivity();
Dialog.show("Activity", convenientActivity + " convenientActivity", "Ok", null);
Dialog.show("Activity", codenameoneActivity + " codenameoneActivity", "Ok", null);
Dialog.show("Activity", app + " App", "Ok", null);
convenientActivity.runOnUiThread(new Runnable() {
public void run() {
Dialog.show("In run", "Run started", "Ok", null);
}
});
}
public boolean isSupported() {
return true;
}
}
In Statemachine I run this in code on a button click.
#Override
protected void onMain_ButtonAction(Component c, ActionEvent event) {
UIThreadManager uIThreadManager = new UIThreadManager();
uIThreadManager.runNativeCode();
}
As I said earlier. The codes before runOnUiThread work but the codes in runOnUiThread does not work. The dialogs in the runNativeCode in the native implementation were for checking the activity in different flavors which shows correctly that the different flavors are the same.
Thanks.
The native UI thread is totally different from our EDT so showing a Codename One dialog from that thread would be a huge EDT violation that can cause a serious crash!
Since our dialog blocks safely you would be effectively blocking the entire application and crashing it.
We use this line which is pretty much equivalent to what you wrote quite a bit in Codename One and in libraries e.g. here:
AndroidNativeUtil.getActivity().runOnUiThread(new Runnable() { ... });

Resources