I have an application in which lookup provider is in explorer window and it is a jcomboBox. Its selected value is provided as lookup to other top components and displayed one in editor and one in output window area. The value of the jcombobox is saved at the time of closing the application and initialized into the jcombobox when the application is started.
When I clean and build the application and start the application, the initial value displayed in the jcombobox is not updated in the lookup and listner windows display uninitialized values. Once the new value is selected in the jcombobox it gets displayed in the other windows.
If I close the application without changing the value of the jcombobox and start the application, the lookup is not updated.
If I change the selection in the combobox, close the application and start again, the lookup gets updated.
I expect anytime when the application is started, the other windows will get the value of the lookup. Any help in this regards will be appreciated. Thanks in advance.
The code for the explorer window which provides the lookup is as follows:
public final class ProviderTopComponent extends TopComponent {
public ProviderTopComponent() {
initComponents();
setName(Bundle.CTL_ProviderTopComponent());
setToolTipText(Bundle.HINT_ProviderTopComponent());
associateLookup(new AbstractLookup(content));
}
private void initComponents() {
jComboBox1 = new javax.swing.JComboBox();
jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
jComboBox1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jComboBox1ActionPerformed(evt);
}
});
private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {
str = (String) jComboBox1.getSelectedItem();
content.set(Collections.singleton(str), null);
}
private final InstanceContent content = new InstanceContent();
String str;
// Variables declaration - do not modify
private javax.swing.JComboBox jComboBox1;
void writeProperties(java.util.Properties p) {
// better to version settings since initial version as advocated at
// http://wiki.apidesign.org/wiki/PropertyFiles
p.setProperty("version", "1.0");
p.setProperty("val", (String) jComboBox1.getSelectedItem());
}
void readProperties(java.util.Properties p) {
String version = p.getProperty("version");
// TODO read your settings according to their version
String v = p.getProperty("val");
if(v != null) {
jComboBox1.setSelectedItem(v);
}
}
}
The code for the lookup listener window is as follows:
public final class Listner_1TopComponent extends TopComponent implements LookupListener{
public Listner_1TopComponent() {
initComponents();
setName(Bundle.CTL_editorTopComponent());
setToolTipText(Bundle.HINT_editorTopComponent());
}
...
private void initComponents() {
...
jLabel1 = new javax.swing.JLabel();
...
Collection<? extends String> str_collection;
private Lookup.Result<String> result = null;
String str;
// Variables declaration - do not modify
private javax.swing.JLabel jLabel1;
// End of variables declaration
#Override
public void componentOpened() {
result = org.openide.util.Utilities.actionsGlobalContext().lookupResult(String.class);
result.addLookupListener(this);
}
#Override
public void componentClosed() {
result.removeLookupListener(this);
}
#Override
public void resultChanged(LookupEvent le) {
str_collection = result.allInstances();
if (str_collection.isEmpty()) {
} else {
str = str_collection.iterator().next();
}
jLabel1.setText(str);
jLabel1.repaint();
}
}
Related
I am building a preference page extending the FieldEditorPreferencePage class.
This is the code (some obvious code not displayed):
public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
public static final String PREF_KEY_1 = "checkBoxPref";
public static final String PREF_KEY_2 = "filePref";
private FileFieldEditor pathField;
private BooleanFieldEditor yesOrNoField;
private Composite pathFieldParent;
#Override
public void init(IWorkbench workbench) {
setPreferenceStore(new ScopedPreferenceStore(InstanceScope.INSTANCE, Activator.PLUGIN_ID));
}
#Override
protected void createFieldEditors() {
this.yesOrNoField = new BooleanFieldEditor(PREF_KEY_1, "Check this box!", getFieldEditorParent());
this.pathFieldParent = getFieldEditorParent();
this.pathField = new FileFieldEditor(PREF_KEY_2, "Path:", this.pathFieldParent);
addField(this.yesOrNoField);
addField(this.pathField);
boolean isChecked = getPreferenceStore().getBoolean(PREF_KEY_1);
updatePathFieldEnablement(! isChecked);
}
/**
* Updates the fields according to entered values
*/
private void updatePathFieldEnablement(boolean enabled) {
this.pathField.setEnabled(enabled, this.pathFieldParent);
}
#SuppressWarnings("boxing")
#Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getProperty().equals(FieldEditor.VALUE) && event.getSource() == this.yesOrNoField) {
updatePathFieldEnablement(! (boolean) event.getNewValue());
}
super.propertyChange(event);
}
}
The propertyChange method is there to enable/disable the FileFieldEditor depending on the BooleanFieldEditor value.
It works OK if I change the BooleanFieldEditor valeu by checking or unchecking it, but the propertyChange is not called when I hit the "Restore default values" button.
Do someone see a reason for that?
OK, I think I've got my response.
I went further in my investigation and I got to this code which seems suspect to me:
In class BooleanFieldEditor :
#Override
protected void doLoadDefault() {
if (checkBox != null) {
boolean value = getPreferenceStore().getDefaultBoolean(getPreferenceName());
checkBox.setSelection(value);
wasSelected = value;
}
}
and in class StringFieldEditor
#Override
protected void doLoadDefault() {
if (textField != null) {
String value = getPreferenceStore().getDefaultString(
getPreferenceName());
textField.setText(value);
}
valueChanged();
}
We can see that the FileFieldEditor (that inherits from StringFieldEditor) launches an PropertyChangeEvent to its listeners (valueChanged();) but not the BooleanFieldEditor. I did not find any code indicating that BooleanFieldEditor are using another mechanism. I think this is a bug in jFace.
To get around this problem, I just had to override the FieldEditorPreferencePage#performDefaults method and the result's fine.
I've an combo box which is composed of a text field and a popup with a CellTable showing the suggestion items. The text field has a change handler that updates the CellTable's selection.
When typing a character and clicking an already selected suggestion, the first click is swallowed. The second click works and triggers the selection via the CellTable.addDomHandler(...).
Any idea why first click is swallowed?
Example code:
private static class SuggestFieldTextAndPopupSandbox extends SimplePanel {
private final TextField mText;
private CellTable<Handle<String>> mTable;
private SingleSelectionModel<Handle<String>> mTableSelection;
private SingleSelectionModel<Handle<String>> mSelection;
private ProvidesKey<Handle<String>> mKeyProvider = new SimpleKeyProvider<Handle<String>>();
private PopupPanel mPopup;
private List<Handle<String>> mData;
public SuggestFieldTextAndPopupSandbox() {
mData = Lists.newArrayList(new Handle<String>("AAA"), new Handle<String>("AAB"), new Handle<String>("ABB"));
mSelection = new SingleSelectionModel<Handle<String>>();
mText = new TextField();
mText.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent pEvent) {
mPopup.showRelativeTo(mText);
}
});
mText.addBlurHandler(new BlurHandler() {
#Override
public void onBlur(BlurEvent pEvent) {
mTableSelection.setSelected(startsWith(mText.getValue()), true);
}
});
mText.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent pEvent) {
mText.setText(mText.getText().toUpperCase());
}
});
mTable = new CellTable<Handle<String>>(0, GWT.<TableResources>create(TableResources.class));
mTable.setTableLayoutFixed(false);
mTableSelection = new SingleSelectionModel<Handle<String>>(mKeyProvider);
mTable.setSelectionModel(mTableSelection);
mTable.addDomHandler(new ClickHandler() {
#Override
public void onClick(final ClickEvent pEvent) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
#Override
public void execute() {
mSelection.setSelected(mTableSelection.getSelectedObject(), true);
mText.setFocus(true);
mPopup.hide();
}
});
}
}, ClickEvent.getType());
mTable.addColumn(new TextColumn<Handle<String>>() {
#Override
public String getValue(Handle<String> pObject) {
return pObject.get();
}
});
mTable.setRowData(mData);
mPopup = new PopupPanel();
mPopup.setAutoHideEnabled(true);
mPopup.setWidget(mTable);
mPopup.setWidth("200px");
mPopup.setHeight("200px");
VerticalPanel p = new VerticalPanel();
p.add(mText);
setWidget(p);
}
private Handle<String> startsWith(final String pValue) {
final String val = nullToEmpty(pValue).toLowerCase();
int i = 0;
for (Handle<String> item : mData) {
String value = item.get();
if (value != null && value.toLowerCase().startsWith(val)) {
return item;
}
i++;
}
return null;
}
}
I reproduced your issue and here is the problem:
when you click on the suggestions the following is happening:
The text field is loosing focus which causes the corresponding ChangeEvent to be dealt with followed by the BlurEvent.
The click causes the popup to get the focus now which is why it is swallowed.
If you remove the ChangeHandler and the BlurHandler of the text field the issue disappears. But I think I found another solution
Try replacing the DOM handler of the mTable with a selection handler relative to the mTableSelection as follows:
mTableSelection.addSelectionChangeHandler(new Handler(){
#Override
public void onSelectionChange(SelectionChangeEvent event) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
#Override
public void execute() {
mSelection.setSelected(mTableSelection.getSelectedObject(), true);
mText.setFocus(true);
mPopup.hide();
}
});
}
});
Found a way how to properly solve this.
Skipping the blur handler when user hovers the suggestion list area seemed to fix that issue, at least from the tests that were done didn't see any more issues.
This was necessary because just before the user clicks a suggestion item, the text is blurred and it fires a selection change. This in turn cancels the selection made when user clicks an item.
My Site has on the left a GWT-Tree. In the center is a GWT-TabBar.
Both parts are implemented as Views/Activities/Places. I have two tokenizer: "m" for the tree and "t" for the tabs.
If I visit one place (goTo()) only this place will be used to generate the history token. But I would like to see this: <page>#m:sub/sub/sub;t:map
I actually thought that the hole idea of activities&places. I don't see the point to have multiple tokenizer, when only one tokenizer can provide a token at once.
You cannot display two different tokens #m: and #t: at the same time as you cannot be in two places at the same time.
So if both tabs and tree are displaying at the same time, then the state of both must be stored at once in the same place.
This is more or less what you need.
public class ExamplePlace extends Place {
public String treePosition = "/";
public int tabIndex = 0;
public ExamplePlace() {
super();
}
public ExamplePlace(String treePosition, int tabIndex) {
this.treePosition = treePosition;
this.tabIndex = tabIndex;
}
#Prefix("overview")
public static class Tokenizer implements PlaceTokenizer<ExamplePlace> {
/**
* parse token to get state
*
*/
#Override
public ExamplePlace getPlace(String token) {
String treePosition = "";
int tabIndex = 0;
String[] states = token.split(";");
for (String state : states) {
String[] mapping = state.split("=");
if (mapping.length == 2) {
if ("t".equals(mapping[0])) {
treePosition = mapping[1];
}
if ("m".equals(mapping[0])) {
try {
tabIndex = Integer.valueOf(mapping[1]);
} catch (Throwable e) {
}
}
}
}
return new ExamplePlace(treePosition, tabIndex);
}
/**
* store state in token
*
*/
#Override
public String getToken(ExamplePlace place) {
StringBuffer sb = new StringBuffer();
if (place.getTreePosition()!=null) {
sb.append("t").append("=").append(place.getTreePosition());
sb.append(";");
}
sb.append("m=").append(place.getTabIndex());
return sb.toString();
}
}
public String getTreePosition() {
return treePosition;
}
public void setTreePosition(String treePosition) {
this.treePosition = treePosition;
}
public int getTabIndex() {
return tabIndex;
}
public void setTabIndex(int tabIndex) {
this.tabIndex = tabIndex;
}
}
This will give you URLs that look like ;
index.html#overview:t=/subtree/subtree/leaf;m=2
You might run in trouble with the forward slashes in the token, not sure. Change them to some other character if necessary;
The activity receives the incoming place and inject the state into the view;
I am just creating a new Proxy:
LayoutExampleRequest r = requestFactory.employeeRequest();
DepartmentProxy d = r.create(DepartmentProxy.class);
r.save(d);
departmentEditor.editProxy(d, r);
Then pass the Proxy and the Request(LayoutExampleRequest ) to my editor
driver.edit(proxy, request);
Until here ! everything works as espected. I can save Department objects with null EmployeeProxy. Now iam getting with a suggest box Proxys of EmployeeProxy from the server.
search = new SuggestBox(new SuggestOracle() {
#Override
public void requestSuggestions(final Request request,final Callback callback) {
System.out.println(request.getQuery());
//ignore less than 3
if(request.getQuery().length() > 3){
requestFactory.employeeRequest().search(request.getQuery()).fire(new Receiver<List<EmployeeProxy>>(){
#Override
public void onSuccess(List<EmployeeProxy> response) {
List<MySuggestion<EmployeeProxy>> suggestions = new ArrayList<MySuggestion<EmployeeProxy>>();
for(EmployeeProxy e:response){
MySuggestion<EmployeeProxy> suggestion = new MySuggestion<EmployeeProxy>();
suggestion.setModel(e,e.getFirstName(),e.getFirstName()+" "+e.getLastName());
suggestions.add(suggestion);
}
callback.onSuggestionsReady(request, new Response(suggestions));
}
});
}
}
});
MySuggestion is a wrapper class to handle the EmployeeProxy.
Now i want to add this EmployeeProxy to my DeparmentProxy since i have a #OneToOne on JPA.
search.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
#Override
public void onSelection(SelectionEvent<Suggestion> event) {
MySuggestion<EmployeeProxy> s = (MySuggestion<EmployeeProxy>)event.getSelectedItem();
proxy.setSupervisor(s.getModel());
}
});
proxy is the EntityProxy for Department (I sent to my editor) driver.edit(proxy, request);
then i fire the driver:
departmentEditor.getDriver().flush().fire(new Receiver<Void>() {
#Override
public void onSuccess(Void response) {
Window.alert("Success");
// refresh the datagrid
Range range = dataGrid.getVisibleRange();
dataGrid.setVisibleRangeAndClearData(range, true); //1st way
// create a new DepartmentProxy to bind to the Editor.
createProxy();
// change button text
updateButton.setText("Save");
}
#Override
public void onConstraintViolation(Set<ConstraintViolation<?>> violations) {
for(ConstraintViolation v :violations){
Window.alert(v.getMessage()+" "+v.getPropertyPath());
}
}
#Override
public void onFailure(ServerFailure error) {
Window.alert(error.getMessage());
}
});
The problem is iam getting ConstraintViolations from the EmployeeProxy, is like the driver atach the EmployeeProxy but with null values.
(Iam validating my Entityes with JSR-330 )
Dont know how to make a relationship with a new Proxy with other taked from the server. in a #OneToOne relationship
Any help would be nice!
Thank you
/* UPDATE */
Something like this but with editor
final LayoutExampleRequest r = requestFactory.employeeRequest();
final DepartmentProxy d = r.create(DepartmentProxy.class);
d.setName("Name");
d.setService(Service.CONTRACT_MANAGMENT);
// get some random employee
requestFactory.employeeRequest().findById(1).fire(new Receiver<EmployeeProxy>() {
#Override
public void onSuccess(EmployeeProxy response) {
d.setSupervisor(response);
r.save(d).fire(new Receiver<DepartmentProxy>() {
#Override
public void onSuccess(DepartmentProxy response) {
Window.alert("Kidding me! why editor cant get it work =p?");
}
});
}
});
The problem was i put on my editor properties of the EmployeeProxy so when a user select the employeproxy would see information about it, so i delete them and then do the same and now works.
Is like GWT when detects properties from another proxy on the editor thinks you will fill it. And the line:
proxy.setSupervisor(s.getModel());
doesn't works.
I have a custom Oracle with Objects to pass to the SuggestBox. Then I need get back a object when it's selected from de SuggestBox.
public HandlerRegistration addSelectionHandler(SelectionHandler<SuggestOracle.Suggestion> handler)
The problem is that I don't have Suggestion. I have "CustomSuggestion". I read de API and I try to write a Custom SuggestBox implementing the interface HasSelectionHandlers but I can't because the SuggestBox have a implementation of the interface. I get the error:
The interface HasSelectionHandlers cannot be implemented more than once with different arguments: HasSelectionHandlers<SuggestOracle.Suggestion> and HasSelectionHandlers<CustomSuggestion>
Can you help me? Sorry for my bad english.
Not sure I understand your problem. Have a look at the following example (really basic but you should get an idea on how to deal with custom suggestions). Hope that helps:
public void onModuleLoad() {
SuggestBox box = new SuggestBox(new CustomOracle<CustomSuggestion>());
box.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
#Override
public void onSelection(SelectionEvent<Suggestion> event) {
String value = ((CustomSuggestion) event.getSelectedItem()).fSomeOtherValue;
Window.alert(value);
}
});
RootPanel.get().add(box);
}
private class CustomOracle<CustomSuggestion> extends SuggestOracle {
private LinkedList<Starter.CustomSuggestion> fStore;
public CustomOracle() {
fStore = new LinkedList<Starter.CustomSuggestion>();
fStore.add(new Starter.CustomSuggestion("2", "two", "foo"));
fStore.add(new Starter.CustomSuggestion("22", "twenty-two", "bar"));
fStore.add(new Starter.CustomSuggestion("222", "two-hundred twenty-two", "w000t"));
}
#Override
public void requestSuggestions(Request request, Callback callback) {
String query = request.getQuery();
LinkedList<Starter.CustomSuggestion> result = new LinkedList<Starter.CustomSuggestion>();
for (Starter.CustomSuggestion entry : fStore) {
if (entry.fDisplay.contains(query)) {
result.add(entry);
}
}
callback.onSuggestionsReady(request, new Response(result));
}
}
private class CustomSuggestion implements Suggestion {
private String fReplace;
private String fDisplay;
private String fSomeOtherValue;
public CustomSuggestion(String display, String replace, String someOtherValue) {
fDisplay = display;
fReplace = replace;
fSomeOtherValue = someOtherValue;
}
#Override
public String getDisplayString() {
return fDisplay;
}
#Override
public String getReplacementString() {
return fReplace;
}
}