MapContainer show only on click/touch - codenameone

I am trying to use naive map.
I have places a MapContainer insider a Form Component but the From shows blank without the map inside it, on the simulator. When I click on the viewport the map shows as long as the mouse button remains down. When I release it disappear again.
Is it a real problem or is it a misfunction of the simulator? If it is a real problem what am I doing wrong?
below is the class I am using:
package com.mainsys.zappeion;
import com.codename1.googlemaps.MapContainer;
import com.codename1.maps.Coord;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BorderLayout;
/**
*
* #author Christoforos
*/
public class ZappeionMap extends com.codename1.ui.Form {
private Form current;
public ZappeionMap() {
super("Ζάππειον", new BorderLayout());
}
#Override
public void show() {
if(current != null){
current.show();
return;
}
final MapContainer cnt = new MapContainer();
this.addComponent(BorderLayout.CENTER, cnt);
cnt.setCameraPosition(new Coord(41.889, -87.622));
super.show();
}
}
/********** Implementing Shai's answer ******************/
I changed my code to what Shai suggested show my class now is:
package com.mainsys.zappeion;
import com.codename1.googlemaps.MapContainer;
import com.codename1.location.Location;
import com.codename1.location.LocationManager;
import com.codename1.maps.Coord;
import com.codename1.ui.BrowserComponent;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.plaf.Style;
/**
*
* #author Christoforos
*/
public class ZappeionMap extends com.codename1.ui.Form {
private Form current;
private static final String HTML_API_KEY = "AIzaSyDHlFJK561bQVs0AyBm1M5xWS_YCHNuPfc";
public ZappeionMap() {
super("Ζάππειον", new BorderLayout());
final MapContainer cnt = new MapContainer( HTML_API_KEY );
this.addComponent(BorderLayout.CENTER, cnt);
cnt.setCameraPosition(new Coord(41.889, -87.622));
}
}
It still having the same problem. The screen is blank. The map only shown when I click on the screen.
I also noticed something else. On the debuger I get the message:
WARNING: Apple will no longer accept http URL connections from applications you tried to connect to http://tile.openstreetmap.org/4/2/9.png to learn more check out https://www.codenameone.com/blog/ios-http-urls.html
Why is it trying to connect to http://tile.openstreetmao.org. It is supposed to work with google maps not with openstreet maps.
One more information, maybe it is worh something. I test it on real device. The screen is still blink but when I touch the screen it does not show anythink, in contrast with the simulater that when I click on the screen the map appears.
I am using netbeans 8.2 on centos 7
Any help is appreciated.
Thank you Christoforos.

Why are you overriding the show method of form and don't construct the UI n the constructor?
It looks like you copied some code from the lifecycle class and mixed it with a form subclass e.g. the current variable.
This is closer to correct:
public class ZappeionMap extends com.codename1.ui.Form {
private Form current;
public ZappeionMap() {
super("Ζάππειον", new BorderLayout());
final MapContainer cnt = new MapContainer();
this.addComponent(BorderLayout.CENTER, cnt);
cnt.setCameraPosition(new Coord(41.889, -87.622));
}
}

Related

Codenameone - TextField & Keyboard

I have problem with my TextField for getting user's input. I followed examples available (developer guide, stackoverflow etc etc), but somehow the keyboard doesn't appear. Attached is the code ( I deleted the rest of my codes for t'shooting purposes) & the screenshot.
Need help on how can I make the virtual keyboard appear.
TQ in advance.
import com.codename1.ui.Form;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.ui.Toolbar;
import com.codename1.io.Log;
import com.codename1.ui.TextField;
import com.codename1.ui.layouts.BorderLayout;
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 celebriesta {
private Form current;
private Resources theme;
private Form home, allEvent, specEvent, picEvent;
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;
}
home = new Form("Home", BoxLayout.y());
home.setScrollableY(true);
TextField txt = new TextField();
txt.setFocusable(true);
txt.setConstraint(TextField.NUMERIC);
txt.startEditingAsync();
home.addComponent(txt);
home.show();
}
public void stop() {
current = getCurrentForm();
}
public void destroy() {
}
}
The keyboard doesn't appear in the simulator. Just use your computers keyboard to type into the text field.
When running on the device the native OS virtual keyboard will appear as expected.

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.

TreeView one-at-a-time hander on CheckBoxTreeItem changes

