Linking combobox in JavaFx - javafx

I have a interface with three combobox. Each combobox shows an attribute of an object and is sorted either alphabetical order or numerical order depending the case. When I select a item (atribute) from a combobox the other two shall select it's item (atribute) corresponding to the object.
I can't find documentation about it and don't have any clue about how to do it. I find information about nested combobox only but this is not the case.
I hope you understand.

In this example I've added a listener to one of the combo boxes, which "listens" for a change to the combo boxes selected value. Upon selecting a value within that combo box, the second combo box adjusts itself to have the corresponding value. You can take this same logic and apply it 3 ways by adding a listener to each combo box. Let me know if you have any questions!
ComboBox<String> combo = new ComboBox<String>();
combo.getItems().add("1");
combo.getItems().add("2");
combo.getItems().add("3");
combo.getSelectionModel().select(0); // value index to select
ComboBox<String> combo2 = new ComboBox<String>();
combo2.getItems().add("10");
combo2.getItems().add("20");
combo2.getItems().add("30");
combo2.getSelectionModel().select(0);
combo.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue ov, String oldVal, String newVal) {
if (newVal.equals("1"))
if (combo2.getSelectionModel().getSelectedIndex() != 0)
combo2.getSelectionModel().select(0);
if (newVal.equals("2"))
if (combo2.getSelectionModel().getSelectedIndex() != 1)
combo2.getSelectionModel().select(1);
if (newVal.equals("3"))
if (combo2.getSelectionModel().getSelectedIndex() != 2)
combo2.getSelectionModel().select(2);
}
});

Related

javaFx TableView with Multiple ComboBoxes

