JavaFx: How can I get the combobox object from it's textfield? - javafx

I have a combobox (cb). When someone clicks on the associated textfield, I want to clear it. I use
cb.getEditor().setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent evt) {
((TextField) evt.getSource()).clear();
}
});
and the result is in cb.getEditor().getText()
So far so good.
If I fill the box via the pull down instead of typing the result is in cb.getSelectionModel().getSelectedIndex();
That's good too. The combobox is populated with an object, not a string, so I can't really use getSelectedItem(). I wish I could.
The problem is, if I try to select something from the pulldown, and THEN use the editor, the selectedIndex() remains set.
How can I clear the combobox selectedIndex when I have a mouse event for the textfield? I can't find a way to get the combobox from the textfield.
I don't know if it's relevant but I also tie the text to the box via TextFields.bindAutoCompletion(cb.getEditor(), cb.getItems()));

From the ComboBox documentation:
Because a ComboBox can be editable, and the default means of allowing
user input is via a TextField, a string converter property is provided
to allow for developers to specify how to translate a users string
into an object of type T, such that the value property may contain it.
By default the converter simply returns the String input as the user
typed it, which therefore assumes that the type of the editable
ComboBox is String. If a different type is specified and the ComboBox
is to be editable, it is necessary to specify a custom
StringConverter.
(my emphasis).
Therefore, you need to provide a converter for your ComboBox that defines how to convert the string the user typed in the combo box editor into an object of the correct type, and conversely how to convert an object of that type into a string to display in the text field.
Once you have done that, the correct way to retrieve the value from the combo box is with
cb.getValue();

Related

Hide a button in a non selected cellView with bindings

I begin developing with Cocoa. I have an ArrayController which provides datas to a NSTableView with DataBindings.
I added a button on my cellView and want it visible only when the cell (or row, there’s only one column) is selected.
I added a Boolean property to my dataModel « estSelectionne » to activate or not the « Hidden » of my button.
My question:
how to set the value of the « estSelectionne » Boolean? (Tried to addObserver…)
or better, can I set directly the Boolean Hidden in IB, and how?
Thank you in advance
I set the value of my model property "estSelectionne" in an override of NSTableView.isRowSelected and it's OK

Uneditable box after ticking it

How can I make it after ticking the box and it turns uneditable right away?
This question is somewhat loaded because the answer is, it depends.
Your screenshot makes it look like that control is in a grid row, which would imply the control is connected to a datasource. If that's the case, do you want only the checkbox to be disabled or the entire row?
You would probably put code in the datasource field's modified method or the datasource's active method.
If the checkbox is a standalone control, you would override the clicked method with something like:
public void clicked()
{
super();
if (this.checked())
this.enabled(false);
}
I believe it's due to Field properties in table.
Seems like it restricts edit after creation.
Otherwise - check code on form (or class maintaining the form). It might be on Control/Field/Datasource/Table modify method.

JavaFX ComboBox: Receive mouseclick/keypress events from ListView

