Re textArea growByLimit issues in layerLayout - codenameone

I set the textArea setGrowByContent true and setGrowLimit to 2, but there is always only one row. So i twisted the code and increase the
height of textArea by twice if the size of textArea is greater than Button size. Below is the codes. My issue is at the end of the question:
Button homeButtonn = new Button(btnIcon){
#Override
protected Dimension calcPreferredSize() {
System.out.println("Button size: " + super.calcPreferredSize());
return super.calcPreferredSize();
}
#Override
public void setUIID(String id) {
super.setUIID("homeButtonn");
}
};
TextArea buttonTitle = new TextArea(title){
#Override
protected Dimension calcPreferredSize() {
System.out.println("textArea title: " + getText());
System.out.println("Textarea size: " +super.calcPreferredSize());
System.out.println("");
return super.calcPreferredSize();
}
};
buttonTitle.setUIID("smallLabel");
buttonTitle.getAllStyles().setAlignment(Label.LEFT);
zeroPaddingMargin(buttonTitle);
if (buttonTitle.getPreferredW() -10 > homeButtonn.getPreferredW()) {
buttonTitle.setPreferredH(buttonTitle.getPreferredH() * 2);
}
buttonTitle.setPreferredW(homeButtonn.getPreferredW() - 10);
buttonTitle.getAllStyles().setMargin(3, 3, 3, 3);
buttonTitle.setEditable(false);
buttonTitle.setGrowByContent(true);
buttonTitle.setGrowLimit(2);
buttonTitle.setScrollVisible(false);
gridContainer.add(LayeredLayout.encloseIn(homeButtonn, FlowLayout.encloseRightBottom(buttonTitle)));
OUTPUT:
Button size: width = 146 height = 140
textArea title: DJ and Sound
Textarea size: width = 194 height = 25
Here textArea size is greater than button size but if i set size of the textArea with exact size of button,
it fits well. So how can textArea size be greater than button size and also all texts of textArea fits well inside button?
The problem i got is that since textArea size is greater than button size, the height of textArea is multiplied by twice its own height but
textArea fit well in single line and it leaves extra line/row below.
PS see the screenshot. Thankyou
without calcPreferred size or preferredSize:
If calcPreferredSize is removed, it takes whole screenwidth though it is in gridlayout with 3 column
Update:
Recent Code without calcPreferredSize & textArea nested in a container too
GridLayout gl2 = new GridLayout(counter / 3 + 1, 3);
gl2.setAutoFit(true);
Container gridContainer = new Container(gl2);
gridContainer.setScrollableY(true);
f.addComponent(gridContainer);
imageUrl = entry.get("img").toString();
title = entry.get("name").toString();
homePlaceholder = homePlaceholder.scaled(screenWidth / 3 - 20, screenWidth / 3 - 26);
encodedHomePlaceholder = EncodedImage.createFromImage(homePlaceholder, true);
Image btnIcon = URLImage.createToStorage(encodedHomePlaceholder, "home_" + title + imageUrl, allUrl.globalHomeImageUrl + imageUrl, URLImage.RESIZE_SCALE_TO_FILL);
homeButton.setIcon(btnIcon);
TextArea buttonTitle = new TextArea(title);
buttonTitle.getAllStyles().setAlignment(Label.LEFT);
buttonTitle.getAllStyles().setMargin(3, 3, 3, 3);
buttonTitle.setEditable(false);
buttonTitle.setGrowByContent(true);
buttonTitle.setGrowLimit(2);
buttonTitle.setScrollVisible(false);
Container btnTitleContainer = new Container();
btnTitleContainer.addComponent(buttonTitle);
gridContainer.add(LayeredLayout.encloseIn(homeButton, FlowLayout.encloseRightBottom(btnTitleContainer)));
f.revalidate();

Don't use calcPreferredSize, setPreferred* or any such API when you want something to be automatically calculated.
By definition you are disabling the automatic calculation when you are using these APIs that is why most of those API's are deprecated.
You need to only use layout logic.

