JavaFx remove item from TilePane - layout

What I am trying to do is have a button with three lines of text on it.
The first line is always present. The second and third line are created as TilePane objects with three elements in them. What I am trying to do is optionally remove either the end two elements of the second and third row or alternatively the middle item depending on a configuration parameter.
What I have tried is the following:
firstRow.getChildren().addAll(leftFront, leftCentre, leftBack);
secondRow = new TilePane();
secondRow.getChildren().addAll(rightFront, rightCentre, rightBack);
leftCentre.visibleProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
if (newValue) {
firstRow.getChildren().remove(leftBack);
firstRow.getChildren().remove(leftFront);
} else {
firstRow.getChildren().remove(leftCentre);
}
});
leftCentre.visibleProperty().bind(labelProp);
rightCentre.visibleProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
if (newValue) {
secondRow.getChildren().remove(rightBack);
secondRow.getChildren().remove(rightFront);
} else {
secondRow.getChildren().remove(rightCentre);
}
});
rightCentre.visibleProperty().bind(labelProp);
Where the elements with left and right named items are the ones I want to remove or keep depending on the SimpleBooleanProperty labelProp. If I set labelProp to false the four outer elements appear. However if I set the labelProp to true only the top line of the three appear.
So what I am doing wrong?

Worked out my problem. It appears that the initial value of the BooleanProperty was removing the values I expected to see when it was initialised. So when I tried to make them reappear the Nodes had been removed.
Is there a way to make the elements in a TilePane to aligned? For example
First1 First2
Second1 Second2
Is what I am seeing on the screen as I set the TilePane aligment to CENTER. What I want to see is:
First1 First2
Second1 Second2
so it looks a little neater.

Related

Show Data from Arraylist in list view in Kotlin and Android Studio

