SWT Text field setting and RCP command binding to key - java

I have RCP application, and i have a command in it, that launches a wizard of some entity (edit wizard, that shows all fields of entity, and user can change it and finish wizard to save this entity). I'm using JFace data binding to bind entity's field to swt Texts and Combos.
That command have handler (that contains wizard call), and this handler is bind to some button and all works fine.
Then i need to bind this command to some Key combination (Ctrl+E for example). I'm using org.eclipse.ui.bindings extention for it:
<key
commandId="com.project.command"
contextId="com.project.view.context"
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"
sequence="M1+E">
</key>
"com.project.view.context" is made by me to bind to same key combination in 2 different views and it's looks ok (and activates different commands in these 2 views).
But when i open my wizard through this key combination there is a problem:
SWT Text fields dont binds to Integer fields of entity. With String fields it's all ok, and they're binding fine. But Integer fields dont (There are just empty space in it).
What i've tried:
I debugged my wizard and wizard page, and all time entity state is
fine (their Integer fields is correct and not 0 or null)
Tried to write Integer to String Convertors for JFace binding. Didnt help.
I tried disable JFace binding for this fields, and seting Text field
value manual:
swtTextField.setText(entity.getIntegerField().toString());
But this also didnt work! Looks like it's not JFace binding problem,
but SWT text problem? Debuggin this situation :
entity.getIntegerField().toString() = "1234" before and after
"setText" swtTextField.getText = "" before and after "setText"
(And when i run this debug not from Key combination-command call,
all looks good and swtTextField.getText = "1234" after "setText")
Tried to change context of binding extention to default
("org.eclipse.ui.contexts.window") that didnt helped too.
So, summing up, all works fine, when i calling my command through button (or context menu). But there is a problem with Integer->Text fields (String fields works fine) when i calling my command through key combination binding extention.
Have any ideas what's wrong with it?
Added: I found out, that the problem is in key combination. When the key combination contains not-english key symbol (Ctrl+non-english-key my language key symbol, cause our application uses not-english key combinations) then the problem appears: SWT Text doesnt accept Integer values. When the key combinations is english (Ctrl+english-key) - all is ok.
All other commands (without SWT Text fields) works fine too, and they are binded to Ctrl+non-english-key combinations too...
That is very strange and I still dont understand, why that hanneps...

I have bumped into this problem several months ago. The problem was with JFace Data Bindings. What helped:
use org.eclipse.core.databinding.observable.value.IObservableValue for observing your Text. So you can write code like this: IObservableValue yourTextObserveTextObserveWidget = SWTObservables.observeText(yourText, SWT.Modify);
Use org.eclipse.core.databinding.beans.BeansObservables to observe the value of your entity so you can write code like this: BeansObservables.observeValue(yourModel, "yourInt");
Use org.eclipse.core.databinding.DataBindingContext and bind your IObservableValue like this: bindingContext.bindValue(yourTextObserveTextObserveWidget, yourModelTemplateObserveValue, null, null)
So the final code for binding your model to a Text will be like this:
DataBindingContext bindingContext = new DataBindingContext();
IObservableValue yourTextObserveTextObserveWidget = SWTObservables.observeText(yourText, SWT.Modify);
IObservableValue yourModelTemplateObserveValue = BeansObservables.observeValue(yourModel, "yourInt");
bindingContext.bindValue(yourTextObserveWidget, yourModelTemplateObserveValue, null, null);
Please check the documentation of the data binding if you have any further questions. This is working in my program with String, boolean and Integer types. I haven't tested anythig else though.

Related

Search in one GWT ComboBox affects on other ComboBox with the same store