What ever i did to make it right in layer layout and textarea, it didnt work so i tried other things and it work. I set the bg image of the container with border layout & keep the textarea in the south of borderlayout.
homePlaceholder = homePlaceholder.scaled(screenWidth / 3, screenWidth / 3);
encodedHomePlaceholder = EncodedImage.createFromImage(homePlaceholder, true);
Image btnIcon = URLImage.createToStorage(encodedHomePlaceholder, "home_" + title + imageUrl, allUrl.globalHomeImageUrl + imageUrl, URLImage.RESIZE_SCALE_TO_FILL);
Container innerContainer = new Container(new BorderLayout());
innerContainer.getAllStyles().setBgImage(btnIcon);
innerContainer.getAllStyles().setBackgroundType(Style.BACKGROUND_IMAGE_SCALED);
gridContainer.add(innerContainer);
TextArea buttonTitle = new TextArea(properCase(title));
buttonTitle.setUIID("smallLabel");
zeroPaddingMargin(buttonTitle);
innerContainer.add(BorderLayout.SOUTH,buttonTitle);
buttonTitle.setEditable(false);
buttonTitle.setGrowByContent(true);
buttonTitle.setGrowLimit(2);
buttonTitle.setScrollVisible(false);
gridContainer.revalidate();

Related

EncodedImage failing to work on actual phone

I am facing a problem while using encodedImage. When a user logins into the app, the first form after successful login has an image. And the image is causing me issues upon retrieving it.
When the user captures an image in the app, I convert it to a base64 string which I send to the server. The code for that is:
ImageIO img = ImageIO.getImageIO();
ByteArrayOutputStream out = new ByteArrayOutputStream();
img.save(et, out, ImageIO.FORMAT_JPEG, 1);
byte[] ba = out.toByteArray();
String userImage64 = Base64.encodeNoNewline(ba);
et is the captured image. So I store the string userImage64 in the server.
When I retrieve the base64, I decode it and convert it to an EncodedImage. The code is:
String url = new JSONObject(result.getResponseData()).getString("photo");
byte[] b = Base64.decode(url.getBytes());
Image icon = EncodedImage.create(b);
When I am on the simulator, everything flows smoothly. The images display and everything works very well.
My issue is, when I put the app on an android device, it doesn't work. It shows me a toast of successful login and just stops there. So i did some debugging and realized that issue is with the three lines of converting from base64 to image. When I comment out the three lines, everything works very well. Where could I be going wrong?
EDIT
Below is the code I use to capture a photo:
String i = Capture.capturePhoto();
if (i != null) {
try {
final Image newImage = Image.createImage(i);
Image roundedMask = Image.createImage(rich.minScreensize() / 4, rich.minScreensize() / 4, 0xff000000);
Graphics gra = roundedMask.getGraphics();
gra.setColor(0xffffff);
gra.fillArc(0, 0, rich.minScreensize() / 4, rich.minScreensize() / 4, 0, 360);
Object masked = roundedMask.createMask();
cropImage(newImage, rich.minScreensize() / 4, rich.minScreensize() / 4, et -> {
if (editing) {
try {
ImageIO img = ImageIO.getImageIO();
ByteArrayOutputStream out = new ByteArrayOutputStream();
img.save(et, out, ImageIO.FORMAT_JPEG, 1);
byte[] ba = out.toByteArray();
userImage64 = Base64.encodeNoNewline(ba);
et = et.applyMask(masked);
logoimage.setIcon(et);
///removed unnecessary code
logoimage.getComponentForm().revalidate();
} catch (IOException ex) {
}
} else {
et = et.applyMask(masked);
logoimage.setIcon(et);
}
});
} catch (IOException ex) {
Log.p("Error loading captured image from camera", Log.ERROR);
}
}
Inside there is code I use to crop the photo and that is code is:
private void cropImage(Image img, int destWidth, int destHeight, OnComplete<Image> s) {
Form previous = getCurrentForm();
Form cropForm = new Form("", new LayeredLayout());
Label toobarLabel = new Label("New Holder", "Toolbar-HeaderLabel");
cropForm.setTitleComponent(toobarLabel);
Toolbar mainToolbar = new Toolbar();
mainToolbar.setUIID("ToolBar");
cropForm.setToolbar(mainToolbar);
Label moveAndZoom = new Label("Move and zoom the photo to crop it");
moveAndZoom.getUnselectedStyle().setFgColor(0xffffff);
moveAndZoom.getUnselectedStyle().setAlignment(CENTER);
moveAndZoom.setCellRenderer(true);
cropForm.setGlassPane((Graphics g, Rectangle rect) -> {
g.setColor(0x0000ff);
g.setAlpha(150);
Container cropCp = cropForm.getContentPane();
int posY = cropForm.getContentPane().getAbsoluteY();
GeneralPath p = new GeneralPath();
p.setRect(new Rectangle(0, posY, cropCp.getWidth(), cropCp.getHeight()), null);
if (isPortrait()) {
p.arc(0, posY + cropCp.getHeight() / 2 - cropCp.getWidth() / 2,
cropCp.getWidth() - 1, cropCp.getWidth() - 1, 0, Math.PI * 2);
} else {
p.arc(cropCp.getWidth() / 2 - cropCp.getHeight() / 2, posY,
cropCp.getHeight() - 1, cropCp.getHeight() - 1, 0, Math.PI * 2);
}
g.fillShape(p);
g.setAlpha(255);
g.setColor(0xffffff);
moveAndZoom.setX(0);
moveAndZoom.setY(posY);
moveAndZoom.setWidth(cropCp.getWidth());
moveAndZoom.setHeight(moveAndZoom.getPreferredH());
moveAndZoom.paint(g);
});
final ImageViewer viewer = new ImageViewer();
viewer.setImage(img);
cropForm.add(viewer);
cropForm.getToolbar().addMaterialCommandToRightBar("", FontImage.MATERIAL_CROP, e -> {
previous.showBack();
s.completed(viewer.getCroppedImage(0).
fill(destWidth, destHeight));
});
cropForm.getToolbar().addMaterialCommandToLeftBar("", FontImage.MATERIAL_CANCEL, e -> previous.showBack());
cropForm.show();
}

