Adding elements to TableViewer from a collection? - swt

So I'm trying to make a simple program that takes in some basic information about a loan, and turns it into an amortization table.
I am using WindowBuilder for this, and thus I have a Tableviewer that is supposed to have a column for Month, interest, payment, ect.
Unfortunately, I can't figure out how to get the table to actually display information. I have a Loan object that generates an ArrayList of month objects (each month being one row of the table), but from what I've read online, it's not as simple as telling the Tableviewer to populate each column with a variable from that arraylist.
I have set my Content Provider to be a Loan object, which contains an Arraylist of Month Objects, and each Month object has a getter for each column.
How do I go about displaying the text in each column?
Thanks.
EDIT:
So, here is the snippet of code from the example given to me below:
colFirstName.setLabelProvider(new ColumnLabelProvider() {
#Override
public String getText(Object element) {
Person p = (Person) element;
return p.getFirstName();
}});
I don't quite understand what is going on here. It's overriding the getText method, and casting the element to the type of element that has their data?
balanceCol.setLabelProvider(new ColumnLabelProvider(){
#Override
public String getText(Object element) {
Loan m = (Loan) element;
return m.getMonthObj().get(0).getMonth();
}
});
When I run this, it almost sorta works. It fills in about half the months, and then I get this error:
java.lang.ClassCastException: model.Month cannot be cast to model.Loan

Related

"Call to a member function active_pest() on array" when using SyncWithoutDetaching() to update a pivot table

I'm trying to using SyncWithoutDetaching() to update a pivot table (active_pest) but am getting a "Call to a member function active_pest() on array" error message.
The background here is that I have 8 tables: products, pests, actives (i.e active ingredients), crops, active_product, pest_product, crop_product, and active_pest. My form collects information about a selected (agrichemical) product - in that form, the user selects the pests, actives, and crops associated with that product. When submitted, my existing code is saving the expected information in the products table and, through a set of "belongsToMany" relationships, the active_product, pest_product, and crop_product pivot tables are also correctly updated.
For any given product there are typically 1 or 2 actives and 3-8 pests and it is those id values that I want to add to the active_pest pivot table.
My code is:
// ProductController
public function update(UpdateRequest $request)
{
$actives = $request->get('active');
$actives->active_pest()->SyncWithoutDetaching( $request->get('pest'));
...
}
// pest model
public function active_pest()
{
return $this->belongsToMany('App\Models\Pest', 'active_pest', 'active_id', 'pest_id');
}
Answers to other questions about this type of error message indicate that there is something wrong with the active_pest() relationship - but I got the same error message after making a typo there (active_pestr). Regardless, I don't understand what I'm doing wrong.
Insight appreciated. Thanks, Tom
$actives = $request->get('active');
Just return array, so you are trying something like this [1,2,3]->active_pest().
Which is exactly what it says. Call to a member function active_pest() on array.
You need to work with eloquent instance to perform ->active_pest()->SyncWithoutDetaching( $request->get('pest'));
So you can find you instances like this:
$actives = Active::whereIn('col_name', $request->get('active'))->get();
This will return you collection of instances, to save pest for each of them you need to iterate with foreach like this:
foreach($actives as $active){
$active->active_pest()->SyncWithoutDetaching( $request->get('pest'));
}

Combine chart data if category name is the same - JavaFX

I have an observable list of chart data which is created automatically. Is there any way to automatically combine the data which has the same category name in to one category?
The reason I need this is since the observable list of data is created directly form a table in a SQL database, I can not know if the user actually wants to show a combined view or each category and value separately in the chart.
Say I have the following data:
Instead of Bordeau-1 appearing this many times, I want all the values combined in to one pie called Bordeau-1, the same goes for Boredeau-2 and 3.
This is the code I use to automatically create data from the ObservableList which represents a table:
ObservableList<PieChart.Data> pieChartData
=
FXCollections.observableArrayList(EasyBind.map(observableListData, rowData -> {
String name = (String) rowData.get(0);
Double value = Double.parseDouble(rowData.get(1));
return new PieChart.Data(name, value);
}));
When you load the data, store it in a Map<String, Double>, and use the Map.merge(...) method to add or combine new values.
So in the code where you are loading the data from the database, you do this:
public Map<String, Double> loadDataFromDatabase() {
Map<String, Double> data = new HashMap<>();
// for each row in database:
// get name and value from row
data.merge(name, value, Double::sum);
// end for...
return data ;
}
Once you have loaded all the data into the map, you need to convert it to an ObservableList<PieChart.Data>. I don't think there's a cute way to do this in EasyBind, and if you're loading all the data at the start anyway, then you don't need the bound list. You can do something like:
ObservableList<PieChart.Data> pieChartData =
data.entrySet().stream()
.map(entry -> new PieChart.Data(entry.getKey(), entry.getValue()))
.collect(Collectors.toCollection(() -> FXCollections.observableArrayList()));
If the original map may get modified after the pie chart is created, you will need to make it an ObservableMap, register a listener with it, and update the pie chart data accordingly if the map changes. If you need this, it might be worth requesting the appropriate functionality in the EasyBind framework. Something like a method
public static <K, V, T> ObservableList<T> mapToList(ObservableMap<K, V> map, Function<Map.Entry<K, V>, T> mapping);

Looking for Wicket repeater that works only with iterator (without knowing exact result size)