I'm using com.extjs.gxt.ui.client.widget.form.ComboBox GWT version 2.8.2 and gxt 2.3.1a .
I have 2 comboboxes that have the same storage with many values. When I do search in one combobox I see in debug ComboBox lastquery value same as in search string and only single found value in the CombobBox store. But same value I see in other CombobBox which use same storage. So when I'm trying to work with other comboboxes connected (by listener) to second combobox I get an error because I can't load the required values.
com.google.gwt.core.client.JavaScriptException: (TypeError) : Cannot read properties of null (reading 'getValue__Ljava_lang_Object_2')
at Unknown.TypeError: Cannot read properties of null(Unknown#-1)
Maybe some option exists to allow to use of the same storage in several ComboBoxes without affecting each other, i.e. not limit storage with filtered by search string values? Using 2 storages by creating 2 copies is not preferable. Thanks in advance.
UPD: combobox2.getValue() gives null when search was performed earlier. How I can reload storage in this case?
UPD: I created 2 comboboxes with the same storage:
private final ListStore<ComboBoxItemModel<String>> countryStore;
public ComboBox<ComboBoxItemModel<String>> createCountryCombobox() {
ComboBox<ComboBoxItemModel<String>> countriesComboBox = new ComboBox<>();
countriesComboBox.setFieldLabel("Country");
countriesComboBox.setStore(countryStore);
countriesComboBox.setAllowBlank(false);
countriesComboBox.setTriggerAction(ComboBox.TriggerAction.ALL);
countriesComboBox.setDisplayField(ComboBoxItemModel.COMBO_BOX_ITEM_NAME);
countriesComboBox.setValue(countriesComboBox.getStore().getAt(0));
countriesComboBox.setForceSelection(true);
countriesComboBox.setEditable(true);
return countriesComboBox;
}
setEditable(true) option allows to search countries in the list, but it delete values in the storage as result. So I can't load values for other fields connected to second combobox without manual selection in combobox2.
Seems using two storage is quite a simple solution. Other solutions that I tried look like a workaround. I just create copies and it works fine:
ListStore<ComboBoxItemModel<String>> store = new ListStore<>();
store.add(countryStore.getModels());
countriesComboBox.setStore(store);

Designing json to save changing data

I used to save data from a java application by using JSON.
Basically, the application was a complex form. Each value entered by the user was stored with the field name as the key. I came across a problem when the keys were changed when the application became more complex.
Per example,the application had a field "Optionnal Module", so the JSON looked like:
"Optional Module:": "Yes"
Then, we added another "Optional Module", so we had
"Optional Module 1:": "Yes",
"Optional Module 2:": "No"
In the code, I was loading directly the value into the textfield, like optModule.setText(parsedJSON.get("Optionnal Module"));
But when I added the second module, it changed to
if (parsedJSON.get("Optionnal Module") != null) {
optModul1.setText(parsedJSON.get("Optionnal Module"));
} else {
optModul1.setText(parsedJSON.get("Optionnal Module 1"));
}
As you can see, the code can get confusing with all changes made to the application.
I can surely use a Facade design pattern to avoid keep the class simple, but I still have another class to maintain...
I then thought I could had an ID instead of the text field name for the JSON key, which is working. Is it a good practice? Is there another way to deal with these changes?
I hope I'm understable.
Thanks!

"Simply" determining Java Radio Button id

I'm hoping that Java is not as in-elegant as my efforts with it lead me to believe.
I am working with JRadioButtons, and want to programmatically determine an "ID" associated with them. For this, I am trying to read "name" as listed in its NetBeans properties.
In the ide, when I right-click the component, I am given the option of "Change Variable Name..." I use this to set values such as rb1, rb2, etc.
But in the properties panel, there is also the "name" entry which can be set to a different value. I use this to set "id"-s such as 1, 2, etc.
Working with radio buttons, I know that I can have a series of if-statements that, in a handler, ask
Object src = evt.getSource();
int val=-1;
if (src == rb1) { val=1; }
else if (src == rb2) { val=2; }
else if (src == rb3) { val=3; }
else { val=4; }
But, besides requiring me to hard code the id value with the control name myself, where I'm prone to make a transcription error, I want to believe that there is simpler single-statement means to achieve this, something like:
String name = rbGroup.getSelection().getName();
.getText();
.getLabel();
But, I seem to be stuck with the much less elegant and verbose use of multiple if-else statements.
How can I query the control to give me the properties listed in the NetBeans IDE in the simplest means possible?
One way is to use the Action Command of the button:
rb1.setActionCommand("1");
Then in the event handler you can juse use:
String command = evt.getActionCommand();
The action command defaults to the text of the button if you don't set it explicitly.

Java error: Context already contains a binding with name ""

Ok so I have followed this tutorial step by step: Custom Java Desktop Database Application
I can't understand what I'm doing wrong but when I run the application and click on "New Customer" i get the following error:
Caused by: java.lang.IllegalArgumentException: Context already contains a binding with name ""
I believe that it has something to do with the combobox which is binded with the countries list which comes from the database. The binding expression is set to null and binding source is set to countriesList.
Any help would be appreciated guys?
Thanks
SOLVED
When binding elements of the combo box, in the advanced tab, I just set the name to "null"..and it started working.
while giving "null" into Identification's name works, it only works for the second occurance, you may not repeat the "null" string as the name for the third or any other occurances.
Because,
actually the only one we need to remember is, the name needs to be unique. That's all :)
It seems something was changed in Netbeans. The bindings don't need a name, but for some reason Netbeans started adding "" as the name of many bindings. My solution has been to open the .java file in another editor and just removing the last , "" in the createAutoBinding method call.

How to test AjaxFormChoiceComponentUpdatingBehavior in WicketTester

In my Wicket application I used one radio button with "yes" and "no" options. If I select "No", I should display one dropdown choice. I wrote code using AjaxFormChoiceComponentUpdatingBehavior. How do I unittest this using WicketTester?
Solution for Wicket 1.5.x:
AbstractAjaxBehavior behavior = (AbstractAjaxBehavior)WicketTesterHelper.
findBehavior(getTester().getComponentFromLastRenderedPage("path:to:component"),
AjaxFormChoiceComponentUpdatingBehavior.class);
getTester().executeBehavior(behavior);
First select the radio button that you want.
form.select("path to radio button", 0/1)
Then execute ajax behaviour:
tester.executeBehavior((AbstractAjaxBehavior)tester.getComponentFromLastRenderedPage("path to radio buttons").getBehaviors().get(0));
Here is my piece of code which works perfectly for me with select box but should fiat as well for radio button if you change Behaviour class. Needed steps are:
Insert new value into form (use FormTester)
Find behaviour
Execute behaviour on change
Here is an example of code:
//simulate insert new value
FormTester formTester = tester.newFormTester(PANEL_ID + FORM);
formTester.setValue("selectBox", "newValue");
//Find onchange behaviour
AjaxFormComponentUpdatingBehavior behavior =
(AjaxFormComponentUpdatingBehavior) WicketTesterHelper.findBehavior(
tester.getComponentFromLastRenderedPage(PANEL_ID + FORM + ":" + "selectBox"),
ajaxFormComponentUpdatingBehavior.class);
//execute onchange
tester.executeBehavior(behavior);
I missed the par how to update form value in previous answers.
If the radio button is on a form I think you should use the FormTester class:
http://wicket.apache.org/apidocs/1.4/org/apache/wicket/util/tester/FormTester.html
For an example of an Ajax form submit test you can take a look at:
http://www.java2s.com/Open-Source/Java-Document/J2EE/wicket-1.4/org/apache/wicket/ajax/form/AjaxFormSubmitTest.java.htm
Try something like this:
tester.executeAjaxEvent("form:myRadioButtonId", "onchange");
This turns out to be somewhat painful, at least in Wicket 1.4 (I haven't tried with 1.5).
Via a web search, I found hints in Mischa Dasberg's blog. Basically, you can't use the BaseWicketTester.executeAjaxEvent((String componentPath, String event) method because the behavior you're using isn't an AjaxEventBehavior and you can't use the BaseWicketTester.executeBehavior(final AbstractAjaxBehavior behavior) because it wipes out the request parameters.
Mischa's solution was to implement his own executeBehavior method in a parent test case, which worked for his situation, but not for my need, as it assumed the request parameter id was the same as the full component path.
I've done something similar by implementing my own executeAjaxBehavior in an extension of WicketTester, but assuming (as is true in my case) that the request parameter is the last ":" separated section of the component path:
public void executeAjaxBehavior(String path, String value) {
AbstractAjaxBehavior behavior = (AbstractAjaxBehavior) getComponentFromLastRenderedPage(path).getBehaviors().get(0);
CharSequence url = behavior.getCallbackUrl(false);
WebRequestCycle cycle = setupRequestAndResponse(true);
getServletRequest().setRequestToRedirectString(url.toString());
String[] ids = path.split(":");
String id = ids[ids.length-1];
getServletRequest().setParameter(id, value);
processRequestCycle(cycle);
}
Both his solution and mine (based on his) also assume that the behavior is the first (or only) one on the component.
This is a bit clunky, but something like this may work for you.
It might be better if the ids and behavior were gotten separately and passed as parameters, and of course you might do well to find the first behavior that actually was an AjaxFormChoiceComponentUpdatingBehavior instead of blithely assuming it was the first behavior, but this is a start.
This is also similar code to what's inside the BaseWicketTester class for the other behavior testing methods, which might be worth looking through.

Categories

Resources