Codename One - setScrollVisible in two examples of code

This question is related to this one: Codename One - container.setScrollVisible(true) in the center of a BorderLayout
In the following example of code the setScrollVisible(true) works correctly when the user expands the Accordion (that occupies more space that the height of the screen) and does the scrolling:
Form hi = new Form("Hi World", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE));
Container body = new Container(BoxLayout.y());
for (int i = 0; i < 100; i++) {
body.add(new Label("Label " + i));
}
Accordion accordion = new Accordion();
accordion.addContent("Tap to expand", body);
Container center = new Container(BoxLayout.y());
center.add(accordion);
center.setScrollableY(true);
center.setScrollVisible(true);
center.getAllStyles().setPaddingUnit(Style.UNIT_TYPE_DIPS);
center.getAllStyles().setPadding(2, 2, 2, 2);
hi.add(BorderLayout.CENTER, center);
hi.show();
But in this other example of code, the setScrollVisible(true) doesn't work when the user expands all the Accordions (that occupy more space that the height of the screen) and does the scrolling:
Form hi = new Form("Hi World", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_SCALE));
// Warning: you need to set the theme property "ComponentGroupBool" to true
Button button1 = new Button("Button 1", "ButtonMenuCategories");
CheckBox button11 = CheckBox.createToggle("Button 1.1");
CheckBox button12 = CheckBox.createToggle("Button 1.2");
Button button13 = new Button("Button 1.3", "ButtonMenuCategories");
CheckBox button131 = CheckBox.createToggle("Button 1.3.1");
CheckBox button132 = CheckBox.createToggle("Button 1.3.2");
CheckBox button133 = CheckBox.createToggle("Button 1.3.3");
CheckBox button14 = CheckBox.createToggle("Button 1.4");
Button button2 = new Button("Button 2", "ButtonMenuCategories");
Button button3 = new Button("Button 3", "ButtonMenuCategories");
Button button4 = new Button("Button 4", "ButtonMenuCategories");
Button button5 = new Button("Button 5", "ButtonMenuCategories");
Accordion accordion13 = new Accordion();
ComponentGroup cmpGroup1 = ComponentGroup.enclose(button131, button132, button133);
cmpGroup1.setScrollable(false);
accordion13.addContent(button13, FlowLayout.encloseCenter(cmpGroup1));
Accordion accordion1 = new Accordion();
ComponentGroup cmpGroup2 = ComponentGroup.enclose(button11, button12, accordion13, button14);
cmpGroup2.setScrollable(false);
accordion1.addContent(button1, FlowLayout.encloseCenter(cmpGroup2));
Accordion accordion2 = new Accordion();
accordion2.addContent(button2, new Label("Hello"));
Accordion accordion3 = new Accordion();
accordion3.addContent(button3, new Label("Hello"));
Accordion accordion4 = new Accordion();
accordion4.addContent(button4, new Label("Hello"));
Accordion accordion5 = new Accordion();
accordion5.addContent(button5, new Label("Hello"));
ComponentGroup cmpGroup = ComponentGroup.enclose(accordion1, accordion2, accordion3, accordion4, accordion5);
Container menu = FlowLayout.encloseCenter(cmpGroup);
accordion13.setScrollable(false);
accordion1.setScrollable(false);
accordion2.setScrollable(false);
accordion3.setScrollable(false);
accordion4.setScrollable(false);
accordion5.setScrollable(false);
cmpGroup.setScrollable(false);
menu.setScrollableY(true);
menu.setScrollVisible(true);
hi.add(BorderLayout.CENTER, menu);
hi.show();
What's wrong in the second example of code?

