Creating a javax.microedition.lcdui.Image on J2Se Application - image

I have designed a component for J2Me, and here is the paint method:
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
class Component {
...
public void paint(Graphics g) {
if (background != null)
g.drawImage(image, bounds.getLocation().x, bounds.getLocation().y, 0);
}
...
}
I want to paint this component on a J2Se application, I tried to paint the component onto a J2Me Image and extracted the int[] into an InputStream, and create a new image on the J2Se platform, with this object:
public class ComponentStreamer {
private Component component;
private Image j2Me_Image;
public void setComponent(Component component) {
this.component = component;
}
public InputStream getInputStream() throws IOException {
if(component==null)
return null;
//THIS LINE THROWS THE EXCEPTION
j2Me_Image=Image.createImage(component.getSize().width, component.getSize().height);
component.paint(j2Me_Image.getGraphics());
return getImageInputStream(j2Me_Image);
}
}
I've tried the Object, but the commented line throws an exception:
Exception in thread "AWT-EventQueue-0" java.lang.UnsatisfiedLinkError: javax.microedition.lcdui.ImmutableImage.decodeImage([BII)V
at javax.microedition.lcdui.ImmutableImage.decodeImage(Native Method)
at javax.microedition.lcdui.ImmutableImage.getImageFromStream(Image.java:999)
at javax.microedition.lcdui.ImmutableImage.<init>(Image.java:955)
at javax.microedition.lcdui.Image.createImage(Image.java:554)
How can over come this error?
Thanks,
Adam.

Well,
That was a very long process of diving into the sources of the J2Me MIDP and CLDC, and the use of a package called Microemulator, here is some code to get anyone else started:
this starts an emulator, which then enables some of the J2Me features.
private void setUpEmulator() {
try {
// overrideJ2MeImagePackageLock();
Headless app = new Headless();
DeviceEntry defaultDevice = new DeviceEntry("Default device", null, DeviceImpl.DEFAULT_LOCATION, true, false);
Field field = app.getClass().getDeclaredField("emulator");
field.setAccessible(true);
Common emulator = (Common) field.get(app);
emulator.initParams(new ArrayList<String>(), defaultDevice, J2SEDevice.class);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Un-handled Exception");
}
}
Next we have few other nice objects to work with:
public class J2MeImageLayer extends ScalableLayer {
private static final long serialVersionUID = -4606125807092612043L;
public J2MeImageLayer() {
componentViewer.super();
}
#Override
public void repaint() {
J2SEMutableImage mutableImage = new J2SEMutableImage(page.getSize().width, page.getSize().height);
page.paint(mutableImage.getGraphics());
Graphics g = getImage().getGraphics();
g.drawImage(mutableImage.getImage(), 0, 0, DCP_Simulator.this);
}
public void addComponent(Component component) {
page.add(component);
}
public void setComponent(final Component component) {
page.removeAllElements();
final Container componentParent;
if ((componentParent = component.getParent()) != null)
component.setRemovedAction(new interfaces.Action() {
#Override
public void action() {
componentParent.add(component);
}
});
page.add(component);
}
}
and this is the highlight on how to do that.
Adam.

Related

javafx User interface not updating?

I'm new to JavaFX.
I'm building a GUI for a project of mine, and I have a problem with it -
it seems that once I show my UI it stops updating.
In my case, it supposed to update a fill colour for a circle but it does not.
I tried to move the line:
someCircleId.setFill(color));
to be above the line:
Main.stage.show();
in the initialize function in my code and it did change the color of
the certain circle.
public class UIController implements Initializable {
public UIController() {
fillMap();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
Main.stage.show();
}
#FXML
public void pressExitButton() {
Main.dropDBSchema();
System.exit(0);
}
public void changeCircleColor(String circleKey, Color color) {
Platform.runLater(
() -> {
Circle circle = this.circles.get(circleKey);
PauseTransition delay = new PauseTransition(Duration.seconds(10));
delay.setOnFinished(event -> circle.setFill(color));
delay.play();
}
);
}
}
And this is the class that uses these functions:
public class MonitoringLogicImpl implements MonitoringLogic {
public void updateUI(UUID flowUUID, String sender, String receiver, DATA_STATUS status){
String key = flowUUID.toString()+"_"+sender+"_"+receiver;
Color color = this.uiController.getColorAccordingToStatus(status);
this.uiController.changeCircleColor(key, color);
}
}
This is the FXML initialization :
public void start(Stage stage){
this.stage = stage;
FXMLLoader loader = new FXMLLoader();
try {
loader.setLocation(getClass().getResource("/UserInterface.fxml"));
this.root = loader.load();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
stage.setTitle("Troubleshooting project");
stage.setScene(new Scene(root, 900, 700));
stage.show();
}
I created my UI using Scene-Builder tool.

Is it possible to Fetch user location from a Worker class?

I have to schedule a work to fetch user current location and update to server in a given interval (Even the app is not running).
I am trying to WorkManagerAPI to implement the functionality.
Is it possible to fetch the current location of the user from the doWork() method ?
locationManager.requestLocationUpdates(
provider, timeInterval, travelDistance, locationListener
);
When I request Location updates from the doWork() it throws below error.
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
As per my understanding, when implementing LocationManager.requestLocationUpdates() on a Worker thread, the call is being made on a non-UI, background thread created by WorkManager. LocationManager.requestLocationUpdates() is an asynchronous call possibly on another background thread. To handle the callbacks defined by the LocationListener, the calling thread must stay alive. Thats why the exception says,
Can't create handler inside thread that has not called Looper.prepare()
Check the code snippet below. Please consider this as pseudocode, I haven't tested this piece of code.
public class LocationWorker extends Worker {
String LOG_TAG = "LocationWorker";
private Context mContext;
private MyHandlerThread mHandlerThread;
public LocationWorker(#NonNull Context context, #NonNull WorkerParameters workerParams) {
super(context, workerParams);
mContext = context;
}
#NonNull
#Override
public Result doWork() {
Log.d(LOG_TAG, "doWork");
mHandlerThread = new MyHandlerThread("MY_THREAD");
mHandlerThread.start();
Runnable runnable = new Runnable() {
#Override
public void run() {
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
String bestProvider = locationManager.getBestProvider(new Criteria(), true);
boolean permission = false;
if (PermissionChecker.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
PermissionChecker.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Log.e(LOG_TAG, "This app requires ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION permissions.");
permission = true;
}
Log.d(LOG_TAG, "permission: "+permission);
Log.d(LOG_TAG, "bestProvider: "+bestProvider);
if (permission && bestProvider != null) {
MyLocationListener locListener = new MyLocationListener();
locationManager.requestLocationUpdates(bestProvider, 500, 1, locListener, mHandlerThread.getLooper());
}
}
};
mHandlerThread.post(runnable);
return Result.success();
}
class MyHandlerThread extends HandlerThread {
Handler mHandler;
MyHandlerThread(String name) {
super(name);
}
#Override
protected void onLooperPrepared() {
Looper looper = getLooper();
if (looper != null)
mHandler = new Handler(looper);
}
void post(Runnable runnable) {
if (mHandler != null)
mHandler.post(runnable);
}
}
class MyLocationListener implements LocationListener
{
#Override
public void onLocationChanged(final Location loc)
{
Log.d(LOG_TAG, "Location changed: " + loc.getLatitude() +","+ loc.getLongitude());
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
Log.d(LOG_TAG, "onStatusChanged");
}
#Override
public void onProviderDisabled(String provider)
{
Log.d(LOG_TAG, "onProviderDisabled");
}
#Override
public void onProviderEnabled(String provider)
{
Log.d(LOG_TAG, "onProviderEnabled");
}
}
}

Camera not initialization issue with rpi3 camera v2 on Android Things

I am trying to run a simple Android Thing project that simply captures and renders the captured image in the display. I took the sample code from (https://github.com/googlecodelabs/androidthings-imageclassifier/tree/master/imageclassifier-add-camera) without the image recognition part. But I'm getting the following error-
I/InstantRun: starting instant run server: is main process
I/CameraManagerGlobal: Connecting to camera service
D/CameraHandler: Using camera id 0
W/CameraHandler: Cannot capture image. Camera not initialized.
D/CameraHandler: Opened camera.
So it seems it detects the camera but it can't capture images from the camera. Anyone faced similar issues on AndroidThings platform?
Main Camera Handler code provided below-
public class CameraHandler {
private static final String TAG = CameraHandler.class.getSimpleName();
public static final int IMAGE_WIDTH = 320;
public static final int IMAGE_HEIGHT = 240;
private static final int MAX_IMAGES = 1;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCaptureSession;
/**
* An {#link android.media.ImageReader} that handles still image capture.
*/
private ImageReader mImageReader;
// Lazy-loaded singleton, so only one instance of the camera is created.
private CameraHandler() {
}
private static class InstanceHolder {
private static CameraHandler mCamera = new CameraHandler();
}
public static CameraHandler getInstance() {
return InstanceHolder.mCamera;
}
/**
* Initialize the camera device
*/
public void initializeCamera(Context context,
Handler backgroundHandler,
ImageReader.OnImageAvailableListener imageAvailableListener) {
// Discover the camera instance
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] camIds = {};
try {
camIds = manager.getCameraIdList();
} catch (CameraAccessException e) {
Log.d(TAG, "Cam access exception getting IDs", e);
}
if (camIds.length < 1) {
Log.d(TAG, "No cameras found");
return;
}
String id = camIds[0];
Log.d(TAG, "Using camera id " + id);
// Initialize the image processor
mImageReader = ImageReader.newInstance(IMAGE_WIDTH, IMAGE_HEIGHT,
ImageFormat.JPEG, MAX_IMAGES);
mImageReader.setOnImageAvailableListener(
imageAvailableListener, backgroundHandler);
// Open the camera resource
try {
manager.openCamera(id, mStateCallback, backgroundHandler);
} catch (CameraAccessException cae) {
Log.d(TAG, "Camera access exception", cae);
}
}
/**
* Callback handling device state changes
*/
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
#Override
public void onOpened(#NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Opened camera.");
mCameraDevice = cameraDevice;
}
#Override
public void onDisconnected(#NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera disconnected, closing.");
closeCaptureSession();
cameraDevice.close();
}
#Override
public void onError(#NonNull CameraDevice cameraDevice, int i) {
Log.d(TAG, "Camera device error, closing.");
closeCaptureSession();
cameraDevice.close();
}
#Override
public void onClosed(#NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Closed camera, releasing");
mCameraDevice = null;
}
};
/**
* Begin a still image capture
*/
public void takePicture() {
if (mCameraDevice == null) {
Log.w(TAG, "Cannot capture image. Camera not initialized.");
return;
}
// Here, we create a CameraCaptureSession for capturing still images.
try {
mCameraDevice.createCaptureSession(
Collections.singletonList(mImageReader.getSurface()),
mSessionCallback,
null);
} catch (CameraAccessException cae) {
Log.d(TAG, "access exception while preparing pic", cae);
}
}
/**
* Callback handling session state changes
*/
private CameraCaptureSession.StateCallback mSessionCallback =
new CameraCaptureSession.StateCallback() {
#Override
public void onConfigured(#NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (mCameraDevice == null) {
return;
}
// When the session is ready, we start capture.
mCaptureSession = cameraCaptureSession;
triggerImageCapture();
}
#Override
public void onConfigureFailed(#NonNull CameraCaptureSession cameraCaptureSession) {
Log.w(TAG, "Failed to configure camera");
}
};
/**
* Execute a new capture request within the active session
*/
private void triggerImageCapture() {
try {
final CaptureRequest.Builder captureBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(mImageReader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
//captureBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
Log.d(TAG, "Capture request created.");
mCaptureSession.capture(captureBuilder.build(), mCaptureCallback, null);
} catch (CameraAccessException cae) {
Log.d(TAG, "camera capture exception");
}
}
/**
* Callback handling capture session events
*/
private final CameraCaptureSession.CaptureCallback mCaptureCallback =
new CameraCaptureSession.CaptureCallback() {
#Override
public void onCaptureProgressed(#NonNull CameraCaptureSession session,
#NonNull CaptureRequest request,
#NonNull CaptureResult partialResult) {
Log.d(TAG, "Partial result");
}
#Override
public void onCaptureCompleted(#NonNull CameraCaptureSession session,
#NonNull CaptureRequest request,
#NonNull TotalCaptureResult result) {
session.close();
mCaptureSession = null;
Log.d(TAG, "CaptureSession closed");
}
};
private void closeCaptureSession() {
if (mCaptureSession != null) {
try {
mCaptureSession.close();
} catch (Exception ex) {
Log.e(TAG, "Could not close capture session", ex);
}
mCaptureSession = null;
}
}
/**
* Close the camera resources
*/
public void shutDown() {
closeCaptureSession();
if (mCameraDevice != null) {
mCameraDevice.close();
}
}
}
The pitfall with camera:
Check the permissions in Manifest file, and restart the device.
The camera-permission is granted not after installing the application, but first after install and RESTART of device.
see https://developer.android.com/things/sdk/index.html

