Requirement:
I have a list of strings displayed in the ComboBox. Each of these Strings can have some properties. These properties are displayed in PropertyTable. ComboBox's selected Item's properties are displayed in the table. In addition, we use PropertyTable for editing or setting property values to the selected item in the comboBox.
Problem:
The moment I de-select the comboBox Item,say item1, all the existing property values in the PropertyTable are set as new property values to item1. Again, when I select this item1 back, I should get above property values(i.e values before item1 is Deselected) back in to the PropertyTable?
Current Implementation Logic:
I am having TableCellListner for each PropertyTableCell, whenever cell content is changed, it takes the cell's new value and assigns this as new property value to the combo box's selected item. whenever new item is selected, table is refreshed with the selected Item's property values.
//before is Table initialization code
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
TableCellListener table = (TableCellListener)e.getSource();
String selectedItem=(String)ComponentPropComboBox.getSelectedItem();
if(table.getColumn()==1 && selectedItem!=null)
{
Property property=propertyMap.get(selectedItem);
else if(table.getRow()==0)
{
property.setProperty("MIN_LENGTH", (String)table.getNewValue());
propertyMap.put(selectedItem, property);
}
else if(table.getRow()==1)
{
property.setProperty("STARTS_WITH_STRING", (String)table.getNewValue());
propertyMap.put(selectedItem, property);
}
}
}
};
TableCellListener tcl = new TableCellListener(PropertiesTable, action);
How do i implement this requirement by overcoming the above challenge?
PS:
TableCellListner is a Not a java generic library. You can view code and its explanation at the following links:
http://www.camick.com/java/source/TableCellListener.java
http://tips4java.wordpress.com/2009/06/07/table-cell-listener/
I believe the question is obvious! Pls do let me know if question is not clear.Thanks in advance for your help & donating the knowledge!
In the code that listens for JComboBox selections. At its start have it set a boolean that the item is being changed. Then have your table refresh code ignore events that come while the boolean is set. After you are finished refreshing then set the boolean back.
Related
I'm writing a seating chart program using JavaFX. I have a table that keeps a list of students together that holds their name, grade, and whether they are present or absent (using a checkbox). I have a delete button that allows me to delete the students from the list. This works fine, however, whenever I delete the student object, the checkbox does not go along with it. I'm not sure what I would need to add to get that to work. Here is a snippet of the delete code. There are also two images below that show my problem. This is my first post so please let me know if I missed something. Please help! Thanks!
ObservableList<Student> items, sel;
items = currentTable.getItems();
sel = currentTable.getSelectionModel().getSelectedItems();
Student s = new Student("", "", 0, "");
for (Student p : sel) {
items.remove(p);
s = p;
}
Before Delete
After Delete
This has nothing to do with the delete or remove method. It has to do with what you did in TableColumn.setCellFactory().
To get the checkbox you shown, you should have used (in general) one of the two methods:
Overriding updateItem() in TableCell while setting Cell Factory
There is this empty parameter in updateItem() which indicates whether the row is empty or not. You need to use that to determine when not to show the checkbox.
column.setCellFactory(col -> {
return new TableCell<Foo, Boolean>() {
final CheckBox checkBox = new CheckBox();
#Override
public void updateItem(final Boolean selected, final boolean empty) {
super.updateItem(selected, empty);
if (!this.isEmpty()) {
setGraphic(checkBox);
setText("");
}
else {
setGraphic(null); // Remove checkbox if row is empty
setText("");
}
}
}
}
Using CheckBoxTableCell
JavaFX API has this convenient class CheckBoxTableCell that would do all these for you. Most people find this class hard to use because there are 2 things that you need to ensure to use it correctly:
The TableView that the column belongs to must be editable.
The TableColumn itself must be editable.
Example:
tableView.setEditable(true);
tableColumnSelected.setCellFactory(CheckBoxTableCell.forTableColumn(tableColumnSelected));
tableColumnSelected.setEditable(true);
As for whether which entry you want to be removed with the delete button, you just need to remove the correct items from the TableView.
I'm noob in javafx and scene builder. I want to populate tableview by selecting one item from combobox. It is possible?
i try with String val = combobox.getValue() and i put the string in SQL query in preparedStatement for directly sort but app stops at the null string value and tableview is not updated.
Thank you guys!
It is possible that the String is being initialized with the ComboBox value even before the ComboBox gets an input. In that case, the ComboBox will return a null value.
You should add an onAction event for the ComboBox which will update the string.
You can use the following code segment to do that
comboBox.setOnAction((event) -> {
val = comboBox.getValue();
//Any other action you want to carry out when an item of the combo box is selected
});
Or if you are using an FXML file and want to add the onAction event in the controller, you can use this.
public void comboBoxEvent(ActionEvent event){
val = comboBox.getValue();
} // Use this code when working with FXML files
Both these examples assume that the String var was defined globally. Just to be on the safer side, when you are comparing var to another value or storing it somewhere else, you should put it under an if condition
if(var != null)
//Code segment here
Vaadin: I need to set the selected row, after I update table content.
I have a Comboboxbutton containing different customers.
Additionally I have two tables, the first shows main categories and the secound shows subcategories.
Initially, no customer is selected, Main categories are shown, no subcategory is shown.
When I click on a category (lets say product for example!), sub-category table appers and shows sub-categories.
When I change the customer now from empty to a specific customer, both tables are filtered, BUT: The product-selection is lost. I need to set the selection to the one selected before.
I get the table content as an sql-container object from antoher class.
mainCatTable = new Table();
...
mainCatTable.setContainerDataSource(source.getMainCats());
//My Checkboxbutton
Combobox custBox = new ComboBox();
//Get the customers from the Database
custBox.setContainerDataSource(source.getCustomers());
custBox.setItemCaptionPropertyId("Customers");
custBox.addValueChangeListener(new ValueChangeListener() {
public void valueChange(ValueChangeEvent valueEvent) {
//Here I need to store the old selection, before i update the mainCat table to a specific customer
mainCatTable.setContainerDataSource(source.getMainCats(currentCustomer));
//Here I need something to set the selected row to the previous value
subCatTable.setContainerDataSource(source.getSubCats());
}
});
The sql-container which the getMainCats method returns, is created like this:
FreeformQuery subcatExtractionQuery = new FreeformQuery("select customerName from customers", connectionPool);
return new SQLContainer(subcatExtractionQuery);
The problem is, t tried different ways, but it didn't work.
This was my try:
https://vaadin.com/forum/#!/thread/1819417/1819416
But they use an indexcontainer, but I don't.
Can anybody explain how to do this WITHOUT an index container?
What about to use value of the table to get/set "selected" row?
Object value = mainCatTable.getValue();
mainCatTable.setContainerDataSource(source.getMainCats(currentCustomer));
mainCatTable.setValue(value);
I am using this link for creating a ContextMenu for each table row. Right now I'm running into problems because I'm not sure how to attach a ContextMenu after the 'type' has been inserted into a row.
Lets say I'm using a .zip editor program, and it lists the contents. I have an Image, and a text file, and some other stuff, all of them are under a class called Entry. My table's generic type is 'Entry', and I'd like to be able to create a context menu for each entry based on it's underlying subclass type (like an ImageEntry might return a menu item to open it up in an image editor...etc).
Right now I have a generic context menu for everything, but it's not great displaying a menu item about opening a text file with an image editor...
Is this possible to do? If so, what is the proper way to go about doing it?
Add a listener to the row's itemProperty (which represents the item displayed in the row) and update the context menu when it changes:
table.setRowFactory(new Callback<TableView<Person>, TableRow<Person>>() {
#Override
public TableRow<Person> call(TableView<Person> tableView) {
final TableRow<Person> row = new TableRow<>();
final ContextMenu contextMenu = new ContextMenu();
row.itemProperty().addListener((obs, oldPerson, newPerson) -> {
contextMenu.getItems().clear();
// add items to context menu depending on value of newPerson
// ...
});
// Set context menu on row, but use a binding to make it only show for non-empty rows:
row.contextMenuProperty().bind(
Bindings.when(row.emptyProperty())
.then((ContextMenu)null)
.otherwise(contextMenu)
);
return row ;
}
});
We are trying to implement a validation on the selections made with a JCombobox. In case of the new selection failing this validation, we are trying to revert to the previous selection.
Any idea about how could this be done?
I've created an implementation of ItemListener interface. Captured the previous value by checking for the DESELECTED event and validated the current selection after SELECTED event. But I'm not sure about where do I reset to the previous value when needed.
Can I do it from the listener itself?
Would that lead to recursive calls to my listener?
Can I do it from the listener itself ?
Yes you can. For instance:
JComboBox comboBox = new JComboBox();
comboBox.addItemListener(new ItemListener() {
Object previousSelection = null;
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getStateChange() == ItemEvent.DESELECTED) {
previousSelection = e.getItem();
} else if(!isValid(e.getItem())) {
JComboBox cb = (JComboBox)e.getSource();
cb.setSelectedItem(previousSelection);
}
}
});
Where isValid(Object obj) method should validate selected item.
Would that lead to recursive calls to my listener ?
Sure but the previous selected item was valid so it will be called 2 times top:
First time when user attempts to select an invalid item.
Second time when listener sets the previous item as the selected one.