MultiList not showing complete text (Codename One)

Im using a MultiList to display some result from a web service but the address is not showing up completely.
Please this picture
The first address should be "Jalan Gertak Merah, 80000 Johor Bahru, Johor, Malaysia" and not "Jalan Gertak Merah, 80"
How can I correct this please.
This is my code:
Style s = UIManager.getInstance().getComponentStyle("Button");
FontImage p = FontImage.createMaterial(FontImage.MATERIAL_PORTRAIT, s);
EncodedImage placeholder = EncodedImage.createFromImage(p.scaled(p.getWidth() * 3, p.getHeight() * 4), false);
f.setTitle("Tourist Attractions");
getattractive();
ArrayList arr = (ArrayList) response.get("results");
for (Object m : arr) {
Map ma = (Map) m;
address = (String) ma.get("formatted_address");
name = (String) ma.get("name");
icon = (String) ma.get("icon");
data.add(createListEntry(name, address, icon));
}
DefaultListModel<Map<String, Object>> model = new DefaultListModel<>(data);
MultiList ml = new MultiList(model);
ml.getUnselectedButton().setIconName("icon_URLImage");
ml.getSelectedButton().setIconName("icon_URLImage");
ml.getUnselectedButton().setIcon(placeholder);
ml.getSelectedButton().setIcon(placeholder);
findContainer(f).add(BorderLayout.CENTER, ml);
c.addComponent(bn);
bn.addActionListener((ActionEvent evt) -> {
System.exit(0);
});
findContainer(f).add(BorderLayout.SOUTH, c);
f.getComponentForm().revalidate();

Add text to picture in Windows Universal app