I'm beginner in JavaFX.
I need to make one-at-a-time handler for any changes in the check boxes for my TreeView. Now it works like it handles all selected nodes simultaneously.
Thanks for help. Here is my code:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.CheckBoxTreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.CheckBoxTreeCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
BorderPane root = new BorderPane();
root.setCenter(initTreeView());
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
public TreeView initTreeView() {
TreeView<String> treeView = new TreeView<>();
treeView.setRoot(new CheckBoxTreeItem<>("123"));
treeView.getRoot().addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(), event -> System.out.println("hello"));
treeView.setCellFactory(p -> new CheckBoxTreeCell<>());
treeView.getRoot().getChildren().addAll(new CheckBoxTreeItem<>("1"),new CheckBoxTreeItem<>("2"), new CheckBoxTreeItem<>("3"));
treeView.getRoot().getChildren().get(0).getChildren().addAll(new CheckBoxTreeItem<>("4"),new CheckBoxTreeItem<>("5"), new CheckBoxTreeItem<>("6"));
treeView.getRoot().getChildren().get(1).getChildren().addAll(new CheckBoxTreeItem<>("7"),new CheckBoxTreeItem<>("8"), new CheckBoxTreeItem<>("9"));
treeView.getRoot().getChildren().get(2).getChildren().addAll(new CheckBoxTreeItem<>("10"),new CheckBoxTreeItem<>("11"), new CheckBoxTreeItem<>("12"));
return treeView;
}
public static void main(String[] args) {
launch(args);
}
}
Actually it works correctly. Your event handler is called once for every changed checkbox node. Just note that changing subnodes affects parent ones as well, so you get several event handles calls.
Try next code instead which prints the name of the affected checkbox:
treeView.getRoot().addEventHandler(CheckBoxTreeItem.checkBoxSelectionChangedEvent(),
event -> System.out.println("hello " + event.getTreeItem().getValue()));
For example, if you click on checkbox "5" you will get the following log:
hello 5
hello 1
hello 123
because all parent node have changed state as well (from unchecked to intermediate "-" state). If you click "6" after that only one checkbox is affected and output will be:
hello 6

How I can stop an animated GIF in JavaFX?

I want to use an animated GIF in my project, but I dont know how I can stop the loop animation. I mean, I want the GIF to play 1 time only.
Thanks!
I haven't done GIF animation, wasn't even aware that JavaFX would have methods for starting and stopping them. If you wish to do ANY animation using images, I rather suggest you do it frame by frame yourself. This way you have full control over it and you can have more than just 256 colors in your image.
I read a very good article about Creating a Sprite Animation with JavaFX in Mike's blog.
It's very easy to do. You simply extend the Transition class, add an ImageView to it and implement the Transition's Interpolate method.
Edit: oh, and by the way, GIFs have a loop flag which tells them to either play in a loop or not to play in a loop. In other words: In theory you could modify the GIF file's loop property. In theory only, because I just tried with specifying to play only once and in JavaFX it still played in an endless loop while in FireFox it played once. By the way, JavaFX doesn't seem to support animated PNGs (APNG) which would support more than 256 colors. So the automatic image animation capabilities are very limited. Best to do the animation by yourself.
I hope someone comes up with something better, but here's an example code about how you could get full control over your gif.
import java.awt.image.BufferedImage;
import java.net.URISyntaxException;
import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* Requires GifDecoder from here: http://www.java2s.com/Code/Java/2D-Graphics-GUI/DecodesaGIFfileintooneormoreframes.htm
*/
public class AnimatedGifDemo extends Application {
#Override
public void start(Stage primaryStage) throws URISyntaxException {
HBox root = new HBox();
// TODO: provide gif file, ie exchange banana.gif with your file
Animation ani = new AnimatedGif(getClass().getResource("banana.gif").toExternalForm(), 1000);
ani.setCycleCount(10);
ani.play();
Button btPause = new Button( "Pause");
btPause.setOnAction( e -> ani.pause());
Button btResume = new Button( "Resume");
btResume.setOnAction( e -> ani.play());
root.getChildren().addAll( ani.getView(), btPause, btResume);
Scene scene = new Scene(root, 1600, 900);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public class AnimatedGif extends Animation {
public AnimatedGif( String filename, double durationMs) {
GifDecoder d = new GifDecoder();
d.read( filename);
Image[] sequence = new Image[ d.getFrameCount()];
for( int i=0; i < d.getFrameCount(); i++) {
WritableImage wimg = null;
BufferedImage bimg = d.getFrame(i);
sequence[i] = SwingFXUtils.toFXImage( bimg, wimg);
}
super.init( sequence, durationMs);
}
}
public class Animation extends Transition {
private ImageView imageView;
private int count;
private int lastIndex;
private Image[] sequence;
private Animation() {
}
public Animation( Image[] sequence, double durationMs) {
init( sequence, durationMs);
}
private void init( Image[] sequence, double durationMs) {
this.imageView = new ImageView(sequence[0]);
this.sequence = sequence;
this.count = sequence.length;
setCycleCount(1);
setCycleDuration(Duration.millis(durationMs));
setInterpolator(Interpolator.LINEAR);
}
protected void interpolate(double k) {
final int index = Math.min((int) Math.floor(k * count), count - 1);
if (index != lastIndex) {
imageView.setImage(sequence[index]);
lastIndex = index;
}
}
public ImageView getView() {
return imageView;
}
}
}
It provides a pause/resume button for testing. What you need in addition is the Gif Decoder code and an animated banana.gif.

where is the underscore in my CheckBox?

The shortest possible program to show my problem:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestCheckBox extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) {
Scene scene = new Scene(new StackPane());
final VBox vbox = new VBox();
vbox.getChildren().addAll(new Label("ABC_DEF"), new CheckBox("ABC_DEF"));
((StackPane) scene.getRoot()).getChildren().add(vbox);
stage.setScene(scene);
stage.show();
}
}
leads to:
In SceneBuilder by comparison it´s displayed normally, but not in my application. I am running Java 1.8.0-b129
Any hint?
You probably want to setMnemonicParsing to false on the CheckBox.
MnemonicParsing property to enable/disable text parsing. If this is set to true, then the Label text will be parsed to see if it contains the mnemonic parsing character '_'. When a mnemonic is detected the key combination will be determined based on the succeeding character, and the mnemonic added.
The default value for Labeled is false, but it is enabled by default on some Controls.

Resources