Install4j: Howto use String arrays in textfields - textfield

In my installer there is a screen with textfields whitch appears several times in a loop to configure different instances of services. For cleanliness i want to save those values in a String array.
How do i bind the specific index of the array to the texfield?
What do i write into the 'variable name' field of the textfield?
I've tried all possible combinations like ${installer:vars[0]}, but none of them worked.

This kind of binding is not possible directly. You have to bind the text field to a temporary variable, say tempVar and in the validation expression of the screen you have to push it into a list variable, say myList with the following code:
List values = (List)context.getVariable("myList");
if (values == null) {
values = new ArrayList<String>();
context.setVariable("myList", values);
}
values.add(context.getVariable("tempVar"));

Related

java8 make immutable List after removing null elements

I know Arrays.asList creates immutable List. My requirement is to create immutable List<Student> with no null elements in it. So I am creating new ArrayList() first then removing null elements using java 8 filters as shown below:
List<Student> list = new ArrayList<>();
list.add(makeStudent("ram", 'M'));
list.add(makeStudent("sathya", 'F'));
list.add(makeStudent(null, 'M'));
list.add(makeStudent("sri", 'M'));
list = list.stream().filter(s -> s != null).collect(Collectors.toList());
Below is the makeStudent method, it returns null if name is not available:
private Student makeStudent(String name, char gender) {
return null != name ? new Student(name, gender) : null;
}
I thought Collectors.toList() will create immutable. But I was wrong. The list is still mutable here. Is there a better way to make the list clean (remove null) and immutable in single line using java 8?
You might rewrite your code to this one:
list = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
Collector collectingAndThen allow you to wrap result collection
Even though you specified Java 8, here is how you can filter an existing List into a fully immutable List that you're looking for with Java 9:
list = list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toCollection(List::of));
using Collections.unmodifiableList to wrap the List collected by the stream.
list = Collections.unmodifiableList(list.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList()));
the Collectors.toList() method do the things like as reduce:
//pseudo-code
Collectors.reduce(ArrayList::new, List::add, List::addAll)
IF you passing an immutable List to reduce you can't collect any items from the stream into the List since it is immutable.
You can either use Collections.unmodifiableList as suggested in other answers or you can also convert stream to array and then use Arrays.asList.
list = Arrays.asList(list.stream()
.filter(Objects::nonNull)
.toArray(Student[]::new));

Map implementaion using arraylist as value

I am using Maps in my code for the first time, hence require some inputs from you experts.
My requirement is I have to check two different tables from database. Value from First table will be used as Key and Value for second table will be used as Value for the key.
Each key will have multiple values, so I will be storing all values against each key in a arraylist i.e. my Map will be like MAP.
Now, my issue is following:
I don't know the total no. of keys, so I can't create arraylist objects in advance. How to manage this?
How can I check if key exists in map such that if it exists then I have to updated the arraylist corresponding to it only. And if it doesn't exist then create new key, create arraylist corresponding to it, populate arraylist with the value.
Finally I have to iterate whole map and use the key and values.
How can it be implemented? Am I following the right approach? if not what is a better approach?
Thanks
With lists in Java you do not need to know the size up front. That is a requirement for Arrays. Therefore just create your Map
Map> myMap = new HashMap<>();
This should work
if (myMap.containsKey(someKey)) {
myMap.get(someKey).add(someValue); // adds a value to the list that already is in the map
} else {
myMap.put(someKey, Arrays.asList(someValue)); // which inserts a new key/value
}
If you need to iterate over all values in the list then you need a nested for loop
for (Map.Entry> entry : myMap.entrySet()) {
// your key = entry.getKey()
for (ValueType value : entry.getValue()) {
// use your value
}
}
http://docs.oracle.com/javase/7/docs/api/java/util/Map.html
Hope that helps.

How to search by key in hashset?

