ComboBox selected value not getting translated - javafx

My app should have several languages. English is by default. Problem is that if user will switch to different language, everything will be translated except for ComboBox selected value. This is how it looks:
Code behind ComboBox is:
ObservableList<Currency> currencyItem= CurrencyDA.getCurrencies();
currenciesComboBox.setItems(currencyItem);
Callback<ListView<Currency>, ListCell<Currency>> currencyFactory = lv -> new ListCell<Currency>(){
#Override
protected void updateItem(Currency currency, boolean empty){
super.updateItem(currency, empty);
setText(empty ? "" : interfaceBundle.getString("currency_"+currency.getName()));
}
};
currenciesComboBox.setCellFactory(currencyFactory);
currenciesComboBox.setButtonCell(currencyFactory.call(null));
currenciesComboBox.getSelectionModel().selectFirst();
How can I get selected value refreshed?

From the doc
As the ComboBox internally renders content with a ListView, API exists in the ComboBox class to allow for a custom cell factory to be set. For more information on cell factories, refer to the Cell and ListCell classes. It is important to note that if a cell factory is set on a ComboBox, cells will only be used in the ListView that shows when the ComboBox is clicked. If you also want to customize the rendering of the 'button' area of the ComboBox, you can set a custom ListCell instance in the button cell property. One way of doing this is with the following code :
//(note the use of setButtonCell):
Callback<ListView<String>, ListCell<String>> cellFactory = ...;
ComboBox comboBox = new ComboBox();
comboBox.setItems(items);
comboBox.setButtonCell(cellFactory.call(null));
comboBox.setCellFactory(cellFactory);
So the only thing you have to add is :
currenciesComboBox.setButtonCell(currencyFactory.call(null));

Related

How to update values in QTableView

I have a QTableView which gets its data from QAbstractTableModel and is a 2d array. Below the TableView I have two comboboxes. User first selects the row in the TableView. Now I want that when the user selects an option from the combobox, I want the selected option to update the display in the TableView selection.
Shown below is the UI. For example if the User Selects REF DES in the class combo box I want the selected row to update its class name to REF DES.
I am using c++ qt5. How do I achieve this with signals and slots?
enter image description here
Currently I have a slot that updates the combobox values based on my selection in tableview. I use something like this.
void GetOptionsClass::slotSelectionChange(const QItemSelection&, const QItemSelection&)
{
int rowidx = ui->line_tableView->selectionModel()->currentIndex().row();
data = model->index(rowidx, 2).data().toString();
if (data == "BOARD GEOMETRY") {
ui->lineSubclass->clear();
ui->lineSubclass->addItems(board_geometry_opts);
ui->lineClass->setCurrentIndex(0);
}
However I want to reverse this. Meaning when I change combobox I want to update the qtableview.

How do I get a new value from an editable combo box?

I am trying to add a value to an editable combo box called nameComboBox that I created in the Scene Builder.
I populate the combo box with this code:
private ObservableList<String> getNames()
{
return (FXCollections.observableArrayList("Freddy","Kerstin"));
}
..
nameComboBox.getSelectionModel().select(getNames());
I have a Save button defined form the Scene Builder. The code looks like this:
#FXML
private void handleSaveBtn()
{
System.out.println("The new name is " + nameComboBox.getValue());
}
When the scene is displayed, the combo boxes editable field is displayed empty with the two names hidden in the list underneath the empty field, which is what I want to happen.
If then type "Rusty" in the empty field and click a save button all that happens is that the println statement returns
"The new name is null".
If I wanted to do something with the new value, like validate it or store it in a database, how do I get the value that I entered in the editable field?
Try using this instead of .getValue() :
nameComboBox.getEditor().getText()
This returns the value of the textProperty of the TextField (.getEditor()) of the editable ComboBox.
try this
nameComboBox.setItems(getNames());
nameComboBox.setValue("Freddy");

JavaFX nested controls, how to get selection?

I try to implement an application with JavaFX 8 where I have a ListView of GridPanes, where each GridPane consists of 2 other controls (ChoiceBoxes). The Gridpanes in the ListView are dynamically added by the user during runtime. What I like to achive is to add a listener to the ChoiceBox such that I know to which ListView item/index the selected choicebox belongs to if a user makes a choice.
My Problem is now that I cannot get the index of the ListView when the user selects an item of the choicebox, because the item (i.e. the Gridpane) in ListView is not (automatically) selected or focused in this case.
Can anybode help me with this?
Thanks for the comments, I got the solution now by looking for the parent of the choicebox (note that paneList is an ArrayList in which I stored the references to the GridPanes which where added by the user)
// define Listener for choiceBox
choiceBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
GridPane parent = (GridPane) choiceBox.getParent();
// keep track of selected choice
selectedChoice = newValue;
logger.debug("selected choice: {}", selectedChoice);
// keep also track of parent GridPane
selectedGridpane = paneList.indexOf(parent);
logger.debug("selected GridPane {}", paneList.indexOf(parent));
});

