A trouble with Uber Clone - codenameone

Hi Guys: I´m trying with Uber Clone code and I´m using Netbeans . I have two questions:
1).- In the countryPickerForm Listing 4.12 (The Listing number is the book´s listing "Create an Uber Clone..."); Netbeans marks me an error,("Cannot find symbol variable CommonCode"), of course, in the CommonCode object, i don´t know what library to use
´´´
public class CountryPickerForm extends Form{
//#SuppressWarnings("LeakingThisInConstructor")
public CountryPickerForm(Button sourceButton, Resources Flag){
super(BoxLayout.y());
**CommonCode.initBlackTitleForm(this,"Select a Country", val-> search(val));**
Image blankIcon = Image.createImage(100, 70, 0);
´´´
2).- And the second question: What is te correct place to the Listing (5.22) "Toogling the "WhereTo?" UI when focus changes". I placed it Inside the MapForm class outside from any method, but Neatbeans marks me an error: "< identifier > expected. Ilegal start of type "
This is the code:
from.addFocusListener(new FocusListener(){
public void focusGained(Component cmp){
fromSelected.setIcon(square);
if(layer.getComponentCount()> 1){
Component c = layer.getComponentAt(1);
c.setY(getDisplayHeight());
layer.animateUnlayout(200,150,() ->{
c.remove();
revalidate();
});
}
}
public void focusLost(){
fromSelected.setIcon(circle);
}
});
to.addFocusListener(new FocusListener(){
public void focusGained(Component cmp){
fromSelected.setIcon(circle):
toSelected.setIcon(square);
showToNavigationBar(layer);
}
public void focusLost(Component cmp){
toSelecte3dsetIcon(circle);
}
});
Thanks Guys!!!!

CommonCode was somehow lost in one of the edits to the book. It's a part of the downloadable zip listed at the start of the book and should be there. This is the full listing of that class:
package com.codename1.apps.uberclone.forms;
import com.codename1.apps.uberclone.server.UserService;
import com.codename1.components.MultiButton;
import com.codename1.io.Log;
import com.codename1.ui.Button;
import static com.codename1.ui.CN.*;
import com.codename1.ui.Command;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.TextField;
import com.codename1.ui.Toolbar;
import com.codename1.ui.animations.CommonTransitions;
import com.codename1.ui.animations.Transition;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.Style;
import com.codename1.util.LazyValue;
import com.codename1.util.SuccessCallback;
import java.io.IOException;
/**
* Common code for construction and initialization of various classes e.g. the side menu logic etc.
*
* #author Shai Almog
*/
public class CommonCode {
private static Image avatar;
public static Image getAvatar(SuccessCallback<Image> avatarChanged) {
if(avatar == null) {
int size = convertToPixels(10);
Image temp = Image.createImage(size, size, 0xff000000);
Graphics g = temp.getGraphics();
g.setAntiAliased(true);
g.setColor(0xffffff);
g.fillArc(0, 0, size, size, 0, 360);
Object mask = temp.createMask();
UserService.fetchAvatar(i -> {
avatar = i.fill(size, size).applyMask(mask);
avatarChanged.onSucess(avatar);
});
if(avatar != null) {
return avatar;
}
Style s = new Style();
s.setFgColor(0xc2c2c2);
s.setBgTransparency(255);
s.setBgColor(0xe9e9e9);
FontImage x = FontImage.createMaterial(FontImage.MATERIAL_PERSON, s, size);
avatar = x.fill(size, size);
if(avatar instanceof FontImage) {
avatar = ((FontImage)avatar).toImage();
}
avatar = avatar.applyMask(mask);
}
return avatar;
}
public static Image setAvatar(String imageFile) {
int size = convertToPixels(10);
Image temp = Image.createImage(size, size, 0xff000000);
Graphics g = temp.getGraphics();
g.setAntiAliased(true);
g.setColor(0xffffff);
g.fillArc(0, 0, size, size, 0, 360);
Object mask = temp.createMask();
try {
Image img = Image.createImage(imageFile);
avatar = img.fill(size, size).applyMask(mask);
} catch(IOException err) {
// this is unlikely as we just grabbed the image...
Log.e(err);
}
return avatar;
}
public static MultiButton createEntry(char icon, String title) {
MultiButton b = new MultiButton(title);
b.setUIID("Container");
b.setUIIDLine1("WhereToButtonLine1");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
}
public static MultiButton createEntry(char icon, String title, String subtitle) {
MultiButton b = new MultiButton(title);
b.setTextLine2(subtitle);
b.setUIID("Container");
b.setUIIDLine1("WhereToButtonLineNoBorder");
b.setUIIDLine2("WhereToButtonLine2");
b.setIconUIID("WhereToButtonIcon");
FontImage.setMaterialIcon(b, icon);
return b;
}
public static Label createSeparator() {
Label sep = new Label("", "WhereSeparator");
sep.setShowEvenIfBlank(true);
return sep;
}
public static void constructSideMenu(Toolbar tb) {
Button userAndAvatar = new Button("Shai Almog", "AvatarBlock");
userAndAvatar.setIcon(getAvatar(i -> userAndAvatar.setIcon(i)));
userAndAvatar.setGap(convertToPixels(3));
userAndAvatar.addActionListener(e -> new EditAccountForm().show());
tb.addComponentToSideMenu(userAndAvatar);
MultiButton uberForBusiness = new MultiButton("Do you Uber for business?");
uberForBusiness.setTextLine2("Tap to create your business profile");
uberForBusiness.setUIID("UberForBusinessBackground");
uberForBusiness.setUIIDLine1("UberForBusinessLine1");
uberForBusiness.setUIIDLine2("UberForBusinessLine2");
tb.addComponentToSideMenu(uberForBusiness);
tb.addCommandToSideMenu("Payment", null, e -> {});
tb.addCommandToSideMenu("Your Trips", null, e -> {});
tb.addCommandToSideMenu("Help", null, e -> {});
tb.addCommandToSideMenu("Free Rides", null, e -> {});
tb.addCommandToSideMenu("Settings", null, e -> new SettingsForm().show());
Button legalButton = new Button("Legal", "Legal");
Container legal = BorderLayout.centerCenterEastWest(null, new Label("v4.178.1001", "VersionNumber"), legalButton);
legal.setLeadComponent(legalButton);
legal.setUIID("SideNavigationPanel");
tb.setComponentToSideMenuSouth(legal);
}
/**
* Initializes a form with a black background title animation style
* #param f the form
*/
public static void initBlackTitleForm(Form f, String title, SuccessCallback<String> searchResults) {
Form backTo = getCurrentForm();
f.getContentPane().setScrollVisible(false);
Button back = new Button("", "TitleCommand");
removeTransitionsTemporarily(backTo);
back.addActionListener(e -> backTo.showBack());
back.getAllStyles().setFgColor(0xffffff);
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK);
f.setBackCommand(new Command("") {
#Override
public void actionPerformed(ActionEvent evt) {
backTo.showBack();
}
});
Container searchBack = null;
if(searchResults != null) {
Button search = new Button("", "TitleCommand");
search.getAllStyles().setFgColor(0xffffff);
FontImage.setMaterialIcon(search, FontImage.MATERIAL_SEARCH);
search.addActionListener(e -> {
});
searchBack = BorderLayout.north(
BorderLayout.centerEastWest(null, search, back));
} else {
searchBack = BorderLayout.north(
BorderLayout.centerEastWest(null, null, back));
}
Label titleLabel = new Label(title, "WhiteOnBlackTitle");
titleLabel.getAllStyles().setMarginTop(back.getPreferredH());
titleLabel.getAllStyles().setMarginUnit(Style.UNIT_TYPE_PIXELS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
f.getToolbar().setTitleComponent(LayeredLayout.encloseIn(searchBack, titleLabel));
f.getAnimationManager().onTitleScrollAnimation(titleLabel.createStyleAnimation("WhiteOnBlackTitleLeftMargin", 200));
f.setTransitionInAnimator(CommonTransitions.createCover(CommonTransitions.SLIDE_VERTICAL, false, 300));
f.setTransitionOutAnimator(CommonTransitions.createUncover(CommonTransitions.SLIDE_VERTICAL, true, 300));
}
public static void removeTransitionsTemporarily(final Form f) {
final Transition originalOut = f.getTransitionOutAnimator();
final Transition originalIn = f.getTransitionInAnimator();
f.setTransitionOutAnimator(CommonTransitions.createEmpty());
f.setTransitionInAnimator(CommonTransitions.createEmpty());
f.addShowListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
f.setTransitionOutAnimator(originalOut);
f.setTransitionInAnimator(originalIn);
f.removeShowListener(this);
}
});
}
}
The second listing appears in MapForm in showNavigationToolbar. This code goes through some additional refactoring later on and looks like this:
void showNavigationToolbar() {
final Container layer = getLayeredPane(MapForm.class, true);
final Container pinLayer = createPinLayer(layer);
Button back = new Button("", "TitleCommand");
FontImage.setMaterialIcon(back, FontImage.MATERIAL_ARROW_BACK);
CompletionContainer cc = new CompletionContainer();
AutoCompleteAddressInput from = new AutoCompleteAddressInput("Current Location", "From", layer, cc);
AutoCompleteAddressInput to = new AutoCompleteAddressInput("", "Where To?", layer, cc);
from.setCurrentLocation(LocationService.getCurrentLocation());
Image circle = createCircle();
Label fromSelected = new Label(circle);
Label toSelected = new Label(square);
SearchService.nameMyCurrentLocation(LocationService.getCurrentLocation(), name -> from.setTextNoEvent(name));
to.requestFocus();
lastFocused = to;
from.addFocusListener(createFromFocusListener(fromSelected, from, circle));
to.addFocusListener(createToFocusListener(fromSelected, circle, toSelected, to));
addMapListener((source, zoom, center) -> onMapChangeEvent(center));
Container navigationToolbar = BoxLayout.encloseY(back,
BorderLayout.centerCenterEastWest(from, null, fromSelected),
BorderLayout.centerCenterEastWest(to, null, toSelected)
);
navigationToolbar.setUIID("WhereToToolbar");
navigationToolbar.getUnselectedStyle().setBgPainter((g1, rect) ->
paintWhereToToolbarBackground(g1, layer, rect, fromSelected, circle, toSelected)
);
cc.addCompletionListener(e ->
onCompletionEvent(to, from, pinLayer, navigationToolbar, layer));
back.addActionListener(e ->
onBackFromNavigation(pinLayer, navigationToolbar, layer));
layer.add(NORTH, navigationToolbar);
navigationToolbar.setWidth(getDisplayWidth());
navigationToolbar.setHeight(getPreferredH());
navigationToolbar.setY(-navigationToolbar.getHeight());
getAnimationManager().addAnimation(layer.createAnimateLayout(200),
() -> cc.showCompletionBar(layer));
}
private FocusListener createToFocusListener(final Label fromSelected, Image circle, final Label toSelected, AutoCompleteAddressInput to) {
return new FocusListener() {
#Override
public void focusGained(Component cmp) {
fromSelected.setIcon(circle);
toSelected.setIcon(square);
lastFocused = to;
}
#Override
public void focusLost(Component cmp) {
toSelected.setIcon(circle);
}
};
}
private FocusListener createFromFocusListener(final Label fromSelected, AutoCompleteAddressInput from, Image circle) {
return new FocusListener() {
#Override
public void focusGained(Component cmp) {
fromSelected.setIcon(square);
lastFocused = from;
}
#Override
public void focusLost(Component cmp) {
fromSelected.setIcon(circle);
}
};
}