In my code Im showing the project name in the list view. But I want to show the name of all added Contacts.
showAllContactsBtn.setOnClickListener(){
val arrayAdapter: ArrayAdapter<Contact> = ArrayAdapter(
this,android.R.layout.simple_list_item_1,listOfAllNames
)
listNames.adapter = arrayAdapter
listNames.setOnItemClickListener { adapterview, view, x, y ->
Toast.makeText(this, "Contact picked" + listofAllnames[x].name, Toast.LENGTH_LONG).show()
}
How do I show the names like in Toast "list of All names . name"?
An ArrayAdapter just calls toString() on the items you pass in, and displays those. So you could just pass in all the name values instead:
val arrayAdapter: ArrayAdapter<Contact> = ArrayAdapter(
this, android.R.layout.simple_list_item_1, listOfAllNames.map { it.name }
)
If you need to keep the original objects in the ArrayAdapter for whatever reason, you could override the toString() method in the objects' class so it just returns the name. But since you're just looking up an index in the original data set here, just throwing the list of labels into the ArrayAdapter constructor is probably fine!

Adding multiple objects to ArrayList that match a selected string

What I am trying to do: Fill the namesArray with all the objects that match a certain criteria.
The Activity object is made of four strings "category, name, note, time"
The getCategory(activityArray) returns a string which is the selected category, I'm trying to sort the objects where their category matches the selected category into the new namesArray
So this namesArray will end up containing only Activity objects with selected category.
This is my code:
public static void viewActivity(ArrayList<Activity> activityArray) {
String categ = getCategory(activityArray);
String holder;
ArrayList<Activity> namesArray = new ArrayList<Activity>();
for(Activity obj : activityArray) {
holder = obj.getCategory();
if(holder == categ) {
System.out.println(obj.getName());
namesArray.add(obj);
}
}
}
When I run the debugger, first iteration works, and the first object where it's category matches the selected category is added to the namesArray. But then the if statement just seems to stop working, the holder String does not change and stays the same.
So how do I get my method to add every matching object to the namesArray instead of only the first one?
Thanks
Solved by changing the
if(holder == categ) {
to
if(holder.equals(categ)) {

GXT re-arrange data array index in TreeStore

Currently, I'm using gxt 3.0.6
I have a TreeStore let's called it "treeStore", with model data "ParentDto".
private TreeStore<ParentDto> treeStore;
treeStore = new TreeStore<ParentDto>(new ModelKeyProvider<ParentDto>(){
#Override
public String getKey(ParentDto item){
return String.valueOf(item.getParentId());
}
});
Inside ParentDto there is a list of ChildDto. If there is ParentDto data which has list of ChildDto, I want to show it in a tree grid. I use basic tree grid from this link
https://www.sencha.com/examples/#ExamplePlace:basictreegrid
Using that reference, if I try to add 1 ParentDto everything works fine, but when the problem is when I add many Parent Dto.
Here is my code for adding data into the treeStore
public void fillTreeStore(List<ParentDto) listParent){
treeStore.clear();
for(ParentDto parentDto : listParent){
treeStore.add(parentDto);
if(parentDto.getListChild().size() > 0){
for(ChildDto childDto : parent.getListChild()){
treeStore.add(parentDto,childDto);
}
}
}
In my case, I only need 1 level parent and child tree so this code is enough.
I try to debug my code use this expression
treeStore.getAll().get(index);
When I add 1 ParentDto (parentA) which has 1 Child (childA). The result will be
treeStore.getAll().get(0) -> contain parentA
treeStore.getAll().get(1) -> contain childA
But if I add 2 ParentDto (parentA, parentB) and each of them have 1 child (childA,childB). The result will be
treeStore.getAll().get(0) -> contain parentA
treeStore.getAll().get(1) -> contain parentB
treeStore.getAll().get(2) -> contain childA
treeStore.getAll().get(3) -> contain childB
But in the grid, those data will be shown perfectly fine :
row 1 : parentA (this row can expand)
row 2 : childA (the expanded row form parentA)
row 3 : parentB (this row can expand)
row 4 : childB (the expanded row form parentB)
I need to render icon if the data is "parent" so I use this code :
(icon_variable).addBeforeRenderIconCellEventHandler(new BeforeRenderIconCellEventHandler() {
#Override
public void onBeforeRenderIconCell(BeforeRenderIconCellEvent event) {
if(treeStore.getParent(treeStore.get(event.getSelectedRowIndex())) == null){
//#render icon here
}
}
});
The problem is at this code
treeStore.get(event.getSelectedRowIndex())
When parentB is added it will trigger addBeforeRenderIconCellEventHandler method. event.getSelectedRowIndex() will get the row index based on "grid's perspective". At the second row, from grid's perspective (childA), event.getSelectedRowIndex() will return 1. But from "treeStore's perspective", index 1 is "parentB", so my icon render is messed up.
That's why, the result I need in treeStore is like this
treeStore.getAll().get(0) -> contain parentA
treeStore.getAll().get(1) -> contain childA
treeStore.getAll().get(2) -> contain parentB
treeStore.getAll().get(3) -> contain childB
My solution :
To solve this problem, for now, I use 2 Stores, the first one is TreeStore, and the second one is ListStore. Each time parent and child are added, I insert them at TreeStore and ListStore. In the ListStore, I keep parent's and child's index to always match with grid's perspective, so that whenever addBeforeRenderIconCellEventHandler is triggered, I use ListStore to get the data.
In my opinion, this solution is not good enough but because in my case, the maximum data can be added into the store less than 50, it's enough.
It looks like this is default behavior. You didn't say what it is you are trying to do but my guess is you can do it with the methods they provide. I'm guessing you are trying to traverse the tree by looking at the parent and then all of it's children before moving on to the next parent. Something like this would do it.
for (ParentDto parent : treeStore.getRootItems()){
for (ChildDto child : treeStore.getChildren(parent)){
}
}

Binding the style property of all cells in a JavaFX TableView

I have a JavaFX TableView where each row should have a conditional style.
The styling is dependent on whether the source item of of the table row is present in a certain list or not.
This is what I have so far:
1) The data class that holds the data of a table row together with two boolean properties (true if the data is contained in list X) and a string property that should bind to the correct style attributes.
private class WebPageData {
private WebPage page;
private BooleanProperty isReferenced = new SimpleBooleanProperty(false);
private BooleanProperty isReferencing = new SimpleBooleanProperty(false);
private StringBinding style = new When(isReferenced).then("...").otherwise(...);
}
2) A change listener on table selection change that updates each boolean property accordingly, when the table selection changes
tblResultData.getSelectionModel().getSelectedIndices().addListener(new ListChangeListener<Integer>() {
#Override
public void onChanged(ListChangeListener.Change<? extends Integer> arg0) {
if (arg0.getList().size() == 0) {
selectedPage.set(null);
} else {
// for coloring only consider the first selected row
// multi select must be doable for certain other features
WebPage selectedWebPage = tblResultData.getItems().get(arg0.getList().get(0)).page;
selectedPage.set(selectedWebPage);
// tableModel.data holds a list of data for every table row
for (WebPageData data : tableModel.data) {
boolean referenced = selectedWebPage.getReferencedWebPagesList().contains(data.page);
boolean referencing = selectedWebPage.getReferencingWebPagesList().contains(data.page);
data.isReferenced.set(referenced);
data.isReferencing.set(referencing);
}
}
}
});
Now what I want to do is to somehow bind the style property of each table cell to the style property of WebPageData - so that the change listener updates the two boolean properties, therefore the style property of WebPageData is updated and in consequence the style of the table cell changes.
I tried to bind the style during creation phase by using a custom TableCellFactory, but of course this approach fails as there is no WebPageData instance present at this time. As the TableColumn classes don't provide an opportunity to iterate over all cells (so I could bind the style after the table actually gets its data), the only option I currently see is to keep a reference to each created table cell. I don't consider this solution is good practice.
So is there any other option to bind the cell styles? If I don't bind them, I have to set the styles manually each time the table selection changes - which puts me to the "I can't iterate over cells" problem again.
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.scene.control.TreeTableRow;
public class HighlightBoundTreeTableRow extends TreeTableRow<Thing> {
private static final String CHOSEN_STYLE_CLASS = "chosenStyle";
private final ObjectProperty<Boolean> chosen = new SimpleObjectProperty<>();
private final ChangeListener propertyChangeListener = (obs, ov, nv) -> updateHighlight();
#Override
protected void updateItem(Thing item, boolean empty) {
super.updateItem(item, empty);
//cleanup
getStyleClass().remove(CHOSEN_STYLE_CLASS);
chosen.unbind(); // unbinding something that is not bound has no effect
chosen.removeListener(propertyChangeListener); // also ok to remove a listener that was never there
if (empty) {
return;
}
chosen.bind(item.chosenProperty()); //bind will also set the intial value
chosen.addListener(propertyChangeListener);
updateHighlight();
}
private void updateHighlight() {
if (chosen.get()) {
getStyleClass().add(CHOSEN_STYLE_CLASS);
} else {
getStyleClass().remove(CHOSEN_STYLE_CLASS);
}
}
}
I know this was asked forever ago but maybe it'll help someone.
I had a similar issue I wanted to solve. I know you're using a TableCell and this involves a TreeTableRow but I believe the concept is the same: You want to change a field in your data object and have that change update the styling on wherever that object is being displayed in a table.
So I extended TreeTableRow and gave that class its own property field to hold on to. Every time that row is updated I unbind that property and rebind it to the field I want to listen to. (I do the same with the listener.) Since every time updateItem() is called it could be getting a different instance of my data object.
"chosenStyle" is just a class in my style sheet that changes the background color. Using classes instead of calling setStyle() makes it easier to remove the styling.

how to get the name of an object and change the text of a textbox with its' name?

Hi there (developers of wp7 apps).
The following problem already caused countless sleepless nights, so i hope anyone could provide me with a solution.
Elements grouped as a grid should call (on tap) a function that changes a textbox' text with one i declare.
I already have the function that reads the "name" of the object:
private void FunctionABC(object sender, System.Windows.Input.GestureEventArgs e)
{
//Objects name
string ObjectSender = (sender as Grid).Name.ToString();
//But how to continue, if I want kind of "this" result?:
this.ObjectSender.Text = "abc";
}
I appreciate any answer my problem. Thanks.
If your question is how to change the textbox.text property which is placed inside a grid if you tap the grid then you should iterate through the grids Children and find the textbox you are looking for and then change it's text property.
First of all you need to change the this line :
string ObjectSender = (sender as Grid).Name.ToString();
because this line gives you the name of the Grid and not the Grid itself.
Grid ObjectSender = (Grid) sender;
And then you can search through it's children.

Resources