I want to make a component clickable. I am using this approach : https://groups.google.com/forum/#!topic/codenameone-discussions/hfVoqRwd9lI (create a component with custom style, and set multibutton as lead component into that container).
This is my code :
Component[] listingsToAdd = new Component[listings.size()];
for (int iter = 0; iter < listingsToAdd.length; iter++) {
MultiButton mb = new MultiButton();
final Map<String, Object> currentListing = listings.get(iter);
Container c = new Container(new BoxLayout((BoxLayout.Y_AXIS)));
String guid = (String) currentListing.get("seq").toString();
Label date = new Label((String) currentListing.get("dt"));
Label name = new Label((String) currentListing.get("name"));
Label startMt = new Label((String) currentListing.get("start_mt"));
Label place = new Label((String) currentListing.get("place"));
Label description = new Label((String) currentListing.get("description"));
c.add(date).add(name).add(startMt).add(place).add(description);
mb.addActionListener(evt
-> showScheduleDetails(searchResults, currentListing));
c.setLeadComponent(mb);
listingsToAdd[iter] = c;
}
But, when I run it, the container still can't be clickable. How to solve that?
MultiButton is already a lead component. You should set a regular Button or any component that doesn't derive Container as your lead.
Related
I'm working on a rather complex solution that takes an html-like input and converts it to a pdf. One of the many items that I'm trying to solve for is adding barcodes (all types, 3 of 9, PDF417, and qr code) to the footer of documents.
A couple details that give me pause on how to implement:
Bar code will contain current page number
Bar code will contain total page count
Bar code will be inside other itext elements (like a table cell or paragraph) and (in the final solution) needs to be parsed out ahead of time
Knowing those details, I'm struggling a bit on how to combine barcodes with something like the page x of y strategy of using a template to replace page count after rendering all the content.
I assume that each bar code will need it's own template because of the page count, and keep track of the templates until all the content is rendered and then update each individual template with the appropriate bar code. But because the footer is parsed out ahead of time, I need a template that represents a bar code so that the footer will have the correct height and content can be adjusted appropriately.
I believe that each of these pieces need to be handled in the event handler for end of page, is that a correct assessment?
UPD Edited to include code sample. I pulled out quite a bit of the other stuff I was trying to accomplish from this example. As for the parsed ahead of time, instead of going over a loop from 1 to 20 and creating random elements, some other process creates all the elements that need to be present on the document and will pass in that list of elements to the renderer. That does include the footer content as well. In this case I'm creating the footer table in the constructor of the HeaderHandler as that is close to the same concept. The reason I bring this up is that I won't be able to create the table in the HandleEvent of the handler like in most examples I have seen about tables in footers. Hope that makes sense.
void Main()
{
PdfDocument pdf = new PdfDocument(new PdfWriter(Dest));
PageSize pageSize = PageSize.A4;
Document doc = new Document(pdf, pageSize, true);
HeaderHandler hh = new HeaderHandler(doc);
...
some other object generation
...
// create random paragraphs to fill up multiple pages in the final solution this would have already happened.
for (var i = 0; i < 20; i++)
AddItemToList(elementList, i, objects);
// add random elements back to the document
foreach (var e in elementList)
{
... add each item just added to elementList to the document ...
}
renderer.Flush();
hh.UpdateTotal(pdf);
// I think I need to update all the barcodes and print them out here so that page count part of the barcode can be written
doc.Close();
}
class HeaderHandler : IEventHandler
{
Table Footer;
Document Doc;
public Margin First;
public Margin Middle;
public Margin Last;
public Dictionary<int, Margin> PageMargins { get; set; }
public float HeaderHeight { get; }
public float FooterHeight { get; }
PdfFormXObject PgCount;
Text PageNumber;
Dictionary<string, PdfFormXObject> BarcodeImages;
public HeaderHandler(Document doc)
{
Doc = doc;
Footer = new Table(new float[] { 4, 2, 4}).SetAutoLayout();
PageMargins = new Dictionary<int, Margin>();
BarcodeImages = new Dictionary<string, PdfFormXObject>();
var pageSize = Doc.GetPdfDocument().GetDefaultPageSize();
var width = pageSize.GetRight() - pageSize.GetLeft() - Doc.GetLeftMargin() - Doc.GetRightMargin();
// page total
PgCount = new PdfFormXObject(new Rectangle(0,0, 13, 13));
Footer.AddCell(new Cell().Add(new Paragraph("info 1")));
PageNumber = new Text("{page}");
var cell = new Cell().Add(new Paragraph().Add(PageNumber).Add(" of ").Add(new Image(PgCount)).Add(" pages").SetTextAlignment(TextAlignment.CENTER));
Footer.AddCell(cell);
Footer.AddCell(new Cell().Add(new Paragraph("info 2")));
Footer.AddCell("footer 1");
Footer.AddCell("footer 2");
// I think I need to add a template here for the barcode as a placeholder so that when the renderersubtree is ran it provides space for the barcode
Footer.AddCell(new Cell().Add(new Paragraph("{barcode} {qr code - {page} | {pagect} | doc name}")));
TableRenderer fRenderer = (TableRenderer)Footer.CreateRendererSubTree();
using (var s = new MemoryStream())
{
fRenderer.SetParent(new Document(new PdfDocument(new PdfWriter(s))).GetRenderer());
FooterHeight = fRenderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4))).GetOccupiedArea().GetBBox().GetHeight();
}
}
public void UpdateTotal(PdfDocument pdf) {
Canvas canvas = new Canvas(PgCount, pdf);
canvas.ShowTextAligned(pdf.GetNumberOfPages().ToString(), 0, -3, TextAlignment.LEFT);
}
//draw footer and header tables
public void HandleEvent(Event e)
{
PdfDocumentEvent docEvent = e as PdfDocumentEvent;
if (docEvent == null)
return;
PdfDocument pdf = docEvent.GetDocument();
PdfPage page = docEvent.GetPage();
PdfCanvas pdfCanvas = new PdfCanvas(page.GetLastContentStream(), page.GetResources(), pdf);
int pageNum = pdf.GetPageNumber(page);
var pageSize = Doc.GetPdfDocument().GetDefaultPageSize();
Margin activeMargin = new Margin();
if (PageMargins.ContainsKey(pageNum))
activeMargin = PageMargins[pageNum];
var width = pageSize.GetRight() - pageSize.GetLeft() - activeMargin.Left - activeMargin.Right;
Header.SetWidth(width);
Footer.SetWidth(width);
var pageReferences = new List<TextRenderer>();
// update page number text so it can be written to in the footer
PageNumber.SetText(pageNum.ToString());
// draw the footer
rect = new Rectangle(pdf.GetDefaultPageSize().GetX() + activeMargin.Left, activeMargin.Bottom - GetFooterHeight(), 100, GetFooterHeight());
canvas = new Canvas(pdfCanvas, pdf, rect);
// I think it's here that I need to be able to add a barcode placeholder to something that can be called
canvas.Add(Footer);
}
public float GetFooterHeight()
{
return FooterHeight;
}
}
I have a custom control, basically a stacklayout that I can bind a concatenated string, and have this break up into multiple objects, like a tag list.
public void Render()
{
if (ItemsSource == null)
return;
this.Orientation = Orientation == StackOrientation.Vertical ? StackOrientation.Vertical : StackOrientation.Horizontal;
this.Margin = new Thickness (0, 0, 0, 0);
List<string> items = ItemsSource.Split('|').ToList();
foreach (var item in items)
{
var frame = new Frame();
frame.BindingContext = item;
frame.BackgroundColor = Color.FromHex("#FCFACF");
frame.OutlineColor = Color.FromHex("#D0C0AD");
frame.HasShadow = false;
frame.Padding = new Thickness(4, 2, 4, 0);
var label = new Label();
label.Text = "{Binding}";
label.FontSize = 10;
label.Parent = frame;
Children.Add(frame);
}
}
but I can't seem to get this right, how do I add a lable to be a child of a frame, and how can I fix my binding, as at present if I add the label to the children of the stacklayout the text of the labels is {binding} and not the actual text.
Can someone please help me with this. I had all of this working if I added a ItemTemplate with a datatemplate and viewcell in the XAML, but I don't want this done in XAML as I'd like to reuse all of this in other views.
Frame has Content property
Frame.Content = label;
To assign a binding in code, use
label.SetBinding(Label.TextProperty, new Binding("."));
I'm adding a list of images from a directory using an arraylist.When images are added,my ScrollPane gets crowded.How can I keep spacings between images ?
here's my code
File file = new File("D:\\SERVER\\Server Content\\Apps\\icons");
File[] filelist1 = file.listFiles();
ArrayList<File> filelist2 = new ArrayList<>();
hb = new HBox();
for (File file1 : filelist1) {
filelist2.add(file1);
}
System.out.println(filelist2.size());
gridpane.setPadding(new Insets(50,50,50,50));
gridpane.setHgap(20);
gridpane.setVgap(20);
int imageCol = 0;
int imageRow = 0;
for (int i = 0; i < filelist2.size(); i++) {
System.out.println(filelist2.get(i).getName());
image = new Image(filelist2.get(i).toURI().toString());
pic = new ImageView();
pic.setFitWidth(130);
pic.setFitHeight(130);
pic.setImage(image);
hb.getChildren().add(pic);
gridpane.add(pic, imageCol, imageRow );
imageCol++;
// To check if all the 4 images of a row are completed
if(imageCol > 2){
// Reset Column
imageCol=0;
// Next Row
imageRow++;
}
Try using HBox and VBox.
Basically, they are like little containers where you store your stuff and you can add gaps into it!
HBox ab = new HBox(10); <--The 10 is adding space (Answer to your question)
If you want to add stuff into HBox, simply write
ab.getChildren().addAll(your content here);
I have a bunch of GeoCoordinate objects that I wish to display as a polyline (to show a path a person has taken).
My unsuccessful attempt (Does not display any line):
var map = new Map(); // Nokia Maps
var layer = new MapLayer();
var overlay = new MapOverlay();
var polyline = new MapPolyline();
var gc = new GeoCoordinateCollection();
foreach(var geo in MyGeoCoordinateList) {
gc.Add(geo);
}
polyline.Path = gc;
polyline.StrokeColors = Colors.Red;
polyline.StrokeThickness = 3;
overlay.Content = polyline;
layer.Add(overlay);
map.Layers.Add(layer);
LayoutRoot.Children.Add(map);
It turns out that to display a path (which simply connects points and does not follow roads like in Mike Brown's example) you need to add the polyline to a MapElements object, i.e:
var map = new Map(); // Nokia Maps
var polyline = new MapPolyline();
var gc = new GeoCoordinateCollection();
foreach(var geo in MyGeoCoordinateList) {
gc.Add(geo);
}
polyline.Path = gc;
polyline.StrokeColors = Colors.Red;
polyline.StrokeThickness = 3;
map.MapElements.Add(polyline);
LayoutRoot.Children.Add(map);
As a bonus here's how to set the map so it contains the points in the view port (with nice animation):
map.SetView(LocationRectangle.CreateBoundingRectangle(MyGeoCoordinateList, MapAnimationKind.Parabolic);
I wanted to do the same thing, I used a GeoQuery passing in all of the waypoints. The query generated a route that I then displayed on the UI.
var query = new RouteQuery();
query.Waypoints = new[]
{
new GeoCoordinate(40.7840553533410,-73.9764425910787),
new GeoCoordinate(40.7833068308611,-73.9745997113487),
new GeoCoordinate(40.7826229881351,-73.9730985576614),
new GeoCoordinate(40.7821147220884,-73.9719513345183),
new GeoCoordinate(40.7809503161196,-73.9724639235822),
new GeoCoordinate(40.7803311395532,-73.9721954245488),
new GeoCoordinate(40.7795640919224,-73.9729398991417),
};
query.TravelMode = TravelMode.Walking;
var result = await query.GetRouteAsync();
var mapRoute = new MapRoute(result);
mapRoute.Color = Colors.Magenta;
mainMap.AddRoute(mapRoute);
mainMap is the Map control in my UI. The query creates a route that follows the available path (since I marked it as a walking path, it used the foot paths in central park).
The behaviour Im trying to achieve is to press and hold a listbox item and I should be able to delete the item.
I have created the listbox through code. Everylistitem has a stackpanel which holds two textblocks, ie a date and a string.
How can i get press and hold event for a selectedlistitem?? I have not used binding anywhere.
C#:
for (int i = 0; i < iHistCount; i++)
{
TextBlock dateText = new TextBlock();
TextBlock durationText = new TextBlock();
TextBlock spacer = new TextBlock();
TextBlock spacer2 = new TextBlock();
dateText.FontFamily = (FontFamily)App.Current.Resources["CicleFina"];
durationText.FontFamily = (FontFamily)App.Current.Resources["CicleFina"];
dateText.FontSize = 25;
durationText.FontSize = 25;
dateText.TextAlignment = TextAlignment.Right;
durationText.TextAlignment = TextAlignment.Left;
dateText.VerticalAlignment = System.Windows.VerticalAlignment.Center;
durationText.VerticalAlignment = System.Windows.VerticalAlignment.Center;
spacer.Width = 30;
dateText.Width = 130;
spacer2.Width = 50;
durationText.Width = 170;
DateTime dtHist = pCycMan.GetHistoryDate(i);
strDisplay = dtHist.ToString("dd-MMM-yyyy");
dateText.Text = strDisplay;
if( condition)
{
// logic
durationText.Text = strDisplay;
}
StackPanel st = new StackPanel();
st.Height = 50;
st.Orientation = System.Windows.Controls.Orientation.Horizontal;
st.Children.Add(spacer);
st.Children.Add(dateText);
st.Children.Add(spacer2);
st.Children.Add(durationText);
listboxHistory.Items.Add(st);
}
XAML
<ListBox x:Name="listboxHistory" Height="280" Canvas.Left="60" Canvas.Top="232" Width="360" Foreground="Gray">
Assuming you're using the Silverlight toolkit for a context menu, this link is a good example, and has how to create the menu in code-behind.
http://windowsphonegeek.com/articles/WP7-ContextMenu-in-depth--Part1-key-concepts-and-API
For example here:
StackPanel st = new StackPanel();
st.Height = 50;
st.Orientation = System.Windows.Controls.Orientation.Horizontal;
st.Children.Add(spacer);
st.Children.Add(dateText);
st.Children.Add(spacer2);
st.Children.Add(durationText);
listboxHistory.Items.Add(st);
ContextMenu cm = new ContextMenu();
MenuItem delete = new MenuItem()
{
Header = "Delete",
Tag= "Delete" //you could also put the item itself here, would be a good reference
};
delete.Clicked += //your event handler
MenuItem edit = new MenuItem()
{
Header = "Edit",
Tag = "Edit", //you could also put the item itself here, would be a good reference
};
edit.Clicked += //your event handler
//add the items to the context menu.
cm.Items.Add(delete);
cm.Items.Add(edit);
ContextMenuService.SetContextMenu(st, cm);