I start with the question and then describe the problem more in detail:
Question:
Is there a way to receive events from the listview of a JavaFx ComboBox directly (ComboBox consists of a listview and a textfield as far as I understand)? I would like to find out which element of the list has been clicked by mouse or which element was selected when the user pressed enter on the keyboard (after navigating with Up/Down Arrows in the list). I therefore need to receive the mouse click event or the keypress event on the listview, but all I can get so far are events on the combobox itself which turned out to be only changes in the textfield of the combobox.
Detailed problem description:
I have a JavaFx Application with a combobox where the idea is that the value is directly added to another list when the user clicks on an entry in the combobox list (when the popup of the combobox is open). Additionally, when the user navigates in the combobox list with the arrow keys on the keyboard and he presses enter, the currently selected value should be taken and added to the other list. However so far I have not found out how I can implement this feature with the standard JavaFx combobox.
Tried:
The first solution I tried was to add a change listener on the combobox's valueProperty (this is the value that is displayed in the textfield when the popup is closed). So when the user clicks on a listentry, the popup closes and the clicked entry is put into the value field, changes the value and therefore fires my change listener. This worked well with the mouse, but keyboard navigation did not work correctly because everytime the user navigates down or up on the list, the value field of the combobox is updated with the currently selected listentry and therefore fires my changelistener every time (which in turn adds the value to my other list, while it should only be added on enter keypress).
The next solution was to not add a listener to the valueProperty, but to the showingProperty. Everytime the combobox popup closes, the current value of the value field is taken and added to the other list. This works again well with the mouse, but still has issues with keyboard navigation. While it now correctly handles up/down navigation in the list and enter keypresses, the problem is now when you try to cancel the selection. When you press escape, the value is taken as well and added to the other list like you would have pressed enter. The problem with this approach is that I cannot find out with which keypress the popup has been closed.
So the next idea I had is to add an event filter to the combobox itself with the addEventFilter Method of the ComboBox with code similar to the following (also proposed here StackOverflow):
ComboBox comboBox = new ComboBox();
comboBox.addEventFilter(KeyEvent.KEY_PRESSED, (event) -> {
// do stuff
});
But the event filter never gets called when the combobox popup is open. It is only called when the popup is closed, which leads me to the assumption that the event is consumed by the listview. So the only solution to the problem seems to be to somehow capture the events from the listview itself. And that leads back to the question at the beginning of this post. Sorry for the long explanation.:-)
Came across this question while looking for something else. It touches on something I've worked on before so assuming I understand what you're trying to accomplish and also that this is still relevant here are a couple of ideas.
To keep the other list (list #2) in sync with the combo box for mouse clicks try:
A ChangeListener on the selectedItem property for the combo box's selectionModel. Clicking an item in the popup (drop-down) list view will change the selectedItem value and close the Window that 'owns' the list view, or
An event handler to the combo box for the event type ComboBoxBase.ON_HIDDEN which gets fired when the list view closes (or better said 'becomes hidden').
The ChangeListener may be problematic inasmuch as the selection models for the combo box and the list view are linked at a low level, so that changes to the selectedItem value for the list view which will be triggered when navigating with key strokes will necessarily be handled by the ChangeListener. Since you want to sync the combo box and list #2 only when the ENTER key is pressed, this will probably not work. But that still leaves the event handler idea to try.
As for ENTER key press, you need to get a handle for the list view itself, and then add whatever behavior (listeners/event handlers) as needed. You do this by getting the skin for the combo box, which should be an instance of ComboBoxListViewSkin, and then get the list view by invoking the getPopupContent() method for the skin; it returns the popup list view as a Node so you'll to recast the returned value but no big deal.
Hope this helps.
The idea of the below code is that ListView is created once the combobox is loaded in the JavaFX scene. Therefore, we add a listener on the combobox to check when it appears on the scene, and then through "lookup" method we get its listview and add a listener to it.
In the example, I have set a MouseEvent listener but you can easily adjust it for keys as well.
private EventHandler<MouseEvent> cboxMouseEventHandler;
private void initComboBox() {
ComboBox<String> comboBox = new ComboBox<String>();
comboBox.getItems().add("Item 1");
comboBox.getItems().add("Item 2");
comboBox.getItems().add("Item 3");
comboBox.sceneProperty().addListener((a,oldScene,newScene) -> {
if(newScene == null || cboxMouseEventHandler != null)
return;
ListView<?> listView = (ListView<?>) comboBox.lookup(".list-view");
if(listView != null) {
cboxMouseEventHandler = (e) -> {
Platform.runLater(()-> {
String selectedValue = (String) listView.getSelectionModel().getSelectedItem();
if(selectedValue.equals("Item 1"))
System.out.println("Item 1 clicked");
});
}; // cboxMouseEventHandler
listView.addEventFilter(MouseEvent.MOUSE_PRESSED, cboxMouseEventHandler);
} // if
});
} // initComboBox

A suggest to solve QLineEdit property

I'm working with Qt5...and I'm tryng to set a default value in QLineEdit in case of I wrote nothing in the linetext area.
Is possible to do that?
You can do this for example by connecting
void QLineEdit::editingFinished () [signal]
and check in the slot actual text from QLineEdit and if necessary set yours.
If you want user to have empty field when they start editing
First use placeHolderText property of QLineEdit to set the default value to display.
Then connect editingFinished (or possibly some other, check them out) signal to your own slot, where you check if text is empty (and then use the placeHolderText value) or if user entered something.
If you want to leave default text for user to edit
Instead of using placeHolderText, simply set contents of the QLineEdit to desired default value, when you create it. Then in the slot for editingFinished, if user made field empty, restore the text to default.

Passing variables from one form to another in Qt

I've got two forms, the mainform which opens up a dialog box that has a text box in it. How can I pass the text from the textbox back to the mainform? I've tried alot of different methods but I think I'm missing something simple. Thanks for any help.
The dialog box still exists after it closes. So you can, from the main form, do something like this:
QString text = subform->textEdit->text();
This assumes your dialog box is subform and the name you gave to the text edit box is textEdit. Make sure you make textEdit public in the designer.
If you don't want to make textEdit public, then you can add a getter to subform.
If you use the MVC pattern, you create the model object (container for your data) and pass to the text box to fill in the text value itself. When the dialog is closed, just read the value from the model and put it wherever you need it.

Resources