Related

Unusual Crop/GeneralPath behaviour in CodenameOne

I created a minor crop image app which crops the set image in a closed free path defined by the user (closed by joining the starting and ending point). This app is depicting unusual behavior when cropping in different path directions (clockwise and anticlockwise). Can anyone explain why is this happening and how to rectify this problem?
The following is the code:-
My own defined GeneralPath class
package com.mycompany.myapp;
import com.codename1.charts.util.ColorUtil;
import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.Graphics;
import com.codename1.ui.Stroke;
public class GeneralPath extends Component{
com.codename1.ui.geom.GeneralPath generalPath;
Stroke stroke = new Stroke();
int firstPointX = 0, firstpointY = 0;
MyApplication myApplication;
public GeneralPath(MyApplication application) {
// TODO Auto-generated constructor stub
generalPath = new com.codename1.ui.geom.GeneralPath();
stroke.setLineWidth(Math.max(1, Display.getInstance().convertToPixels(1, true)/2));
getAllStyles().setBgColor(0xffffff);
getAllStyles().setBgTransparency(200);
myApplication = application;
}
#Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
paintDrawing(g);
}
private void paintDrawing(Graphics g)
{
g.setColor(ColorUtil.argb(0, 255, 255, 255));
boolean oldAA = g.isAntiAliased();
g.setAntiAliased(true);
g.drawShape(generalPath, stroke);
g.setAntiAliased(oldAA);
}
#Override
public void pointerPressed(int a, int b) {
firstPointX = a;
firstpointY = b;
generalPath.moveTo(x(a), y(b));
}
#Override
public void pointerDragged(int a, int b) {
generalPath.lineTo(x(a), y(b));
}
#Override
public void pointerReleased(int x, int y) {
generalPath.lineTo(x(firstPointX), y(firstpointY));
myApplication.clip();
}
public int x(int x)
{
return x-getParent().getAbsoluteX();
}
public int y(int y)
{
return y - getParent().getAbsoluteY();
}
public com.codename1.ui.geom.GeneralPath getPath()
{
return generalPath;
}
}
MyApplication.java (main class)
package com.mycompany.myapp;
import com.codename1.io.Log;
import com.codename1.ui.Button;
import com.codename1.ui.Display;
import com.codename1.ui.FontImage;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.Stroke;
import com.codename1.ui.animations.CommonTransitions;
import com.codename1.ui.geom.GeneralPath;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.ui.util.UITimer;
import java.io.IOException;
import com.codename1.ui.Toolbar;
import com.codename1.ui.geom.Rectangle;
/**
* 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;
Form hi;
com.mycompany.myapp.GeneralPath gp;
Image finalDuke;
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("Welcome", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
// final Label apple = new Label(theme.getImage("apple-icon.png"));
// final Label android = new Label(theme.getImage("android-icon.png"));
// final Label windows = new Label(theme.getImage("windows-icon.png"));
// Button getStarted = new Button("Let's Get Started!");
// FontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_LINK);
// getStarted.setUIID("GetStarted");
// hi.addComponent(BorderLayout.CENTER,
// LayeredLayout.encloseIn(
// BoxLayout.encloseY(
// new Label(theme.getImage("duke-no-logos.png")),
// getStarted
// ),
// FlowLayout.encloseRightMiddle(apple)
// )
// );
//
// getStarted.addActionListener((e) -> {
// Display.getInstance().execute("https://www.codenameone.com/developers.html");
// });
//
// new UITimer(() -> {
// if(apple.getParent() != null) {
// apple.getParent().replace(apple, android, CommonTransitions.createFade(500));
// } else {
// if(android.getParent() != null) {
// android.getParent().replace(android, windows, CommonTransitions.createFade(500));
// } else {
// windows.getParent().replace(windows, apple, CommonTransitions.createFade(500));
// }
// }
// }).schedule(2200, true, hi);
Image duke = null;
try {
// duke.png is just the default Codename One icon copied into place
duke = theme.getImage("promo_5.png");
} catch(Exception err) {
Log.e(err);
}
finalDuke = duke;
hi = new Form("Shape Clip", new BorderLayout());
// We create a 50 x 100 shape, this is arbitrary since we can scale it easily
// GeneralPath path = new GeneralPath();
// path.moveTo(20,0);
// path.lineTo(30, 0);
// path.lineTo(30, 100);
// path.lineTo(20, 100);
// path.lineTo(20, 15);
// path.lineTo(5, 40);
// path.lineTo(5, 25);
// path.lineTo(20,0);
gp = new com.mycompany.myapp.GeneralPath(this);
hi.add(BorderLayout.CENTER,gp);
hi.getLayeredPane().add(finalDuke);
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = Display.getInstance().getCurrent();
}
}
public void destroy() {
}
public void clip()
{
Stroke stroke = new Stroke(0.5f, Stroke.CAP_ROUND, Stroke.JOIN_ROUND, 4);
// hi.getContentPane().getUnselectedStyle().setBgPainter((Graphics g, Rectangle rect) -> {
// g.setColor(0xff0000);
// float widthRatio = ((float)rect.getWidth()) / 50f;
// float heightRatio = ((float)rect.getHeight()) / 100f;
// g.scale(widthRatio, heightRatio);
// g.translate((int)(((float)rect.getX()) / widthRatio), (int)(((float)rect.getY()) / heightRatio));
// g.setClip(gp.getPath());
// g.setAntiAliased(true);
// g.drawImage(finalDuke, 0, 0, 50, 100);
// g.setClip(gp.getPath().getBounds());
// g.drawShape(gp.getPath(), stroke);
// g.translate(-(int)(((float)rect.getX()) / widthRatio), -(int)(((float)rect.getY()) / heightRatio));
// g.resetAffine();
// });
hi.getContentPane().getAllStyles().setBgPainter((Graphics g, Rectangle rect) -> {
g.drawShape(gp.getPath(), stroke);
g.setClip(gp.getPath());
Image image = finalDuke;
g.drawImage(image, 0, 0);
});
}
}
Please ignore the commented out portions. Thank you
ScreenShots:-
3 overlapping rectangles don't invert the picture during crop but a triangular shape in the opposite direction of that to the rectangle inversely cuts the previous paths
Try calling closePath() in pointerReleased. Even the user is almost closing the path manually, it might not really be closed. If you try to use an unclosed shape as a clip shape you'll get unexpected results.

How to draw on top of an Image in CodeName One?

I have been successful in drawing arbitrary paths on the whole screen by modifying the definition of SignaturePanel class according to need. Next, I want to want to able to draw on any picture selected by the user. Basically, the picture should remain in the background and I should be able to manipulate it. I tried the mutable image but I don't quite get how to implement it. Some sort of code to get me started would be greatly appreciated.
Here's what I have coded this far:
Main Class:-
package com.mycompany.myapp;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Button;
import com.codename1.ui.Container;
import com.codename1.ui.Dialog;
import com.codename1.ui.Label;
import com.codename1.ui.Painter;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.Resources;
import com.codename1.io.Log;
import com.codename1.io.MultipartRequest;
import com.codename1.ui.Toolbar;
import com.codename1.ui.URLImage;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Rectangle;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.LayeredLayout;
import com.codename1.ui.painter.PainterChain;
import java.io.IOException;
/**
* This file was generated by Codename One for the purpose
* of building native mobile applications using Java.
*/
public class MainClass {
private Form current;
private Resources theme;
SignaturePanel sp;
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.setLayout(new BorderLayout());
Button browseGallery = new Button("Browse");
Image test = Image.createImage(1280, 800, 0xffff00);
hi.add(BorderLayout.NORTH,test);
hi.addComponent(BorderLayout.SOUTH, browseGallery);
// browseGallery.addActionListener(new ActionListener<ActionEvent>() {
//
// #Override
// public void actionPerformed(ActionEvent evt) {
// Display.getInstance().openGallery(new ActionListener<ActionEvent>() {
//
// #Override
// public void actionPerformed(ActionEvent e) {
//
// }
// }, Display.GALLERY_IMAGE);
// }
// }
browseGallery.addActionListener(new ActionListener<ActionEvent>() {
#Override
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
Display.getInstance().openGallery(new ActionListener<ActionEvent>() {
#Override
public void actionPerformed(ActionEvent evt) {
// TODO Auto-generated method stub
try {
//Image mutable = Image.createImage(1280, 800, 0x00ff00);
//Image image = URLImage.createImage((String)evt.getSource());
//hi.add(BorderLayout.CENTER_BEHAVIOR_CENTER,mutable);
//image.modifyAlpha((byte) 10);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}, Display.GALLERY_IMAGE);
}
});
// hi.setGlassPane(new Painter() {
//
// #Override
// public void paint(Graphics g, Rectangle rect) {
// // TODO Auto-generated method stub
// System.out.println("glasspane");
// }
// });
sp = new SignaturePanel();
// hi.getLayeredPane();
// hi.add(LayeredLayout.encloseIn(new LayeredLayout(), sp);
System.out.println("before adding");
hi.addComponent(BorderLayout.CENTER, sp);
System.out.println("after adding");
hi.show();
}
public void stop() {
current = Display.getInstance().getCurrent();
if(current instanceof Dialog) {
((Dialog)current).dispose();
current = Display.getInstance().getCurrent();
}
}
public void destroy() {
}
}
SignaturePanel :-
package com.mycompany.myapp;
import com.codename1.ui.Component;
import com.codename1.ui.Display;
import com.codename1.ui.Font;
import com.codename1.ui.Graphics;
import com.codename1.ui.Image;
import com.codename1.ui.Stroke;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.GeneralPath;
import com.codename1.ui.geom.Rectangle;
class SignaturePanel extends Component {
private final GeneralPath path = new GeneralPath();
private final Stroke stroke = new Stroke();
private final Rectangle signatureRect = new Rectangle();
private final Font xFont;
private Image value;
SignaturePanel() {
stroke.setLineWidth(Math.max(1, Display.getInstance().convertToPixels(1, true)/2));
getAllStyles().setBgColor(0xffff00);
getAllStyles().setBgTransparency(10);
xFont = Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);
}
/**
* Overridden to try to make this component as sensitive as possible to
* drag events. If we don't do this, it requires a longer drag before the "drag"
* events will kick in.
* #param x
* #param y
* #return
*/
#Override
protected int getDragRegionStatus(int x, int y) {
return Component.DRAG_REGION_LIKELY_DRAG_XY;
}
/**
*
* #param g
*/
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(0x666666);
calcSignatureRect(signatureRect);
g.drawRect(signatureRect.getX(), signatureRect.getY(), signatureRect.getWidth(), signatureRect.getHeight());
g.drawString("X", signatureRect.getX() + Display.getInstance().convertToPixels(1, true), signatureRect.getY() + signatureRect.getHeight() / 2);
paintSignature(g);
}
/**
* Paints just the signature portion of the panel. This is is reuised to
* also create the image of the signature.
* #param g
*/
private void paintSignature(Graphics g) {
g.setColor(0x0);
boolean oldAA = g.isAntiAliased();
g.setAntiAliased(true);
g.drawShape(path, stroke);
g.setAntiAliased(oldAA);
}
/**
* Calculates a rectangle (in parent component space) used for the drawn "rectangle" inside
* which the user should draw their signature. It tries to create a 16x9 rectangle that
* fits inside the component with a bit of padding (3mm on each edge).
* #param r Output variable.
*/
private void calcSignatureRect(Rectangle r) {
int w = getWidth() - Display.getInstance().convertToPixels(6, true);
int h = (int)(w * 9.0 / 16.0);
if (h > getHeight()) {
h = getHeight() - Display.getInstance().convertToPixels(6, false);
w = (int)(h * 16.0 / 9.0);
}
r.setX(getX() + (getWidth() - w) / 2);
r.setY(getY() + (getHeight() - h)/2);
r.setWidth(w);
r.setHeight(h);
}
#Override
protected Dimension calcPreferredSize() {
Display d = Display.getInstance();
return new Dimension(d.convertToPixels(100, true), d.convertToPixels(60, false));
}
#Override
public void pointerPressed(int x, int y) {
path.moveTo(x(x), y(y));
value = null;
repaint();
}
#Override
public void pointerDragged(int x, int y) {
path.lineTo(x(x), y(y));
value = null;
repaint();
}
#Override
public void pointerReleased(int x, int y) {
value = null;
repaint();
}
/**
* Converts an x coordinate from screen space, to parent component space.
* #param x
* #return
*/
private int x(int x) {
return x - getParent().getAbsoluteX();
}
/**
* Converts a y coordinate from screen space to parent component space.
* #param y
* #return
*/
private int y(int y) {
return y - getParent().getAbsoluteY();
}
/**
* Gets the currently drawn signature as an image. This only includes the
* areas inside the {#link #signatureRect}
* #return
*/
private Image getImage() {
calcSignatureRect(signatureRect);
Image img = Image.createImage(signatureRect.getWidth(), signatureRect.getHeight(), 0xffffff);
Graphics g = img.getGraphics();
g.translate(-signatureRect.getX(), -signatureRect.getY());
paintSignature(g);
return img;
}
/**
* Resets the signature as a blank path.
*/
private void clear() {
path.reset();
}
}
Please ignore the commented out code
You can set the image as a background of your component as in sp.getAllStyles.setBgImage(), then override paint(Graphics g) on the component as you are now. You should then have the image with your drawn shapes laid on top.

