I have an issue with the AutoCompleteTextField component.
It is displayed on a form, which also contains a Picker (set with Display.PICKER_TYPE_TIME type);
So before clicking on the picker all works well: the AutoCompleteTextField shows (after writing some characters) a list populated with String elements.
But after using the hour picker (that seems to display over the layer), the AutoCompleteTextField list already contains the String elements, but the height of this list is very short (list.getHeight() at only 9px, when it should be 105px).
Moreover, I noticed the same issue after using the AutoCompleteTextField setText() method (even after performing a backspace operation).
For your information, I don’t use the setCompletionRenderer() method. I just use the constructor (new AutoCompleteTextField with DefaultListModel<String>) and the setHint() method.
Thanks for advance for your help
After making a change that does or may trigger a change in the layout and requires a reflow of the UI you need to explicitly invoke revalidate() or animateLayout().
See this discussion on layout reflows.
unfortunately the problem persists.
I try with this simple block of code:
Form form = new Form("test");
AutoCompleteTextField actf = new AutoCompleteTextField("Short", "Shock", "Sholder", "Shrek");
form.add(actf);
form.show();
actf.setText("Short"); //triggers the issue
form.revalidate(); //that does not solve the issue
form.getContentPane().animateLayout(0); //neither
Related
I'm working with React Force Graph (2D - https://github.com/vasturiano/react-force-graph) and trying to display custom tooltip on node hover.
This custom Tooltip (dummy component) would display data that's not returned by node - I'd like to add some details to the tooltip, and those are not stored in node data that's returned for example by onNodeHover).
I've seen that I could use nodeLabel which displays simple text label... but it accepts only strings and some simple string interpolations. Unfortunately I can't pass a component as params.
Does anyone know what would be a good approach to this? How this could be handled? Extra points for working examples :D
So here's the answer:
nodeLabel doesn't accept React Node but can easily accept string. So workaround for that problem is just passing the whole stringified html code to nodeLabel and RFG will handle that! This is the best solution I believe (althou native RFG tooltip doesn't support left/right - top/bottom switching in case tooltip would be cut by the edge of screen, but thats minor problem).
other solution that I wouldn't recommend would be to create useCursorPosition and whenever onNodeHover returns something else than null we can set state of displayNode to true (and display it conditionally based on this state) in positions returned by useCursorPosition. This solution is flaky thou, because sometimes onNodeHover doesn't return null I user scrolls fast outside the canvas boundaries (hence the tooltip stays displayed forever). In this solution it's also recommended to use requestAnimationFrame to limit the listener on cursor position.
in my app, when editing a record, I've added an ActionListener to save a temporary copy of the edited values for each field automatically, so that if the app is put in the background and then stopped, the edited values can be recovered when the app is started up again.
However, with the TextAreas it doesn't work since actionListeners don't get called unless the user takes some action (like leaving the field). I need to use the TextArea since there can be multiple lines of text, so using a DataChangedListener for a TextField as suggested in this thread does not seem a viable solution. And being able to save the TextAreas is important to achieve good UX since the user likely loses more work when text is dropped than if for example a value set in a Picker is lost.
Is there another way to achieve this result?
Thanks in advance
TextField allows multiple lines using setSingleLineTextArea(false). When invoked it will function similarly to TextArea.
I've spotted two arrows in the Lightweight Pickers, they seem to be used to go from a field to another.
This behavior is really buggy in my editor and cause encoding errors from some customers. Is there a way to hide/remove them ? If possible in the whole app ?
I've tried to override the Picker and set the return of isEditable to false, as it seemed to control the adding of those arrows, but that has done nothing.
Thanks in advance !
EDIT: In this precise case, I'm using a lightweight Picker with type PICKER_TYPE_STRINGS, but I'd like to control this behavior on all lightweight Pickers.
The picker is instanciated from a PickerComponent with the static createStrings method.
Here is the screenshot of this specific picker and the buttons I want to get rid of are within the red rectangle :
EDIT 2 : Aftert some code analysis, I've found those arrows are shown if the TabIterator of the enclosing Form return previous and next components for this picker. I really don't understand how I dreamed that isEditable was controlling this !
It's possible to override the getTabIterator of the Form, but the constructor of TabIterator (nested class of Form) is private, so unreachable in our classes, and we need it because there no null check on the TabIterator instance when it's called, so we can't return null.
I've tried forcing the parameter of the getTabIterator to null, but the getNext and getPrevious methods of TabIterator return null only if the component is null and the component List (passed as second arg of the TabIterator constructor) is empty. But as the constructor is private, the List is never empty as it's filled by the getTabIterator.
Dead end ?
This is mostly designed for paging between multiple entry fields seamlessly. It seems this isn't pluggable as it should be. You should probably file an RFE so we can provide a way to customize this.
You can file an RFE in the issue tracker here: https://github.com/codenameone/CodenameOne/issues/
A possible workaround might be invoking remove() over the tab iterator until it's empty.
I need activate the last tab in tabpanel in extjs. I have a button that adds new tabs and I need to change the last added.
You can get the length of the items array and setActiveTab using that.
var last = tabPanel.items.length -1;
tabPanel.setActiveTab(last)
Here is fiddle demonstrating a simple working example.
Sencha docs is a huge help in figuring these things out.
I've stumbled on an issue with Comboboxes in javafx2.2. This is the scenario:
Users click on the 'editFile' button.
Another pane becomes visible (with the setVisible method).
This pane contains 6 comboboxes.
Three of them have fixed items: cboReport, cboSales, cboSend. Three of them get their data from a db (ObservableList) and get populated when the pane becomes visible: cboFile, cboCustomer, cboVet
The user selects a file number from the cboFile. The rest of the comboboxes are beeing set with the correct values.
The user presses the save button, the file gets saved as intended.
Next the user presses a close button.
When the window closes, the data on the pane gets resetted through a resetGUI_editFilePane() method. There is have lines like:
...
cboReport.getSelectionModel().clearSelection();
cboSales.getSelectionModel().clearSelection();
cboSend.getSelectionModel().clearSelection();
cboFile.getSelectionModel().clearSelection();
cboCustomer.getSelectionModel().clearSelection();
cboVet.getSelectionModel().clearSelection();
cboFile.getItems().clear();
cboCustomer.getItems().clear();
cboVet.getItems.clear();
...
When the user opens the pane again by pressing the 'editFile' button I notice that only the 'fixed item' comboboxes have cleared their selection, the dynamicly filled comboboxes show the last selected item although the value from the selection itself is null. This looks like a graphics bug to me or am I doing something wrong?
Is there any way around this issue or what is the best method to reset a combobox?
EDIT 2014/08/27:
This is officially not a bug(clearSelection() does not clear value):
https://bugs.openjdk.java.net/browse/JDK-8097244
The official "workaround" is to clear the value of the ComboBox after clearing selection.
cb.getSelectionModel().clearSelection();
// Clear value of ComboBox because clearSelection() does not do it
cb.setValue(null);
It is very simple. You just need to work with the value property of ComboBox. here you go ....
ComboBox c;
c.valueProperty().set(null);
I hope this works for you :-D
I ran into nearly the exact same situation and came across your question while looking for a solution. Fortunately, I came up with a workaround that forces the ComboBoxes to reset. When you reset the data on your pane, instead of doing something like:
cboVet.getSelectionModel().clearSelection();
cboVet.getItems.clear();
do something like this...
parentNode.getChildren().remove(cboVet);
cboVet = new ComboBox(); // do whatever else you need to format your ComboBox
parentNode.add(cboVet);
You'll also need to do a setItems() again on your ComboBox so the new one will be populated. This is not an ideal solution but it seems to be working as I expect the provided clearSelection() method would.
You can retrieve the items and have them all removed:
cboVet.getItems().removeAll(cboVet.getItems());
I've just tested a working solution with the Java JDK 1.7.11:
combobox.setSelectedItem(null);
combobox.setValue(null);
Hope it helps :)
I use reflection with direct manipulation of buttonCell field in ComboBox skin:
#SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> void resetComboBox(ComboBox<T> combo) {
Skin<?> skin = combo.getSkin();
if(skin==null){
return;
}
combo.setValue(null);
Field buttonCellField;
try {
buttonCellField = skin.getClass().getDeclaredField("buttonCell");
buttonCellField.setAccessible(true);
ListCell buttonCell = (ListCell) buttonCellField.get(skin);
if(buttonCell!=null){
StringProperty text = buttonCell.textProperty();
text.set("");
buttonCell.setItem(null);
}
} catch (NoSuchFieldException
| SecurityException
| IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
}
I think it's also possible by providing your own buttonCell implementation through buttonCellFactory property
I had the same problem with a ComboBox. The buttonCell of the ComboBox is not updated correctly when I change the items of the ComboBox. This looks like a graphics bug.
I use direct manipulation of buttonCell field in ComboBox.
combo.getButtonCell().setText("");
combo.getButtonCell().setItem(null);
This is the best solution I've found without recreate the ComboBox.
To clear SelectionModel I found nothing better than creating a new instance of Combobox (previous answers update):
myParentNode.getChildren().remove(myCombobox);
myCombobox = new ComboBox();
myParentNode.add(myCombobox);
But this solution evolves other problems: if you use fxml, this combobox will be placed in the wrong place and with wrong parameters. Some fxml parameters are hardly reproduced directly from your controller class code and this is awful to do it every time you need to clear the combobox.
The solution is using custom components instead of creating instances directly in main controller class code, even if these components are standard. This also helps to free some lines in your main controller class by moving component related event methods and other methods to a separate class file, where you use a reference to your main controller class.
How to create custom components in JavaFX FXML Application can be found in http://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm , but note that CustomControlExample class is not needed for every custom component in your application, if it already has an entry point class with start(Satge stage) method.
How to resolve possible errors with reference from custom component controller class to main controller class can be found in JavaFx: how to reference main Controller class instance from CustomComponentController class?
I need to clear selection of the combo box. And this code worked for me:
List<Object> list = new ArrayList<>(comboBox.getItems());
comboBox.getItems().removeAll(list);
comboBox.getItems().addAll(list);