Sizing a spark list - apache-flex

I'm using spark Lists and PopupAnchors to build a drop down menu system, but I'm having trouble getting it to size reliably - the list always seems to want to take up 5 itemRenderers worth of space, but some of the menus I need to implement can be 3 or less items long. How can I have the list dynamically size to the number of elements in it, and no larger?

This is a fun one. You need to set the property on the VerticalLayout of the spark list.
Try this snippet:
(yourSparkList.layout as VerticalLayout).requestedRowCount = yourDataProvider.length;
This assumes you've got a list named yourSparkList and a dataprovider called yourDataProvider which is populating the list.
If your lists get long, you should set a MAXIMUM constant like so:
public static const MAXIMUM:int = 5;
if(yourDataProvider.length <= MAXIMUM){
(yourSparkList.layout as VerticalLayout).requestedRowCount = yourDataProvider.length;
}else{
(yourSparkList.layout as VerticalLayout).requestedRowCount = MAXIMUM;
}
BTW, there's also a requestedMaxRowCount and a requestedMinRowCount property.

Related

How to change the limit on the number of list templates in the AAOS car-app

When I run the code below, the maximum number of lists is limited to 6, is there any way to change this?
listLimit = getCarContext().getCarService(ConstraintManager.class).getContentLimit(
ConstraintManager.CONTENT_LIMIT_TYPE_LIST);
As in the sample code below, if 6 or more items are added and executed, 7th list is not visible. The sample code shows the 7th list in a new screen by adding a more button. Is there a way to show more than 6 lists on one screen?
public Template onGetTemplate() {
ItemList.Builder listBuilder = new ItemList.Builder();
Row[] screenArray = new Row[]{
createRow(getCarContext().getString(R.string.pane_template_demo_title),
new PaneTemplateDemoScreen(getCarContext())),
createRow(getCarContext().getString(R.string.list_template_demo_title),
new ListTemplateDemoScreen(getCarContext())),
createRow(getCarContext().getString(R.string.place_list_template_demo_title),
new PlaceListTemplateBrowseDemoScreen(getCarContext())),
createRow(getCarContext().getString(R.string.search_template_demo_title),
new SearchTemplateDemoScreen(getCarContext())),
createRow(getCarContext().getString(R.string.msg_template_demo_title),
new MessageTemplateDemoScreen(getCarContext())),
createRow(getCarContext().getString(R.string.grid_template_demo_title),
new GridTemplateDemoScreen(getCarContext())),
createRow(getCarContext().getString(R.string.long_msg_template_demo_title),
new LongMessageTemplateDemoScreen(getCarContext()))
};
...
int currentItemStartIndex = mPage * mItemLimit;
int currentItemEndIndex = Math.min(currentItemStartIndex + mItemLimit,
screenArray.length);
for (int i = currentItemStartIndex; i < currentItemEndIndex; i++) {
listBuilder.addItem(screenArray[i]);
There's no way for you as a developer to be able to change the number of list items that can be shown as these numbers have been chosen to meet safety regulations and can vary by region. Using the ConstraintManager as you're doing is the best practice since it will automatically give you the appropriate limit (vs. hard-coding this limit).
Since the number of items may vary (with 6 as the minimum), it's recommended to include the most relevant/important items first for dynamic lists.

Changing values to combobox from an array

I need to load values from an array to a combobox, with this code it loads only the last value of the array? Can anyone help me please.
for(int i =0; i<lines.size(); i++) {
resultArray[i] = lines.get(i).split("\t");
Laptops[i] = resultArray[i][0];
ObservableList<String> option = FXCollections.observableArrayList(Laptops[i].toString());
cbx1.setValue("");
cbx1.setItems(option);
cbx2.setValue("");
cbx2.setItems(option);
cbx3.setValue("");
cbx3.setItems(option);
}
In your loop, you are creating a brand new List on each iteration. So when you call setItems() on your ComboBox, the option list only has that one item in it.
There are several other issues with your loop, but once you have a valid array, populating a ComboBox with it is quite simple using the Arrays.asList() method:
ObservableList<String> option = FXCollections.observableList(Arrays.asList(resultArray));
cbx1.setItems(option);
That being said, I doubt you're getting a proper array with your line:
resultArray[i] = lines.get(i).split("\t");
Without knowing what lines actually is in your code, it's difficult to address this specifically, but it looks like you could skip the whole resultArray altogether and just use lines.
Calling the split() method returns an array of Strings anyway. Perhaps you could remove the loop altogether and just try:
ObservableList<String> options =
FXCollections.observableArrayList(Arrays.asList(lines.split("\t"));

iText7 large table autoLayout()

According to the docs
public Table(int numColumns,
boolean largeTable)
Constructs a Table with specified number of columns. The final column widths depend on selected table layout. Since 7.0.2 table layout algorithms were introduced. Auto layout is default, except large tables. For large table fixed layout set implicitly. Since 7.1 table will have undefined column widths, that will be determined during layout. In oder to set equal percent width as column width, use UnitValue.createPercentArray(int)
I render a large table using https://developers.itextpdf.com/examples/tables/clone-large-tables
Is there a way to define autoLayout? Maybe after adding the first row, get the cell widths and set them on the table, but that doesn't seem possible, because the column widths are null because I am using the constructor with number of columns.
Or adding some sort of autoLayout when end page is reached.
I don't want to define the widths for the columns because we have lots of tables.
First of all I would like to mention that auto layout requires the content of the whole table. The content is used when calculating the column widths. But you are using large table, which probably means you have a lot of data and you don't want to keep everything in memory (if that's not the case, just don't use large tables).
Thus, all you can do is calculate an approximation of the automatic column widths given some initial cells. Basically, it is possible to implement your first idea, however, it takes some code to be written. But if you have very different content in cells across different rows (e.g. images vs inner tables vs some text), then this method might not work very well because as I said, to estimate column widths well you need all the content.
Please also bear in mind that this approach is quite dirty and might not work for some corner cases. But it does solve the goal and frees you of the necessity to define column widths.
To describe the solution in a few words, we take cells of several initial rows, add them to a temporary table and layout it (estimate positions etc), without actually drawing it anywhere. Then we extract the cell widths from the layout step information and can use them for the large table constructor.
The method estimating column widths looks like this:
private UnitValue[] estimateWidths(Document document, Cell[][] cells) {
int numOfColumns = cells[0].length;
Table table = new Table(numOfColumns);
for (int i = 0; i < cells.length; i++) {
for (int j = 0; j < cells[i].length; j++) {
table.addCell(cells[i][j]);
}
}
LayoutContext context = new LayoutContext(document.getRenderer().getCurrentArea().clone());
TableRenderer tableRenderer = (TableRenderer)table.createRendererSubTree();
LayoutResult result = tableRenderer.setParent(document.getRenderer()).layout(context);
if (result.getStatus() == LayoutResult.PARTIAL) {
tableRenderer = (TableRenderer) result.getSplitRenderer();
}
UnitValue[] widths = new UnitValue[numOfColumns];
List<IRenderer> subList = tableRenderer.getChildRenderers().subList(0, numOfColumns);
for (int i = 0; i < subList.size(); i++) {
IRenderer cell = subList.get(i);
widths[i] = UnitValue.createPointValue(cell.getOccupiedArea().getBBox().getWidth());
}
return widths;
}
So assuming you have a Cell[][] cells array of cells for initial couple of rows (can be one row as well, but the more the better), where cells[i][j] refers to the cell at row i and column j, you can create your large table like this:
Table table = new Table(estimateWidths(doc, cells), true);
But don't forget to explicitly add cells from cells array to the large table before adding new content.

dynamically resize columns in fastreport

I simply want to resize the columns in my grid based on its content. The code below works 100% for each individual row but it will not change the width of the rows above it. Is there anyways to change the rows above the rows that did change?
int wCol1 = 25;
public String resizeCol1(){
String sCol1 = ((String)Report.GetColumnValue("resultSet.column1"));
int test = Convert.ToInt32(Math.Round(sCol1.Length * 9.2));
if (test > wCol1) wCol1= test;
Text3.Width = wCol1;
return sCol1;
}
Set the TfrxReport.EngineOptions.DoublePass property to True.
Calculate the width in the report script and store it in variable on the first pass.
Use Engine.FinalPass flag in the script to detect whether it's the final (second) pass and apply the widths.

Flex - sorting a datagrid column by the row's label

I'm creating a table that displays information from a MySQL database, I'm using foreignkeys all over the place to cross-reference data.
Basically I have a datagrid with a column named 'system.' The system is an int that represents the id of an object in another table. I've used lableFunction to cross-reference the two and rename the column. But now sorting doesn't work, I understand that you have to create a custom sorting function. I have tried cross-referencing the two tables again, but that takes ~30sec to sort 1200 rows. Now I'm just clueless as to what I should try next.
Is there any way to access the columns field label inside the sort function?
public function order(a:Object,b:Object):int
{
var v1:String = a.sys;
var v2:String = b.sys;
if ( v1 < v2 ){
trace(-1);
return -1;
}else if ( v1 > v2 ){
trace(1);
return 1;
}else {
trace(0);
return 0;
}
}
One way to handle this is to go through the objects you received and add the label as a property on each of them based on the cross-referenced id. Then you can specify your label property to display in your data grid column instead of using a label function. That way you would get sorting as you'd expect rather than having to create your own sort function.
The way that DataGrids, and other list based classes work is by using itemRenderers. Renderers are only created for the data that is shown on screen. In most cases there is a lot more data in your dataProvider than what is seen on screen.
Trying to sort your data based on something displayed by the dataGrid will most likely not give you the results you want.
But, there is no reason you can't call the same label function on your data objects in the sortFunction.
One way is to use the itemToLabel function of the dataGrid:
var v1:String = dataGrid.itemToLabel(a);
var v2:String = dataGrid.itemToLabel(b);
A second way is to just call the labelFunction explicitly:
var v1:String = labelFunction(a);
var v2:String = = labelFunction(b);
In my experience I have found sorting to be extremely quick, however you're recordset is slightly larger than what I usually load in memory at a single time.

Resources