I have universal app created for Win 10 mobile which captures photo. I want to add stamp (some text) to my photo. Is it possible? It seems working with bitmap is really difficult in universal applications
Check this link:
How to add wartermark text/image to a bitmap in Windows Store app
Or better use Win2D library (you can find it on NuGet) and snippet like this:
CanvasDevice device = CanvasDevice.GetSharedDevice();
CanvasRenderTarget offscreen = new CanvasRenderTarget(device, 500, 500, 96);
cbi = await CanvasBitmap.LoadAsync(device, "mydog.jpg");
using (var ds = offscreen.CreateDrawingSession())
{
ds.DrawImage(cbi);
var format = new CanvasTextFormat()
{
FontSize = 24,
HorizontalAlignment = CanvasHorizontalAlignment.Left,
VerticalAlignment = CanvasVerticalAlignment.Top,
WordWrapping = CanvasWordWrapping.Wrap,
FontFamily = "Tahoma"
};
var tl = new CanvasTextLayout(ds, "Some text", format, 200, 50); // width 200 and height 50
ds.DrawTextLayout(tl, 10, 10, Colors.Black);
tl.Dispose();
}
using (var stream = new InMemoryRandomAccessStream())
{
stream.Seek(0);
await offscreen.SaveAsync(stream, CanvasBitmapFileFormat.Png);
BitmapImage image = new BitmapImage();
image.SetSource(stream);
img.Source = image;
}

div align right checkboxInput in shiny dashboard not working

My shiny dashboard has checkboxInput and I am trying to align it to right within the title of the box item. For smaller boxes (width of 6) the alignment is proper, however for boxes with width of 12, which ever way I realign the column values, the checkbox input remains at the middle of the box. The code is as follows:
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
skin = "green",
dashboardHeader(
title = "TEST", titleWidth = 225
),
dashboardSidebar(
menuItem("TRENDS", tabName = "vactr", icon = shiny::icon("line-chart"))
),
dashboardBody(
tabItems(
tabItem(
tabName = "vactr",
fluidRow(
box(
width = 12, status = "info", title =
fluidRow(
column(6, "Trend - Usage of space",br(),
div(downloadLink("downloadspacetrend", "Download this chart"), style = "font-size:70%", align = "left")),
column(6,
div(checkboxInput(inputId = "spacetrendcheck", "Add to reports", value = FALSE),style = "font-size:70%",float = "right", align = "right", direction = "rtl"))
),
div(plotOutput("spacetrend"), width = "100%", height = "400px", style = "font-size:90%;"),
uiOutput("spacetrendcomment")
)
)
)
)
)
)
server <- function(input, output, session) {
}
shinyApp(ui = ui, server = server)
I want the "Add to reports" check box to the right end of the box. I tried using float, direction arguments with and without, but not getting the desired output.
There is the following reason for you problem: The header title's width is not set to the whole width of the box. Instead, its width is calculated from the elements it contains. This makes the columns (which are 50% title width) also depend on the elements. Your elements however are not that big, so the resulting div is in itself well divided in two equally large columns, but they together don't span the whole box width.
You can just fix the title width to 100% (box header width), which as a result tells the columns to be that large, whatever their content might be.
This is a one line addition.
Note that the style addition in the code below affects all box titles. But I believe that this is never really a problem.
library(shiny)
library(shinydashboard)
ui <- dashboardPage(
skin = "green",
dashboardHeader(
title = "TEST", titleWidth = 225
),
dashboardSidebar(
menuItem("TRENDS", tabName = "vactr", icon = shiny::icon("line-chart"))
),
dashboardBody(
tabItems(
tabItem(tabName = "vactr",
fluidRow(
box(width = 12, status = "info", title =
fluidRow(
tags$style(".box-title {width: 100%;}"),
column(6, "Trend - Usage of space",br(),
div(downloadLink("downloadspacetrend", "Download this chart"), style = "font-size:70%", align = "left")),
column(6,
div(checkboxInput(inputId = "spacetrendcheck", "Add to reports", value = FALSE),style = "font-size:70%",float = "right", align = "right", direction = "rtl"))
),
div(plotOutput("spacetrend"), width = "100%", height = "400px", style = "font-size:90%;"),
uiOutput("spacetrendcomment")
)
)
)
)
)
)
server <- function(input, output, session) {}
shinyApp(ui = ui, server = server)

Resources