Passing parameters while showing a view in Eclipse RCP - java

I am creating eclipse RCP application and I am stuck with passing parameter while showing a view.
As the first approach, I tried setting a static variable in View2 from View1 and opened that view (as below). It works.
IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
String viewIdToClose = studentListView.ID;
IViewPart viewToClose = activePage.findView(viewIdToClose);
TableItem item = studentTable.getItem(studentTable.getSelectionIndex());
String text = item.getText(ListViewConstants.TABLE_COLUMN_ONE);
activePage.hideView(viewToClose);
try {
String viewIdToOpen = StudentReview.ID;
StudentReview.userId = text;
activePage.showView(viewIdToOpen);
} catch (PartInitException e) {...}
As this doesn't seem to be a good approach, I tried as per the suggestion mentioned in the below link(accepted answer).
Passing parameters to the view
. In this approach, we can pass parameters only after showing the view.
But the issue I have is, the view to be opened should have the value from selected row while calling showView() i.e, I want to populate the parameters in View 2 based on View 1's selection.
Is there any way to achieve this? Is it good to use PULL instead of PUSH approach?
Any suggestion is appreciated.
Thanks!!!
UPDATE 1:
Approach mentioned in Passing parameters to the view
Interface:
public interface ICommunicationView extends IViewPart{
public void accept(Object parameter);
}
Calling accept():
IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
String viewIdToClose = StudentListView.ID;
IViewPart viewToClose = activePage.findView(viewIdToClose);
TableItem item = studentTable.getItem(studentTable.getSelectionIndex());
String text = item.getText(ListViewConstants.TABLE_COLUMN_ONE);
activePage.hideView(viewToClose);
try {
String viewIdToOpen = StudentReview.ID;
ICommunicationView viewToOpen = (ICommunicationView) activePage.showView(viewIdToOpen);
viewToOpen.accept(text);//Sending userId to Review view
} catch (PartInitException e) { ... }
StudentReviewView:
private String studentId;
//getters and setters
#Override
public void accept(Object parameter) {
setStudentId(parameter.toString());
}
public void createPartControl(final Composite parent) {
...
System.out.println("Student Id" + this.getStudentId());
}
It prints Student Id as null.
Am I missing something obvious?
Thanks!

Here is the good links try this..
http://tomsondev.bestsolution.at/2011/02/07/enhanced-rcp-how-views-can-communicate-the-e4-way/

Platform calls createPartControl when the view is opened by activePage.showView(viewIdToOpen). So don't populate your fields on createPartControl. Do it when setStudentId is called.

I also encountered this problem. Found a way around it by repacking the specific view component that needs to be updated.
Here is a proof of concept that sets a string:
Setter interface:
public interface ViewSetter {
void setMessage(String message);
}
View that gets initialized:
//view that implements ViewSetter
#Override
public void createPartControl(Composite parent) {
label = new Label(parent, SWT.NONE); //label is a field
}
#Override
public void setMessage(final String message) {
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
label.setText(message);
label.pack(true);
}
});
}
Code that creates and initializes the view:
IViewPart view = page.showView(viewID);
ViewSetter viewSetter = (ViewSetter)view;
viewSetter.setMessage("Hello World");

Related

How to fill in ComboBox from an API call?

I need to call an API, get a response, add items to ComboBox and update the view in the plugin.
Attached is the image of the combobox
I need to update the thread Ids as they load from an API. My custom Combobox for this is as shown below. I am not sure how to update the custom component from outside the class. Any help?
public class MyComboBox extends AnAction implements CustomComponentAction {
#Override
public void actionPerformed(#NotNull AnActionEvent e) {
}
#Override
public #NotNull JComponent createCustomComponent(#NotNull Presentation presentation, #NotNull String place) {
ComboBox<String> jComboBox = new ComboBox<>();
jComboBox.setMinLength(100);
jComboBox.addItem("Thread Id: " + UUID.randomUUID().toString());
jComboBox.addItem("Thread Id: " + UUID.randomUUID().toString());
jComboBox.setEnabled(true);
return jComboBox;
}
}
I needed a reference to the already instantiated combobox.
I got it with
MyComboBox myComboBox = (MyComboBox) ActionManager.getInstance().getAction("searchThread")
I added another method in MyComboBox:
public void updateUI(List<String> ids) {
this.ids = ids;
String[] array = this.ids.toArray(new String[0]);
jComboBox.setModel(new DefaultComboBoxModel<>(array));
jComboBox.setSelectedIndex(0);
jComboBox.updateUI();
}
and used:
myComboBox.updateUI(newList);
That solved my problem.

When can I use getString() in a Wicket Ajax TabbedPanel?