I am trying to use wicket to display results from nosql database. This means large data sets with unknown size.
I need kind of GridView with paging functionality which DataProvider relies only on iterator and estimated result size (like 100+, which could also mean 500k). Good example would be google search - pagination has max 10 pages, and you can go one by one, or jump few pages ahead/backward.
Does anybody know such component?
I had a very similar problem here. Boris Pavlović pointed out i could use an infinite scrolling solution like this.
But i still ended up using a regular DataView with an IDataProvider with a default wicket ajax page navigator. I limited query results to ~100 (10 per page) and cached the results in the IDataProvider and used the size() on the list. When size() returned same as Maxresults (100) then I give a warning, the user usually doesn't go beyond page 2 (also like google).
My approach to something like that would be the following (that is using the regular DataProvider):
Determine the max displayed pages number (so in the google example, that would be 10 pages)
Whenever size() is called I estimate if there will be more results than [results per page]*[current page] + [max pages]*[results per page];
if yes, then return [results per page] * ([current page] + [max pages]) - 1
else return the exact amount
That would make wicket think that there are [current page] + [max pages] pages worth of results at any given time. So at any given point you would only have to know if there are [max pages] worth of results more, rather than the exact amount of results.
The size() is used to determine the first and count parameter values on the iterator() function, as well as pagination sizes, so it doesn't have to actually be the size of the result set, it can be a value that would indicate how many results you want displayed, and worry about how many more you want displayed when you get closer to that.
However, the intended behaviour of size() is to display the actual size of the results, so any other components or behaviours you use on the GridView should be checked for side-effects, as they could potentially suffer from unexpected results.
I was unable to find lib with such data provider, so I've implemented one - its called IterableGridView
Here is the code: https://github.com/maciejmiklas/cyclop/tree/master/cyclop-wicket-components
Iterable Grid View is based on Wicket's GridView, however it does not work with IDataProvider but with
IterableDataProvider. This new data provider relies only on plain java iterator - size information is not needed, and there is also no need to create range iterators for each page.
final List<String> myGridData = new ArrayList<>();
myGridData.add("value 1");
myGridData.add("value 2");
IterableDataProvider<String> iterableDataProvider = new IterableDataProvider<String>(10) {
#Override
protected Iterator<String> iterator() {
return myGridData.iterator();
}
#Override
public IModel<String> model(String s) {
return Model.of(s);
}
#Override
public void detach() {
}
};
IterableGridView<String> myGrid = new IterableGridView<String>("myGrid", iterableDataProvider) {
#Override
protected void populateEmptyItem(Item<String> item) {
item.add(new Label("myValue"));
}
#Override
protected void populateItem(Item<String> item) {
item.add(new Label("myValue", item.getModelObject()));
}
};
add(myGrid);
myGrid.setItemsPerPage(10);
// you have to use custom pager and not AjaxPagingNavigator
IterablePagingNavigator pager = new IterablePagingNavigator("rowNamesListPager", rowNamesList);
resultTable.add(pager);

Viewing a data matrix in Eclipse (RCP)

This is how I update my TableViewer that displays a list:
public void view(MyListClass list) {
ViewerSupport.bind(
this,
new WritableList(list, controller.theClass()),
BeanProperties.values(controller.theClass(), controller.strings())
);
}
controller is an instance of a class that encapsulates my glue code (it is a different class for the two listings; as is controller.theClass()). strings() is an array of property names. MyListClass descends from ArrayList<MyListEntryObject>. That works fine. But, I want to display a matrix of data. MyMatrixClass is a HashMap<Point, MyMatrixEntryObject>. This is what I've tried:
private void view(MyMatrixClass matrix) {
columns(matrix.columns());
List<WritableList> lists = new ArrayList<WritableList>(matrix.rows());
for (MyEntityClass list : matrix.children())
if (list instanceof MyListClass)
lists.add(new WritableList((MyListClass) list, controller.theClass()));
WritableList[] alists = lists.toArray(new WritableList[0]);
MultiList mlist = new MultiList(alists);
ViewerSupport.bind(
this,
mlist,
BeanProperties.value(controller.theClass(), "value")
);
}
This doesn't work. I get null argument popup errors. (Every data model class implements MyEntityClass. Class names have been altered due to this being a proprietary program I'm being employed to develop.)
Long story short, how do I use ViewerSupport and BeanProperties to display a matrix of data in a TableViewer?
As the JFace table viewer is line-based, you have to provide your matrix in a line-based way. You have to create a collection of the lines of the matrix, and then set this list as the input of the viewer. After that, you could create BeanProperties, that display the columns of the selected rows.

How to name a Class for container of resulted items of a clicked item?

I have an item X that when clicked will be splitted into 1 or more items.
So I have an ArrayList that will be returning the items but I am not sure of how to name the class of that ArrayList.
the class will hold itemName and Count.
public class WhatNameShouldItBe
{
public int itemId ...;
public int itemCount ...;
}
ArrayList<WhatNameShouldItBe> resultItems;
PS: Sorry about the question title ... if you need more information let me know was not sure if anything else was needed to such a question.
Some names I was thinking about:
ExtractedItems but since it is not extracted yet doesnt sound right to me...
ResultedItems or ResultItems
ClickableItemsResult
It is a list of items that can be given to the user when they use a clickable item
English isn't my native language, but I'll give it a shot anyway : SpawnedItem ?
You have a class describing something that has properties. Say it's a Widget. Each widget has an ID and a Count.
You then want a list of these Widgets. No problem, you make an ArrayList and name it something appropriate to what purpose the list serves:
public class Widget
{
public int itemId ...;
public int itemCount ...;
}
ArrayList<Widget> ClickedWidgets;
If the main purpose of the list is to differentiate those Widgets that were clicked on, then call it ClickedWidgets or something similar.
Remember, the most important thing about naming variables in programming is that it makes sense to you. (It also helps if others can figure it out later!)
A little bit vague on the question, but perhaps "Fragments" would work.