Sliding JPanel with Universal Tween Engine

For a few days I have been trying to create a JPanel, that comes flying in from the side. I found the Universal Tween Engine and also saw a few demos but for some reason I was never able to make it work in my own code. For the sake of simplicity let's just attempt to move a JPanel (containing an image in a JLabel) from (0,0) to (600,0) on a JFrame. This is what I've got so far and the closest I have ever gotten to actually moving things with this framework, all it does it make the JPanel jump to its destination within the first tick or so. It is supposed to be so simple but I must be missing something...
SlideTest.java - Creating the UI, initializing the Thread + Tween
public class SlideTest {
TweeningPane p;
public TweenManager tweenManager;
public static void main(String[] args) {
new SlideTest();
}
public SlideTest() {
try {
setupGUI();
} catch (IOException e) {
e.printStackTrace();
}
tweenManager = new TweenManager();
AnimationThread aniThread = new AnimationThread();
aniThread.setManager(tweenManager);
aniThread.start();
Tween.to(p, 1, 10.0f).target(600).ease(Quad.OUT).start(tweenManager);
}
public void setupGUI() throws IOException {
JFrame f = new JFrame();
f.setSize(800, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p = new TweeningPane();
JLabel l = new JLabel(new ImageIcon("E:/Pictures/Stream/aK6IX4V.png"));
f.setLayout(null);
p.add(l);
p.setBounds(0, 0, 300, 300);
f.add(p);
f.setVisible(true);
}
}
AnimationThread.java - The Thread, that is supposed to keep my TweenManager updated as much/often as possible
public class AnimationThread extends Thread {
TweenManager tm;
public void setManager(TweenManager tweenmanager) {
this.tm = tweenmanager;
}
public void run() {
while (true) {
//System.out.println("MyThread running");
tm.update(MAX_PRIORITY);
try {
sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
TweeningPane.java - My Object(JPanel), I want to move across the JPanel
public class TweeningPane extends JPanel implements TweenAccessor<JPanel> {
private static final long serialVersionUID = 1L;
#Override
public int getValues(JPanel arg0, int arg1, float[] arg2) {
return (int) arg0.getBounds().getX();
}
#Override
public void setValues(JPanel arg0, int arg1, float[] arg2) {
arg0.setBounds((int) arg2[0], 0, 300, 300);
}
}
I have finally figured it out. I was simply using the framework in a wrong way as I expected. I'm not sure whether all these steps were needed but this is what I went through in order to make it work: (for future reference)
I had to register my accessor to the engine:
Tween.registerAccessor(TweeningPane.class, new TweeningPane());
And the thread itself now looks like this; I had to give the manager's update method the elapsed time as a parameter.
public void run() {
long ms1 = System.currentTimeMillis();
while (true) {
//System.out.println("MyThread running");
tm.update((System.currentTimeMillis() - ms1) / 1000f);
try {
Thread.sleep(40);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

JavaFX2 - very poor performance when adding custom made (fxml)panels to gridpane dynamically

Problem
I want to add custom made panels, built via javafx scene builder, to a gridpane at runtime. My custom made panel exsits of buttons, labels and so on.
My Attempt
I tried to extend from pane...
public class Celli extends Pane{
public Celli() throws IOException{
Parent root = FXMLLoader.load(getClass().getResource("Cell.fxml"));
this.getChildren().add(root);
}
}
... and then use this panel in the adding method of the conroller
#FXML
private void textChange(KeyEvent event) {
GridPane g = new GridPane();
for (int i=0 : i<100; i++){
g.getChildren().add(new Celli());
}
}
}
It works, but it performs very very poor.
What I am looking for
Is there a way to design panels via javafx scene builder (and as a result having this panels in fxml) and then add it to a gridpane at runtime without make use of this fxmlloader for each instance. I think it performs poor because of the fxml loader. When I add a standard button e.g. whitout fxml it is very much faster.
Short answer: No, it is not (as of JavaFX 2.x and 8.0). It may be in a future version (JFX >8)
Long answer:
The FXMLLoader is currently not designed to perform as a template provider that instantiates the same item over and over again. Rather it is meant to be a one-time-loader for large GUIs (or to serialize them).
The performance is poor because depending on the FXML file, on each call to load(), the FXMLLoader has to look up the classes and its properties via reflection. That means:
For each import statement, try to load each class until the class could successfully be loaded.
For each class, create a BeanAdapter that looks up all properties this class has and tries to apply the given parameters to the property.
The application of the parameters to the properties is done via reflection again.
There is also currently no improvement for subsequent calls to load() to the same FXML file done in the code. This means: no caching of found classes, no caching of BeanAdapters and so on.
There is a workaround for the performance of step 1, though, by setting a custom classloader to the FXMLLoader instance:
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
public class MyClassLoader extends ClassLoader{
private final Map<String, Class> classes = new HashMap<String, Class>();
private final ClassLoader parent;
public MyClassLoader(ClassLoader parent) {
this.parent = parent;
}
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> c = findClass(name);
if ( c == null ) {
throw new ClassNotFoundException( name );
}
return c;
}
#Override
protected Class<?> findClass( String className ) throws ClassNotFoundException {
// System.out.print("try to load " + className);
if (classes.containsKey(className)) {
Class<?> result = classes.get(className);
return result;
} else {
try {
Class<?> result = parent.loadClass(className);
// System.out.println(" -> success!");
classes.put(className, result);
return result;
} catch (ClassNotFoundException ignore) {
// System.out.println();
classes.put(className, null);
return null;
}
}
}
// ========= delegating methods =============
#Override
public URL getResource( String name ) {
return parent.getResource(name);
}
#Override
public Enumeration<URL> getResources( String name ) throws IOException {
return parent.getResources(name);
}
#Override
public String toString() {
return parent.toString();
}
#Override
public void setDefaultAssertionStatus(boolean enabled) {
parent.setDefaultAssertionStatus(enabled);
}
#Override
public void setPackageAssertionStatus(String packageName, boolean enabled) {
parent.setPackageAssertionStatus(packageName, enabled);
}
#Override
public void setClassAssertionStatus(String className, boolean enabled) {
parent.setClassAssertionStatus(className, enabled);
}
#Override
public void clearAssertionStatus() {
parent.clearAssertionStatus();
}
}
Usage:
public static ClassLoader cachingClassLoader = new MyClassLoader(FXMLLoader.getDefaultClassLoader());
FXMLLoader loader = new FXMLLoader(resource);
loader.setClassLoader(cachingClassLoader);
This significantly speeds up the performance. However, there is no workaround for step 2, so this might still be a problem.
However, there are already feature requests in the official JavaFX jira for this. It would be nice of you to support this requests.
Links:
FXMLLoader should be able to cache imports and properties between to load() calls:
https://bugs.openjdk.java.net/browse/JDK-8090848
add setAdapterFactory() to the FXMLLoader:
https://bugs.openjdk.java.net/browse/JDK-8102624
I have had a similar issue. I also had to load a custom fxml-based component several times, dynamically, and it was taking too long. The FXMLLoader.load method call was expensive, in my case.
My approach was to parallelize the component instantiation and it solved the problem.
Considering the example posted on the question, the controller method with multithread approach would be:
private void textChange(KeyEvent event) {
GridPane g = new GridPane();
// creates a thread pool with 10 threads
ExecutorService threadPool = Executors.newFixedThreadPool(10);
final List<Celli> listOfComponents = Collections.synchronizedList(new ArrayList<Celli>(100));
for (int i = 0; i < 100; i++) {
// parallelizes component loading
threadPool.execute(new Runnable() {
#Override
public void run() {
listOfComponents.add(new Celli());
}
});
}
// waits until all threads completion
try {
threadPool.shutdown();
threadPool.awaitTermination(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// seems to be a improbable exception, but we have to deal with it
e.printStackTrace();
}
g.getChildren().addAll(listOfComponents);
}
Just adding code for "caching of already loaded classes" in #Sebastian sir given code. It is working for me. Please suggest changes in it for better performance.
#Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
System.out.println("In Class loader");
Class result;
System.out.println(" >>>>>> Load class : "+name);
result = (Class)classes.get(name);
if(result != null){
System.out.println(" >>>>>> returning cached class.");
return result;
}else{
Class<?> c = findClass(name);
if ( c == null ) {
throw new ClassNotFoundException( name );
}
System.out.println(" >>>>>> loading new class for first time only");
return c;
}
}

Resources