I have a requirement where in i am supposed to compare two csv files. For comparison , we are trying to implement a rules configuration. Now the Rules will have an object like the following :
public class CsvInformation {
private String resultType;
private List<String> primaryKey;
private List<String> standardKey;
private List<String> ignoreKey;
public String getResultType() {
return resultType;
}
public void setResultType(String resultType) {
this.resultType = resultType;
}
public List<String> getPrimaryKey() {
return primaryKey;
}
public void setPrimaryKey(List<String> primaryKey) {
this.primaryKey = primaryKey;
}
public List<String> getStandardKey() {
return standardKey;
}
public void setStandardKey(List<String> standardKey) {
this.standardKey = standardKey;
}
public List<String> getIgnoreKey() {
return ignoreKey;
}
public void setIgnoreKey(List<String> ignoreKey) {
this.ignoreKey = ignoreKey;
}
so i am fetching a list of CSVInformation objects.Now i'd like to map/bind these to a tableView control so that the user will get an option to select values for PrimaryKey,IgnoreKey,StandardKey through a comboBox control in a TableView Cell. The TableView Control should look something similar to the following snapshot.
In the snapshot above, i'd like to fill each row of the TableView with each object of the List of CsvInformation Objects which i am getting from the backEnd. Is this achievable . I googled a bit but everywhere they have mentioned they haven't been able to use a Collection for binding to a comboBox inside a TableView . Any advice/ pointers/ suggestion will be highly appreciated. Thanks
#James_D : Hi James, Thx for the reply. The primary idea is that the user will be given the optoin to select primary Key,Standard Key & Ignore Key so as to tell us which columns to include for comparison and which ones to ignore , which is the primary key etc. Once the user makes that selection for as many rows as are present in the TableView at that time, i need to save these and create a Json out of that.The requirement is such that the tableView needs to comprise of 4 columns : 1 label, 3 Non- Editable Combo-boxes. Now to answer your query on combo box, each combo-box will be unique in nature i.e the entries that'll fill the ComboBox inside the TableView, if i say Row 1 , primaryKey Combo - box will have String values such as Mohit,Neha,Neeraj. Now when i move to fill the fill the next row, i.e Row 2 primaryKey Combo - box will have values such as James,Jason,Bourne.What i am trying to achieve is to create these combo-boxes on the go by binding to a list. I'm attaching a snapshot here for the content of csvHeaderList.Each row in the TableView Content will be from each ondex of the CSVHeaderList. Please let me know if you need any more insights on this.
< TabelView code >
TableView<CsvInformation > table = new TableView<CsvInformation >();
// Create column Result Type (Data type of String).
TableColumn<CsvInformation , String> resultTypeCol = new TableColumn<CsvInformation , String>("Result Type");
// Create column Primary Column (Data type of List<String>).
TableColumn<CsvInformation , List<String>> primaryKeyCol = new TableColumn<CsvInformation , List<String>>("Primary Column");
// Create column Standard Column (Data type of List<String>).
TableColumn<CsvInformation , List<String>> standardCol = new TableColumn<CsvInformation , List<String>>("Standard Column");
// Create column for Ignorable Columns. (Data type of List<String>).
TableColumn<CsvInformation , List<String>> ignoredCol = new TableColumn<CsvInformation , List<String>>("Ignorable Columns");
PropertyValueFactory<CsvInformation , List<CsvInformation >> resultTypeColFactory = new PropertyValueFactory<>(
"resultType");
PropertyValueFactory<CsvInformation , List<CsvInformation >> primaryColFactory = new PropertyValueFactory<>(
"primaryKey");
PropertyValueFactory> standardColFactory = new PropertyValueFactory<>(
"standardKey");
PropertyValueFactory> compareColFactory = new PropertyValueFactory<>(
"ignoreKey");
// Defines how to fill data for each cell.
// Get value from property of CsvInformation.
resultTypeCol.setCellValueFactory(new PropertyValueFactory<>("resultType"));
primaryKeyCol.setCellValueFactory(new PropertyValueFactory<>("primaryKey"));
standardCol.setCellValueFactory(new PropertyValueFactory<>("standardKey"));
ignoredCol.setCellValueFactory(new PropertyValueFactory<>("ignoreKey"));
Where i'm stuck is how to provide my definition for Tablecolumn,Table Cell,Cellfactory for a collection / List like :
TableColumn for mapping my list to a combobox inside a TableView.

Can't clear all items (elements) in an ObservableList

I've a couple of copied elements in an observablelist which I use for copy/paste operations in a TableView. The name of the table is cpTable (copy and paste Table) for storing copied elements and to paste elements that are stored in the table. After each paste operation I want to clear the contents of cpTable before I copy other selected items with Ctrl+C.
But I always get the error:
JavaFX Application Thread" java.lang.UnsupportedOperationException:
Not supported.
at com.sun.javafx.scene.control.ReadOnlyUnbackedObservableList.remove(ReadOnlyUnbackedObservableList.java:246)
Here is my pseudocode:
if (cpTable !=null) {
//first, get all copied items for removing all elements
ObservableList<String> copiedItems = cpTable.getItems();
int size = copiedItems.size();
// remove all elements
for(int i=0;i<size;i++) {
copiedItems.remove(i);
}
cpTable.setItems(copiedItems); //clear cpTable by setting an empty list
}
This is a method that copies the contents of selected items and puts it in a cpTable
public TableView<String> copySelectionToClipboard(TableView<String> table) {
ObservableList<String> data = table.getSelectionModel().getSelectedItems();
TableView<String> tmp = new TableView<>();
tmp.setItems(data);
return tmp;
}
When Ctrl+C is pressed the following line puts all copied items in a cpTable:
cpTable = copySelectionToClipboard( (TableView<String>) keyEvent.getSource());
As mentioned I want to clear all cpTable contents immediately after pasting
the items in a table.
Just clear your Observable List. It looks like you should use copiedItems.clear();
That should clear your table.
As James_D already mentioned, you haven't cleared exactly what's the point.
If you want to delete selected items from a table, you need to delete them from the table item list itself and not from the selection model.
A possible solution looks like this:
TableView<String> table = new TableView<>();
ObservableList<String> tableItems = table.getItems();
// needs multirowselection is set to true
ObservableList<String> readOnlyItems = table.getSelectionModel().getSelectedItems();
// removes all selected elements for the table
readOnlyItems.stream().forEach((item) -> {
tableItems.remove(item);
});
// clear the selection
table.getSelectionModel().clearSelection();
Update
This method get's an TableView, calls it's selection model to get all selected items. And then you add the data to a new TableView. And there is the problem! It's an unmodifiable read only list that you attached to your new table. First make it modifiable, like in the code below:
public TableView<String> copySelectionToClipboard(TableView<String> table) {
ObservableList<String> readOnlyData = table.getSelectionModel().getSelectedItems();
ObservableList<String> writableData = FXCollections.<String>observableArrayList(readOnlyData);
TableView<String> tmp = new TableView<>();
tmp.setItems(writableData);
return tmp;
The next problem is in your call to this method. You call it with a TableView<CsvData> and with a TableView<String> as your method needs. If CsvData is a subtype of String, than you have to change your method signature to TableView<? extends String>
If you are trying to clear all the items from your tableView and want just an empty tableView. You can use this:
myTableView.getItems().clear();
This basically gets all the items from your table view which is nothing but just the observable list now it performs clear operations to remove all the items in tableView.
Assuming you mean
table.getSelectionModel().getSelectedItems()
(since the selection model has no getItems() method), according to the Javadocs, this returns a read-only list. Thus attempting to modify the list will throw an UnsupportedOperationException.
To clear the selection, do
table.getSelectionModel().clearSelection();
(And similarly, if you want to manipulate the selection in any other way, you use methods on the selection model, rather than on the list.)

In javaFX need object reference to node under mouse cursor

I need a reference to the object under the mouse cursor in a javaFX Pane (or ScrollPane)
The following code removes the node under the cursor from the Pane.
The node object is stored in an ArrayList and has a unique id. If I had a reference to the node object, it would be a simple matter to remove it from the list. I'd be happy just to be able to pull the id of the node object out of the target description supplied by the MouseEvent's description of the target, and use it to find my node in the list. Note: I am creating these nodes dynamically and they are nameless: myList.add(new TYPE()).
Here's the snippet that I'm using to remove the node in the Pane;
root.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle (MouseEvent me) {
// would like a line here that grabbed the reference to the target
pane.getChildren().remove(me.getTarget());
}
});
It would be better for you to put the setOnMouseClicked listener to the node on which you want to remove from the list.
List<Node> listOfNodes = new ArrayList();
Node node = new Node();
listOfNodes.add(node);
node.setOnMouseClicked((event) -> {
listOfNodes.remove(node);
});
Note: Better use ObservableList than the ordinary ArrayList especially if you want that node to be removed also out from the root pane.
To James_D: Reason for disbelief: the syntax that fails to get past the compiler is the statement containing the expression me.getTarget().getText() which is commented out. It seemed to me that that ought to have worked.
for (Text tl : textList)
if ( (me.getTarget()) == (tl) )
{
System.out.println("HuRah!");
System.out.println("text is " + tl.getText());
//System.out.println("text is " + me.getTarget().getText());
textList.remove(me.getTarget());
}