I wanted a collection that would contain a bunch of unique strings. Hashset seemed to be the best option since it removes duplicates and is quick about it.
However how would i go about finding an item in the hash set? I could just loop through all the elements but wouldn't that defeat the purpose of being a hashset? Essentially i just want a dictionary where the key is the value.
Hashsets are not used for searching. They are used to treat collection as a whole. You can use it as for what mathematical sets are used for: to create unions, intersections, or for checks of duplication etc.
The dictionaries and hashsets are similar in internal implementation, since they are based on hashtables. But sets do not have keys, since they are not allowed for the lookup of the elements. You must use dictionary for it. If you want to ask a set for an element, you will have to enumerate thru them all.
In the same way, you should not use Queues, stacks or linked list for looking for an element.
To have only strings in a dictionary you can use it like:
IDictionary<string, string dictionary =
new Dictionary<string, string>();
dictionary.Add("Foo", "Foo");
dictionary.Add("Bar", "Bar");
string stringThatILookFor = null;
if (dictionary.TryGetValue("Bar", out stringThatILookFor))
{
// Use stringThatILookFor, which has a value Bar
}
You need to be using Contains.
Dim hsStrings As HashSet(Of String) = {"a", "b", "c"}
If hsStrings.Contains("a") Then 'do smth

How do I use a GtkComboBox with objects, as opposed to strings?

The usual use for a combo box is to let it display options to the user, and then you get an OBJECT out of it. In Win32, you do it by using the CB_SETITEMDATA and CB_GETITEMDATA messages, casting between int and object pointers. In XAML, you set up a data template and the item in the list IS the object.
What is the Correct way to get this effect with a GtkComboBox?
GtkComboBox normally uses a GtkListStore as the underlaying model.
You need to create one with an extra column for the object you want to store and as you insert new items in the combo's model you also need to provide the object you want to associate with that row/item.

How to use GtkTreeView correctly

I am using a TreeView with a ListStore as model. When the user clicks on a row I want to take some action but not using the values in the cells, but using the data I created the row from...
Currently I have the TreeView, the TreeModel (ListStore) and my own data (which I ironically call model)..
So the Questions are:
Is it "right" to have a model - an object representation of the data I want to display and fill a ListStore with that data to display in a TreeView, or would it be better to implement an own version of TreeModel (wrapping my data-model) to display the data?
And also:
If someone double-clicks in a row I can get the RowActivated event (using C#/Gtk#) which provides a Path to the activated row. With that I can get a TreeIter and using that I can get the value of a cell. But what is the best practice to find the data object from which the row was constructed in the first place?\
(Somehow this question got me to the first one - by thinking would getting the data object more easy if I tried to implement my own TreeModel...)
It's quite awkward/difficult to implement TreeModel, so most people simply synch the data from their "real" model into a TreeStore or ListStore.
The columns in the store do not have to match the columns in the view in any way. For example, you can have a column that contains your real managed data objects.
When you add a cellrenderer to a TreeView (visual) column, you can add mappings between its properties and the columns of the store. For example, you could map one store column to the font of a text cellrenderer, and another store column to the text property of the same cellrenderer. Each time the cellrenderer is used to render a particular cell, the mappings will be used to retrieve the values from the store and apply them to the properties of the renderer before it renders.
Here's an example of a mapping:
treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);
This maps store column 0 to the renderer's text GTK property and maps store column 4 to the editable property. For GTK property names you can check the GTK docs. Note that the example above uses a convenience method that adds a column, adds a renderer to it and add an arbitrary number of mapping via params. To add mappings directly to a column, for example a column with multiple renderers, pack the renderers into the column then use TreeViewColumn.AddAttribute or TreeViewColumn.SetAttributes.
You can also set up a custom data function that will be used instead of mappings. This allows you to set the properties of the renderer directly, given a TreeIter and the store - so, if all the data you want to display is trivially derived from your real data objects, you could even have your store only contain a single column of these objects, and use data funcs for all the view columns.
Here's an example of a data func that does exactly what the mapping example above does:
treeColumn.SetCellDataFunc (renderer, delegate (TreeViewColumn col,
CellRenderer cell, TreeModel model, TreeIter iter)
{
var textCell = (CellRendererText) cell;
textCell.Text = (string) model.GetValue (iter, 0);
textCell.Editable = (bool) model.GetValue (iter, 4);
});
Obviously data functions are much more powerful because they enable you not only to use properties of more complex GTK objects, but also to implement more complex display logic - for example, lazily processing derived values only when the cell is actually rendered.