ITemplate, the reason for leaving InstantiateIn(Control container)

I'm implementing the ITemplate interface in ListView control. If i realize it for ItemTemplate in my custom class, everything will be OK. I mean, the runtime will invoke InstantiateIn when i use
ListView.ItemTemplate = new CustomClass();
CustomClass :ITemplate
{
public void InstantiateIn(Control container)
{
HtmlTable table = CreateHeader();
container.Controls.Add(table);
}
...
}
But i want to do the same with ListView.LayoutTemplate. In this case, the runtime invokes InstantiateIn only one time, but every next update it leaves my method. What is the reason for it?
Layout template says how the root container does look like, it is not per item thing.
I have to change my LayoutTemplate after clicking different buttons.
And My LayoutTemplate has a header for the whole ListView. I have to change it, it depends on button.
Also i have two custom classes with implementations of ITemplate (one for ItemTemplate and one for LayoutTemplate). I am going to realise the folowing behaviour:
1). If i click Button1
ListView.ItemTemplate = new CustomItemClass1();
ListView.LayoutTemplate = new CustomLayuotClass1();
2). If i click Button2
ListView.ItemTemplate = new CustomItemClass2();
ListView.LayoutTemplate = new CustomLayuotClass2();
But i can't see my header of LayoutTemplate more, then one time.

Flex extending ComboBox

I created a class CustomCombo.as that extends ComboBox. What is happening is that the CustomCombo combobox is showing as being editable. I do not want this and I cant find the properties to set the editable to false.
I also tried setting the combobox's textInput.editable control to false, but to no avail.
Any help would be greatly appreciated.
CustomCombo.as
package custom {
import spark.components.ComboBox;
public class CustomCombo extends ComboBox {
public function CustomCombo() {
super();
// this.editable = false; //<-- THIS DOESNT WORK ***Access of possibly undefined property editable through a reference with static type custom:CustomCombo
// this.textInput.editable = false; //<-- THIS DOESNT WORK ***Cannot access a property or method of a null object reference
}
}
}
After rummaging through the Flex 4 API I found that they suggest to use the DropDownList control. From what I can see is that they removed the editable property from the ComboBox control in Flex 4, but I may be wrong.
I implemented DropDownList and that solved my problem.
I see that you're using spark and not mx. The editable property I referred to is applicable only to mx based list. In spark, ComboBox extends DropDownListBase and is editable by default.
The ComboBox control is a child class of the DropDownListBase control. Like the DropDownListBase control, when the user selects an item from the drop-down list in the ComboBox control, the data item appears in the prompt area of the control.
One difference between the controls is that the prompt area of the ComboBox control is implemented by using the TextInput control, instead of the Label control for the DropDownList control. Therefore, a user can edit the prompt area of the control to enter a value that is not one of the predefined options.
For example, the DropDownList control only lets the user select from a list of predefined items in the control. The ComboBox control lets the user either select a predefined item, or enter a new item into the prompt area. Your application can recognize that a new item has been entered and, optionally, add it to the list of items in the control.
The ComboBox control also searches the item list as the user enters characters into the prompt area. As the user enters characters, the drop-down area of the control opens. It then and scrolls to and highlights the closest match in the item list.
So ideally, you should be using DropDownList in this case.
You're getting null error when trying to access textInput from the constructor because it hasn't been created yet. In mx based controls (Flex-3), you can access it from the creationComplete handler; I'm not quite sure how to do it for spark based controls.
Update: I think I've figured out how to access skin parts in spark (though you might wanna use the DropDownBox instead). You have to override the partAdded method.
override protected function partAdded(partName:String, instance:Object):void
{
super.partAdded(partName, instance);
if (instance == textInput)
{
textInput.editable = false;
}
}
There's one catch though: it may not work in this case. The source code of ComboBox.as says that
the API ignores the visual editable and selectable properties
So DropDownList it is!
Initial answer, posted for mx ComboBox.
This shouldn't happen as the default value of the editable property is false.
Try explicitly setting the value to false from the constructor.
public function CustomCombo() {
super();
this.editable = false;
}

Resources