javafx tableview detect any change upon any of rows including addition of new one

because I don't really know the sollution.
Lets say i have a TableView that holds info about product: description, quantity and the price. Also have a label that shows a sum of prices (times quantity) of all products from a table. Now i want to be notified about any changes that took affect on this component like changes in existing rows or addition of a new one. Is there any listener or sth similar to achieve it?
Usually you construct a TableView by passing an ObservableList to it. Something like this:
TableView myTable = new TableView<>(myObservableList);
ObservableList<ClassOfTheObjectsInTheList> myObservableList = FXCollections.FXCollections.observableArrayList(anyNoneObservableCollection);
TableView<ClassOfTheObjectsInTheList> myTable = new TableView<>(myObservableList);
You can add a ListChangeListener to any ObservableList at will by doing:
myObservableList.addListener(new ListChangeListener<ClassOfObjectsInTheList>(){
#Override
public void onChanged(javafx.collections.ListChangeListener.Change<? extends ClassOfObjectsInTheList> pChange) {
while(pChange.next()) {
// Do your changes here
}
}
});

Axapta: Update FormTreeControl after image change

In my other methods (data, text, etc.) the setItem method works fine to display changes made to a tree item. However, calling setItem after changing an item's icon doesn't seem to have any effect. What is the best way to update the tree item so the new icon appears?
Thanks
public void modified()
{
FormTreeItem workingItem;
;
super();
//find the current item
workingItem = FormTreeControl.getItem(FormTreeControl.getSelection());
//update the value
workingItem.Image(1);
//update the item in the list
FormTreeControl.setItem(workingItem);
}
Found a couple of issues here:
1. Never found a way to update the icon on a tree item effectively.
2. Found out some of the tree control objects aren't initialized if you try to add/delete from a datasource method, so deleting items throws Object Not Initialized errors.
Fixed it by:
1. Create a new item (addAfterIdx of the old item).
2. Delete the old item.
3. Select the new item.
3. Move the method from the datasource to the actual form control.
Here's the code that worked for me:
public boolean modified()
{
boolean ret;
FormTreeItem workingItem = FormTreeControl.getItem(currentEditingIdx);
TreeItemIdx newItemIdx;
;
ret = super();
//create a new item
newItemIdx = SysFormTreeControl::addTreeItem(FormTreeControl, workingItem.text(), FormTreeControl.getParent(workingItem.idx()), workingItem.data(), element.imageIdx(ABC_Icon.text()));
//delete the old item
FormTreeControl.delete(currentEditingIdx);
//select the new item
FormTreeControl.selectionChanged(FormTreeControl.getItem(FormTreeControl.getRoot()), FormTreeControl.getItem(newItemIdx), FormTreeSelect::Unknown);
return ret;
}

Resources