I have the following problem with Wicket 7.3 and JQuery 2.1.4:
In a dynamic tabbed panel (tabs are added and removed), I want to localize the tab titles and add tooltips. My code
JQueryGenericPanel() {
....
populateItem( ListItem<ITab> item) {
getString();
results in a warning in the log file:
Tried to retrieve a localized string for a component that has not yet been added to the page. This can sometimes lead to an invalid or no localized resource returned. Make sure you are not calling Component#getString() inside your Component's constructor
Using getString() in the panel (which is on the tab) within its method
onInitialize()
does not work, because its too late. The label is already set to "lazy".
Is there any other method similar to "populateItem()" which I can use?
** Addendum **
The code for the tabbed panel is:
public class MyTabbedPanel extends JQueryGenericPanel<List<ITab>> implements ITabsListener {
...
#Override
protected void onInitialize() {
super.onInitialize();
this.add( new ListView<ITab>( "tabs", this.getModel() ) {
...
#Override
protected void populateItem( ListItem<ITab> item ) {
Label link = new Label( "widgetId", new PropertyModel<String>( somePanel, "getTitle()" ) );
The code in the panel is:
private String title = "default";
public String getTitle() { return title; }
#Override
public void onInitialize() {
title = getString( "someKey" );
}
So the PropertyModel fetches the title with 'getTitle()'. Unfortunately this happens before 'onInitialize()' gets called. So the tab title shows "default" instead of the localized text for "someKey".
Instead of
new Label(itemId, getString("key"))
... use:
new Label(itemId, new ResourceModel("key"));
... or if you doing something fancy with the string:
new Label(itemId, new AbstractReadOnlyModel<String>() {
public String getObject() {
return ... + getString("key") + ...;
}
});

How to display separate console on a custom view?

I have created my custom view and put console onto it with the help of TextConsoleViewer viewer.
It appeared on my view, but it also appeared on main console view, which is also present on layout.
How to avoid this? How to put console on my view only or, may be, it is possible to hide unneeded console on console view?
The code for view part:
public class ChatView extends ViewPart {
public static final String ID = "com.scisbo.eclipse.programw.ChatView";
private ShellMod shell;
private TextConsoleViewer textConsoleViewer;
#Override
public void createPartControl(Composite parent) {
ConsoleFinderService consoleFinderService = (ConsoleFinderService) PlatformUI.getWorkbench().getService(ConsoleFinderService.class);
MessageConsole console = consoleFinderService.findConsole("Chat");
textConsoleViewer = new TextConsoleViewer(parent, console);
shell = new ShellMod(
new PrintStream(console.newMessageStream()),
new PrintStream(console.newMessageStream())
);
}
#Override
public void setFocus() {
textConsoleViewer.getControl().setFocus();
}
}
the code for console finder service
public class ConsoleFinderService {
public MessageConsole findConsole(String name) {
ConsolePlugin plugin = ConsolePlugin.getDefault();
IConsoleManager conMan = plugin.getConsoleManager();
IConsole[] existing = conMan.getConsoles();
for (int i = 0; i < existing.length; i++)
if (name.equals(existing[i].getName()))
return (MessageConsole) existing[i];
// no console found, so create a new one
MessageConsole myConsole = new MessageConsole(name, null);
conMan.addConsoles(new IConsole[] { myConsole });
return myConsole;
}
}
Don't add the console to the console manager.
(If you do need a manager, you might want to implement a separate one.)

Wicket - hide element on AjaxButton during lazy loading

I have a page with AjaxLazyLoadPanel, which contain a long-loading list and submitting AjaxButton.
After the AjaxLazyLoadPanel is ready, when I submit, the another long-loading is executing, and after that I need to refresh whole page. This is where I get myself, the code looks as follows:
AjaxButton button1 = new AjaxButton("submit1") {
#Override
protected void onSubmit(AjaxRequestTarget target, Form form) {
someLongWorkingMethod();
setResponsePage(page); //refreshing page
}
};
add(button1);
And it works perfectly. But what I'm trying to do now - is to disable this button or hide this button (or the whole panel if its necessary) when the method is computing, and when the page refresh with setResponsePage I'd like to have this button back.
I've read many posts/mailing lists about it but nothing helped me, I tried all things that I found and placed it before someLongWorkingMethod():
ajaxLazyLoadPanel.setOutputMarkupId(true);
ajaxLazyLoadPanel.setOutputMarkupPlaceholderTag(true);
ajaxLazyLoadPanel.add(new AttributeAppender("style","display:none;"));
ajaxLazyLoadPanel.setVisible(false);
ajaxLazyLoadPanel.setEnabled(false);
target.add(ajaxLazyLoadPanel);
And the same not for ajaxLazyLoadPanel but for "this" (AjaxButton).
Am I doing something terribly wrong or what? Is this what I'm trying to do even possible? I would really appreciate some help.
In your AjaxButton you could override updateAjaxAttributes() and add an IAjaxCallListener which hides the button via jQuery right after you click the button. When the responsePage is rendered the button appears again. The code for the override looks like this:
#Override
protected void updateAjaxAttributes(AjaxRequestAttributes attributes) {
super.updateAjaxAttributes(attributes);
attributes.getAjaxCallListeners().add(new IAjaxCallListener() {
#Override
public CharSequence getBeforeHandler(Component cmpnt) {
return "$(\"#" + cmpnt.getMarkupId() + "\").hide()";
}
#Override
public CharSequence getPrecondition(Component cmpnt) {
return "";
}
#Override
public CharSequence getBeforeSendHandler(Component cmpnt) {
return "";
}
#Override
public CharSequence getAfterHandler(Component cmpnt) {
return "";
}
#Override
public CharSequence getSuccessHandler(Component cmpnt) {
return "";
}
#Override
public CharSequence getFailureHandler(Component cmpnt) {
return "";
}
#Override
public CharSequence getCompleteHandler(Component cmpnt) {
return "";
}
});
}
Thanks to #Robert Niestroj answer (but working only in newest Wicket 6), I found solution for Wicket 1.5, I hope it will help someone.
Its just similar idea, but achieved with overriding getAjaxCallDecorator for AjaxButton, and using pure Javascript
AjaxButton button1 = new AjaxButton("submit1") {
String id = this.getMarkupId();
#Override
protected void onSubmit(AjaxRequestTarget target, Form form) {
...
}
#Override
protected org.apache.wicket.ajax.IAjaxCallDecorator getAjaxCallDecorator() {
return new AjaxCallDecorator() {
#Override
public CharSequence decorateScript(Component component, CharSequence script) {
return "document.getElementById(\'"+id+"\').style.display = 'none';"+script;
}
};
}
};
Important thing to remember is to ensure that you are returning script+[your added script], because otherwise your onsubmit action won't happen.
More info (and also onSucces and onFailure versions) in Wicket 1.5 doc

Apache wicket: how to update model after validation error

I have form with dateTimeField, and ListView.
ListView looks like that:
final ListView<String> countryView = new ListView<String>("country", model.<List<String>>bind("country")) {
#Override
protected void populateItem(final ListItem<String> item) {
final String country = item.getModelObject();
item.add(new ValidationDisplayableLabel("country", country, new String[] { modelPath }));
item.add(new AjaxLink("deleteLink") {
#Override
public void onClick(AjaxRequestTarget target) {
model.getObject().getCountry().remove(country);
if (issPeriod) {
addButton.setVisible(true);
countryTextField.setVisible(true);
findButton.setVisible(true);
}
if (target != null)
target.addComponent(rowPanel);
}
});
}
};
countryTextField = new ValidationDisplayableTextField("countryCodeInput", model.bind("oneCountry"), "job.country.value");
**countryView.setReuseItems(true);**
rowPanel.add(countryView);
rowPanel.add(countryTextField);
addButton.setOutputMarkupPlaceholderTag(true);
rowPanel.add(addButton);
And the addButton looks like that:
AjaxSubmitLink addButton = new AjaxSubmitLink(LinkNames.addCountry.toString()) {
#Override
public void onSubmit(AjaxRequestTarget target, Form form) {
if (model.getObject().getOneCountry() != null)
addCountry();
if (target != null)
target.addComponent(rowPanel);
target.addComponent(form.getPage().get("feedbackPanel"));
}
#Override
protected void onError(AjaxRequestTarget target, Form<?> form)
{
onSubmit(target, form);
}
};
The thing is, that when I fail my dateTimeField (e.g. set hours to 100), enter country code in countryTextField, and press on addButton, it displays validation message in feedback panel, that hour range is incorrect, but don't add the country. This is because my model isn't updated. Maybe there is a way to update it manually? So validation message will be displayed, but the country listView still could be updated?
Submit of the whole form is on other button, so logically it is normal to add a country even if there is a validation error in dateTimeField.
Thanks!
P.S. i've read a lot of posts about similar problem, but most of them were solved with .setReuseItems(true), but it doesn't work in my case.
P.P.S Apache wicket 1.4.17
As an update to this answer, in Wicket 6, you can accomplish this by overriding onError() in the Form:
#Override
protected void onError() {
super.onError();
this.updateFormComponentModels();
}
I faced a similar problem in my project, the workaround I found was to use a special Visitor. It will update the model even though the submitted input is invalid.
public class VisitorUpdateModelWithoutValidation implements FormComponent.IVisitor {
public Object formComponent(IFormVisitorParticipant formComponent) {
if (formComponent instanceof FormComponent) {
final FormComponent<?> formComponent1 = (FormComponent<?>) formComponent;
boolean required = formComponent1.isRequired();
if (required) {
formComponent1.setRequired(false);
}
formComponent1.modelChanging();
formComponent1.validate();
formComponent1.updateModel();
formComponent1.modelChanged();
if (required) {
formComponent1.setRequired(true);
}
}
return Component.IVisitor.CONTINUE_TRAVERSAL;
}
}
Simply use it in the onSubmit method of your behavior : getForm().visitFormComponents(new VisitorUpdateModelWithoutValidation());
You can issue a field.clearInput() on the fields you are updating before you target the update(s).

Categories

Resources