I am unable to get video to play reliably in codenameone

I am at the point of abandoning using codenameone to build an app that allows me to play video from storage or to capture and play. Its either it is playing but no video is showing (most common ) or it plays only once and thats it - the fast forward and rewind buttons not working. I don't know if this is a simulator problem/limitation or whether I just don't know what I am doing.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.ixzdore.ziem.renderer.widgets;
import com.codename1.capture.Capture;
import com.codename1.components.ImageViewer;
import com.codename1.components.MediaPlayer;
import com.codename1.io.FileSystemStorage;
import com.codename1.io.Log;
import static com.codename1.io.Log.e;
import com.codename1.media.Media;
import com.codename1.media.MediaManager;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.layouts.BorderLayout;
import com.ixzdore.ziem.models.DocumentElement;
import com.ixzdore.ziem.models.ReportDocument;
import java.io.IOException;
/**
*
* #author jamesagada
*/
public class NVideo extends Widget {
private final Label _imageLabel = new Label();
private MediaPlayer _mPlayer;
private Container imageVideoContainer;
public NVideo(DocumentElement element, ReportDocument doc, Boolean isEditing) {
super(element, doc, isEditing);
imageVideoContainer = new Container(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE)) {
protected Dimension calcPreferredSize() {
return new Dimension(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayWidth());
}
};
_mPlayer = new MediaPlayer();
setupWidgetFromProperty();
}
#Override
public void renderEdit() {
//super.initLayout();
super.setEnabled(true);
}
public void renderSummary() {
//super.initLayout();
super.setEnabled(false);
getIconContainer().remove();
revalidate();
}
#Override
public void renderView() {
//find the
//super.initLayout();
super.setEnabled(false);
getIconContainer().remove();
revalidate();
}
#Override
public void setupWidgetFromProperty() {
super.setupWidgetFromProperty();
String videoFile = documentElement.getVideoFileFromValue(documentElement.getPropertyValue());
if (videoFile != null) {
try {
Media video = MediaManager.createMedia(videoFile, true);
if (_mPlayer == null) {
_mPlayer = new MediaPlayer();
}
_mPlayer.setDataSource(videoFile);
_mPlayer.setAutoplay(true);
if (imageVideoContainer == null) {
imageVideoContainer = new Container(new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE)) {
protected Dimension calcPreferredSize() {
return new Dimension(Display.getInstance().getDisplayWidth(), Display.getInstance().getDisplayWidth() );
}
};
}
getWidgetContainer().removeAll();
imageVideoContainer.add(BorderLayout.CENTER, _mPlayer);
imageVideoContainer.revalidate();
getWidgetContainer().add(imageVideoContainer);
getWidgetContainer().revalidate();
getWidgetContainer().repaint();
documentElement.setPropertyValue(videoFile);
} catch (Exception err) {
Log.e(err);
}
}
}
#Override
public void setupPropertyButtons() {
super.setupPropertyButtons();
//add a capture button and a browse button for gallery
//save captured picture and put the URL value in the propertyValue
final Widget _this = this;
_captureButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//open the capture button and take a video
String photoFile = Capture.captureVideo();
if (photoFile != null) {
try {
_mPlayer.setDataSource(photoFile);
_mPlayer.setAutoplay(false);
_mPlayer.revalidate();
_mPlayer.repaint();
imageVideoContainer.revalidate();
_this.revalidate();
documentElement.setPropertyValue(photoFile);
} catch (Exception err) {
Log.e(err);
}
}
}
});
_captureButton.setText("");
getIconContainer().add(_captureButton);
getIconContainer().revalidate();
getIconContainer().repaint();
getLabelContainer().repaint();
_findButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
Display.getInstance().openGallery(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ev) {
if (ev != null && ev.getSource() != null) {
String file = (String) ev.getSource();
try {
_mPlayer.setDataSource(file);
_mPlayer.setAutoplay(false);
_mPlayer.revalidate();
_mPlayer.repaint();
imageVideoContainer.revalidate();
imageVideoContainer.repaint();
_this.revalidate();
documentElement.setPropertyValue(file);
} catch (Exception err) {
Log.e(err);
}
}
}
}, Display.GALLERY_VIDEO);
}
});
_findButton.setText("");
getIconContainer().add(_findButton);
getIconContainer().revalidate();
getIconContainer().repaint();
getLabelContainer().repaint();
this.revalidate();
}
public void render(boolean editing) {
if (isEditing) {
renderEdit();
}
if (!isEditing) {
renderSummary();
}
}
}
`
What am I doing wrong or show me working code sample to achieve what I am trying to achieve.

ContactsContract.Contacts issue, duplicates

I've been doing research on this but I can't figure it out. My contacts in my phone in a sample app I downloaded are often duplicated, like so:
I'm quite sure it has something to do with ContactsContract.Contacts. I've read up on it but don't know how to implement it in my code. Could someone help (or indeed if there's another way of doing it). I just want each contact be listed once, not multiple time.
According to http://developer.android.com/reference/android/provider/ContactsContract.Contacts.html :
ContactsContract.Contacts
Constants for the contacts table, which contains a record per aggregate of raw contacts representing the same person.
I have 3 java files in my project, MainActivity, SelectUser and SelectUserAdapter, but I believe MainActivity is the one pertaining to this problem. Probably specifically this line :
phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
If you need more code just let me know.
Here's my MainActivity.java :
package com.example.chris.contactlistcustomlistview;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
// ArrayList
ArrayList<SelectUser> selectUsers;
List<SelectUser> temp;
// Contact List
ListView listView;
// Cursor to load contacts list
Cursor phones, email;
// Pop up
ContentResolver resolver;
SearchView search;
SelectUserAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectUsers = new ArrayList<SelectUser>();
resolver = this.getContentResolver();
listView = (ListView) findViewById(R.id.contacts_list);
phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
// retrieves contact information
LoadContact loadContact = new LoadContact();
loadContact.execute();
// let's set up our search box,
search = (SearchView) findViewById(R.id.searchView);
//*** setOnQueryTextListener ***
search.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
// when the text in searchView changes, call the filter function
adapter.filter(newText);
return false;
}
});
}
// Load data on background
class LoadContact extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
// Get Contact list from Phone
if (phones != null) {
Log.e("count", "" + phones.getCount());
if (phones.getCount() == 0) {
Toast.makeText(MainActivity.this, "No contacts in your contact list.", Toast.LENGTH_LONG).show();
}
while (phones.moveToNext()) {
Bitmap bit_thumb = null;
String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String EmailAddr = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA2));
String image_thumb = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI));
try {
if (image_thumb != null) {
bit_thumb = MediaStore.Images.Media.getBitmap(resolver, Uri.parse(image_thumb));
} else {
Log.e("No Image Thumb", "--------------");
}
} catch (IOException e) {
e.printStackTrace();
}
//what's happening here? For every user in the phonebook, show an image, the name, number, an id and maybe a checkbox?
SelectUser selectUser = new SelectUser();
selectUser.setThumb(bit_thumb);
selectUser.setName(name);
selectUser.setPhone(phoneNumber);
selectUser.setEmail(id);
selectUser.setCheckedBox(false);
selectUsers.add(selectUser);
}
} else {
Log.e("Cursor close 1", "----------------");
}
//phones.close();
return null;
}
#Override
// when DoInBackground is finished, when we have our phone number, name etc... display the results in our listview.
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
adapter = new SelectUserAdapter(selectUsers, MainActivity.this);
listView.setAdapter(adapter);
// Select item on listclick
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Log.e("search", "here---------------- listener");
SelectUser data = selectUsers.get(i);
}
});
listView.setFastScrollEnabled(true);
}
}
#Override
protected void onStop() {
super.onStop();
phones.close();
}
}
public class MainActivity extends Activity {
Cursor cursor;
ListView mainListView;
ArrayList hashMapsArrayList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (cursor != null) {
cursor.moveToFirst();}
try {
cursor = getApplicationContext().getContentResolver()
.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
int Idx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID);
int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int phoneNumberIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int photoIdIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_THUMBNAIL_URI);
cursor.moveToFirst();
Set<String> ids = new HashSet<>();
do {
System.out.println("=====>in while");
String contactid=cursor.getString(Idx);
if (!ids.contains(contactid)) {
ids.add(contactid);
HashMap<String, String> hashMap = new HashMap<String, String>();
String name = cursor.getString(nameIdx);
String phoneNumber = cursor.getString(phoneNumberIdx);
String image = cursor.getString(photoIdIdx);
System.out.println("Id--->"+contactid+"Name--->"+name);
System.out.println("Id--->"+contactid+"Name--->"+name);
System.out.println("Id--->"+contactid+"Number--->"+phoneNumber);
if (!phoneNumber.contains("*")) {
hashMap.put("contactid", "" + contactid);
hashMap.put("name", "" + name);
hashMap.put("phoneNumber", "" + phoneNumber);
hashMap.put("image", "" + image);
// hashMap.put("email", ""+email);
if (hashMapsArrayList != null) {
hashMapsArrayList.add(hashMap);}
// hashMapsArrayList.add(hashMap);
}
}
} while (cursor.moveToNext());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}

CodenameOne Charts not rendering well when sharing or simulator screen capture

The recent updates draw the lines on the charts when sharing, but the chart seems to get a bit mangled both when shared and when doing a screen capture on the simulator. The legend gets rotated and moved into the grid area, the title is missing, and there is a yellow outline that runs through the grid area.
Different chart renderings. The far right image got mirrored somehow when I pasted it, it isn't actually a mirror-image when shared.
Here is a test case:
package com.fastlaneinnovations.chartexample;
import com.codename1.charts.ChartComponent;
import com.codename1.charts.models.XYMultipleSeriesDataset;
import com.codename1.charts.models.XYSeries;
import com.codename1.charts.renderers.XYMultipleSeriesRenderer;
import com.codename1.charts.renderers.XYSeriesRenderer;
import com.codename1.charts.util.ColorUtil;
import com.codename1.charts.views.LineChart;
import com.codename1.components.ShareButton;
import com.codename1.io.FileSystemStorage;
import com.codename1.io.Log;
import com.codename1.ui.Container;
import com.codename1.ui.Display;
import com.codename1.ui.Form;
import com.codename1.ui.Image;
import com.codename1.ui.Label;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.plaf.UIManager;
import com.codename1.ui.util.ImageIO;
import com.codename1.ui.util.Resources;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Set;
public class ChartExample {
private Form current;
private Resources theme;
private XYMultipleSeriesRenderer chartRenderer;
private Container rpmChartContainer;
private XYSeries series;
private LineChart lineChart;
private ChartComponent chart;
private Hashtable<Long, Integer> chartData;
private String chartName = "Chart";
private String path;
private Object os;
private int chartHeight;
private int chartWidth;
private ShareButton share;
private Set<Long> keys;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if (current != null) {
current.show();
return;
}
Form form = new Form();
form.setLayout(new BorderLayout());
chartData = new Hashtable<Long, Integer>();
for (int i = 0; i < 8000; i += 100) {
chartData.put(Long.valueOf(i), Integer.valueOf(i));
}
rpmChartContainer = new Container();
rpmChartContainer.setLayout(new BorderLayout());
series = new XYSeries("RPM");
chartRenderer = createChartRenderer();
setChartSettings(chartRenderer, "RPM vs Time", "Time (s)", "RPM", 0.0,
10.0, 0.0, 8000.0, ColorUtil.YELLOW, ColorUtil.WHITE);
lineChart = new LineChart(buildDataSet(series), chartRenderer);
chart = new ChartComponent(lineChart);
chart.setUIID("ChartComponent");
rpmChartContainer.addComponent(BorderLayout.CENTER, chart);
updateChart();
share = new ShareButton();
share.setName(chartName);
share.setText("Share this chart");
share.setTextToShare("RPM chart created by R-P-M Control Center app");
rpmChartContainer.add(BorderLayout.SOUTH, share);
form.add(BorderLayout.CENTER, rpmChartContainer);
form.show();
createShareButton();
}
public void stop() {
current = Display.getInstance().getCurrent();
}
public void destroy() {
}
public void updateChart() {
keys = chartData.keySet();
series.clear();
for (Long key : keys) {
series.add((key / 1000.0), (chartData.get(key) / 1.0));
}
}
private XYMultipleSeriesRenderer createChartRenderer() {
XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
renderer.setPointSize(3f);
XYSeriesRenderer seriesRenderer = new XYSeriesRenderer();
seriesRenderer.setColor(ColorUtil.GREEN);
// seriesRenderer.setPointStyle(PointStyle.CIRCLE);
// seriesRenderer.setFillPoints(true);
seriesRenderer.setLineWidth(5f);
seriesRenderer.setShowLegendItem(true);
renderer.addSeriesRenderer(seriesRenderer);
return renderer;
}
private XYMultipleSeriesDataset buildDataSet(XYSeries dataSeries) {
XYMultipleSeriesDataset multiDataSet = new XYMultipleSeriesDataset();
multiDataSet.addSeries(dataSeries);
return multiDataSet;
}
private void setChartSettings(XYMultipleSeriesRenderer renderer,
String title, String xTitle, String yTitle, double xMin,
double xMax, double yMin, double yMax, int axesColor,
int labelsColor) {
renderer.setChartTitle(title);
renderer.setXTitle(xTitle);
renderer.setYTitle(yTitle);
renderer.setXAxisMin(xMin);
// renderer.setXAxisMax(xMax);
renderer.setYAxisMin(yMin);
renderer.setYAxisMax(yMax);
renderer.setAxesColor(axesColor);
renderer.setLabelsColor(labelsColor);
renderer.setMarginsColor(ColorUtil.BLACK);
renderer.setGridColor(ColorUtil.BLACK);
}
public void createShareButton() {
rpmChartContainer.revalidate();
chartWidth = rpmChartContainer.getWidth();
chartHeight = rpmChartContainer.getHeight();
Image chartAsImage = Image.createImage(chartWidth, chartHeight);
rpmChartContainer.paint(chartAsImage.getGraphics());
setShareImage(share, chartAsImage);
}
public void setShareImage(ShareButton shareButton, Image shareImage) {
OutputStream os = null;
final String shareImagePath = FileSystemStorage.getInstance()
.getAppHomePath() + shareButton.getName();
FileSystemStorage.getInstance().delete(shareImagePath);
try {
os = FileSystemStorage.getInstance().openOutputStream(
shareImagePath);
ImageIO.getImageIO().save(shareImage, os, ImageIO.FORMAT_JPEG,
0.95f);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
os.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
shareButton.setImageToShare(shareImagePath, "image/jpeg");
}
}
In implementing the 2D transformations on iOS mutable images, I fixed some bugs related to transforms on mutable images in the simulator. You may not have these until the next plugin update.
As for the third image on the right in your screenshot. What device was that from? Can you share a test case with your chart so I can test it out?

Resources