Eclipse Plugin Development---PopupMenuCreation - performance

I am developing a wizard using eclipse plugin development.
Requirement:
I have to create a context menu that needs to get populated as soon as the user right clicks on the source folder in java project. once the User performs the first step my handler needs to get the selected src folder in my wizard. My wizard contains a treeviewer where i need to get the selected src folder packaged.
My analysis:
i have my handler class that gets the selected packages
SampleHandler.java
public Object execute(ExecutionEvent event) throws ExecutionException {
shell = HandlerUtil.getActiveShell(event);
// Initializing workbench window object
IWorkbenchWindow window = (IWorkbenchWindow) HandlerUtil.getActiveWorkbenchWindow(event);
ISelection sel = HandlerUtil.getActiveMenuSelection(event);
final IStructuredSelection selection = (IStructuredSelection) sel;
Object firstElement = selection.getFirstElement();
if (firstElement instanceof IPackageFragment) {
// Get the selected fragment
IPackageFragment packageFragment = (IPackageFragment) firstElement;
modelPackage = packageFragment.getElementName();
boolean a =!ProjectResourceHelper.isEntityBasePackage(modelPackage);
if(a == true){
MessageDialog.openInformation(shell, "Warning", "Please click from entity base package");
Shell shell = HandlerUtil.getActiveShell(event);
GreenWizard wizard = new GreenWizard();
WizardDialog dialog = new WizardDialog( part.getSite().getShell(), wizard);
dialog.create();
dialog.open();
return null;
}
try{
window.run(true, true, new IRunnableWithProgress(){
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
monitor.beginTask("Layer codes are being generated...", 1);
// Invocation of generate layers method
monitor.worked(1);
// Done with operation completion.
monitor.done();
}
});
}
catch(InvocationTargetException ite){
MessageDialog.openError(shell, "Greenfield Code Generation Exception", ite.getMessage());
}
catch (InterruptedException ie) {
MessageDialog.openError(shell, "Greenfield Code Generation Exception", ie.getMessage());
}
}
I have my main wizard class that is called within this method.
GreenWizard wizard = new GreenWizard();
and my main wizard in return calls my wizard page where i need to get the selection performed on right click by the user.
My Wizardpageclass
public GenerateGreenfieldLayer(IWorkbench workbench,
IStructuredSelection selection) {
super("Greenfield");
setImageDescriptor(ResourceManager
.getImageDescriptor("\\icons\\greenfield-new-wiz.png"));
setTitle("GreenField Generate layer");
setDescription("Select specfic class to grenerate Layers");
}
/**
* Create contents of the wizard.
*
* #param parent
*/
#Override
public void createControl(Composite parent) {
Composite container = new Composite(parent, SWT.NULL);
setControl(container);
container.setLayout(new GridLayout(2, false));
final CheckboxTreeViewer treeViewer = new CheckboxTreeViewer(container,
SWT.BORDER);
tree = treeViewer.getTree();
tree.setToolTipText("Choose package");
GridData gd_tree = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gd_tree.widthHint = 280;
gd_tree.heightHint = 140;
tree.setLayoutData(gd_tree);
treeViewer.setContentProvider(new GreenfieldTreeContentProvider());
treeViewer.setLabelProvider(new WorkbenchLabelProvider());
treeViewer.addSelectionChangedListener(new ISelectionChangedListener () {
public void selectionChanged(SelectionChangedEvent event) {
}
});
}
Can anyone please guide me how to get the selection from object method and pass as treeviewer initial input in my wizard page.
Please correct me if i am missing any steps as i am very new to this.
Thanks in advance

You should separate the code into the following pieces and dataflows:
Handler: get the selection and create the wizard and wizard dialog (as you do already)
Handler->Wizard: use the Wizard's constructor or a custom init(foo) method (which you call from the handler) to set the selected object (or whatever you want to pass as initial data) from the handler
Wizard->WizardPage: When creating the Wizard, instantiate the WizardPage(s) and pass the selection to the wizard pages. (If you need a more complex model which is shared between the Wizard and its pages consider creating an instantiating a simple value-holder class as your wizard model; i.e., a simple java class with your data and getters/setters. That object can then be shared across the pages if you pass it to every page's constructor)
WizardPage: create UI for wizard page, let user modify the model
WizardPage->Wizard: if you do not use the shared wizard model via a value-holder class, have a getXxx() method to let the wizard access the user's input from the page
Wizard: implement Wizard.performFinish() to do the work at the end of the wizard using getContainer().run() instead of having the window.run() call in your handler.

Related

Vaadin 8.4.0 Modal for save confirmation after grid buffer save

We are using a grid to present some data. This grid is not using a data provider but setting its items.
We are working on buffered modd, but we still want to show a modal informing what are we about to save, with the posibility to save or cancel.
SaveEditor method has been removed from grid class in our current version (8.4.0), so cant do it that way.
I have come to a close solution but with some remaining problems.
I have extended grid component to be able to create my own editor:
public class MyGridComponent extends Grid<MyData> {
public MyGridComponent (Class<MyData> beanType) {
super(beanType);
}
#Override
protected Editor<MyData> createEditor() {
return new MyGridEditor(this.getPropertySet());
}
}
On my editor I have overriden following methods:
#Override
protected void doEdit(OutcomeWagerLimit bean) {
copyMyBean = bean;
super.doEdit(bean);
}
#Override
public boolean save() {
String desc = copyMyBean.getDescription();
StringBuilder captionBuilder = new StringBuilder()
.append("Save ")
.append(desc)
.append("?");
StringBuilder messageBuilder = new StringBuilder()
.append("Do you really want to save ")
.append(desc)
.append("?");
openConfirmMsgBox(captionBuilder.toString(), messageBuilder.toString(),() -> super.save(), ()->super.cancel());
return true;
}
With this code clicking on save opens my confirmation modal. If clicking on save, everything works flawlessly, but clicking on my modal cancel which will call to EditorImpl.cancel() method, acts in a weird way. Clicking cancel on my modal will close edition mode, but if I edit again any other row (double clicking on it) grid's save and cancel buttons (not the modal ones) stop working. Not launching any request from client to vaadin's servlet.
Does anyone know any possible solution to this or a better way to reach what I'm trying to achieve?
Thanks in advance
Morning,
Just managed to do it. Since not using dataprovider but normal list, I am the one responsible of saving data in other saveEventListener. That is the moment to present modal and in the "ok" case persist it in database.
So there is no need to override EditorImpl save method and do it in a saveEventListener.
Thanks

Update TextArea while executing processes

i found out that my GUI starts to freeze after 3-4 seconds when I click the "start" button like "no response". When I keep on click the App, it's forced to shut down.
Now I want to prevent this but I got no clue how. Just as far as I know JavaFX runs in a Single Thread, therefore, to update my TextArea while the Methods are executing, I need to run these Methods in another Thread.
I hope someone can help me.
How does my project look like?
I got a FXML, a Controller, a Handler, a Transformer , also a Writer and a Reader class (which are used in the Handler class).
When I click the button, which is bind to a method in the Controller, an instance of Handler is created and this one calls the Reader to read in a text file, transformed to a List of Strings (line by line).
In addition, the lines are getting manipulated. After this, the Writer is used to creat a new file and write the new manipulated lines to this file.
It is also allowed to the user to refer to more than just one file.
What I want is that the textarea shows whenever the reader starts to read a file like "The file ... is being read".
Then append "The file ... is being manipulated" when Transformer comes to action and then
"The file ... is being written" when the new lines are written to the new file.
Here is some code..
Controller:
public class FXMLDocumentController implements Initializable {
#FXML
private TextArea console;
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
Handler hand = new Handler();
hand.handle(files);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
}
Handler:
public class Handler {
public void handle(List<String> files) {
for (String s : files) {
List<String> ls = Reader.readFile(s);
Writer.writeFile(Transformer.transform(ls));
}
}
How should I change my code to update the TextArea whenever a file is read, manipulated or written?
Info: I know the class Handler won't compile as I erased the initialization of the List "files" which contains Strings of file paths.
If I left out relevant information, feel free to ask.
I thank you in advance!
You should execute the handle() method in a background thread:
#FXML
private void handleButtonAction(ActionEvent event) {
System.out.println("You clicked me!");
Thread thread = new Thread(() -> {
Handler hand = new Handler();
hand.handle(files);
});
// this line means the background thread will not prevent application exit:
thread.setDaemon(true);
thread.start();
}
If you want to update the text area with the current status, you need to schedule that back on the FX Application Thread using Platform.runLater(). Probably the cleanest way to do this is not to have Platform.runLater() in the Handler class, but define a field in Handler for "consuming" status messages:
public class Handler {
private final Consumer<String> statusMessageProcessor ;
public Handler(Consumer<String> statusMessageProcessor) {
this.statusMessageProcessor = statusMessageProcessor ;
}
// default processor does nothing:
public Handler() {
this(s -> {});
}
public void handle(List<String> files) {
for (String s : files) {
// similarly for other status updates:
statusMessageProcessor.accept("The file "+s+" is being read");
List<String> ls = Reader.readFile(s);
Writer.writeFile(Transformer.transform(ls));
}
}
}
and then
Handler hand = new Handler() ;
can become
Handler hand = new Handler(message ->
Platform.runLater(() -> console.appendText(message + "\n")));
in the button handler method.

How to dismiss a Alert Dialog in Mono for android correctly?

In my application i have a Custom AlertView, which works quite good so far. I can open it the first time, do, what i want to do, and then close it. If i want to open it again, i'll get
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first
so, here some code:
public Class ReadingTab
{
...
private AlertDialog AD;
...
protected override void OnCreate(Bundle bundle)
{
btnAdd.Click += delegate
{
if (IsNewTask)
{
...
AlertDialog.Builer adb = new AlertDialog.Builer(this);
...
View view = LayoutInflater.Inflate(Resource.Layout.AlertDView15ET15TVvert, null);
adb.setView(view)
}
AD = adb.show();
}
}
}
that would be the rough look of my code.
Inside of btnAdd are two more buttons, and within one of them (btnSafe) i do AD.Dismiss() to close the Alert dialoge, adb.dispose() hasn't done anything.
the first time works fine, but when i call it the secon time, the debugger holds at AD = adb.show(); with the Exception mentioned above.
So what do i have to do, to remove the Dialoge from the parent? i can't find removeView() anywhere.
If you are setting up an AlertView once and then using it in multiple places (especially if you are using the same AlertView across different Activities) then you should consider creating a static AlertDialog class that you can then call from all over the place, passing in the current context as a parameter each time you want to show it. Then when a button is clicked you can simply dismiss the dialog and set the instance to null. Here is a basic example:
internal static class CustomAlertDialog
{
private static AlertDialog _instance;
private const string CANCEL = #"Cancel";
private const string OK = #"OK";
private static EventHandler _handler;
// Static method that creates your dialog instance with the given title, message, and context
public static void Show(string title,
string message,
Context context)
{
if (_instance != null)
{
throw new Exception(#"Cannot have more than one confirmation dialog at once.");
}
var builder = new AlertDialog.Builder(context);
builder.SetTitle(title);
builder.SetMessage(message);
// Set buttons and handle clicks
builder.SetPositiveButton(OK, delegate { /* some action here */ });
builder.SetNegativeButton(CANCEL, delegate { /* some action here */});
// Create a dialog from the builder and show it
_instance = builder.Create();
_instance.SetCancelable(false);
_instance.Show();
}
}
And from your Activity you would call your CustomAlertDialog like this:
CustomAlertDialog.Show(#"This is my title", #"This is my message", this);

lwuit change UI language

I use codenameone to develop my mobile application. In this application I implement some classes and codes manually for instance create all forms by hard coding not using codenameone designer for some reason.
By the way I wanted to navigate in forms like what codenameone use, so I use one variable from type of Form called it prevForm and when I want to open a form I set it to current form and then I show new form.
Ok, that is main scenario. In this application I wanna implement internationalization too, so I create my own hashtable (Farsi and English) for this application.
This is my problem:
How can I set or change language and apply it to forms that I opened?
Is my method for navigate between forms are good?
Here is my code:
public class BaseForm extends Form implements ActionListener {
public BaseForm(){
this.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
}
Command exit, ok, back;
Form prevForm;
protected void initForm(){
}
protected void showForm(){
}
protected void showForm(final Form prevForm){
//String name = this.getName();
//if("Reminder".equals(name) || "3Transaction".equals(name))
{
this.prevForm = prevForm;
Form f = this;
back = new Command("Back");
//ok = new Command("Ok");
//delete = new Command("Delete");;
Button button = new Button("Button");
f.addCommand(back);
//f.addCommand(ok);
//f.addCommand(delete);
//f.addComponent(button);
f.addCommandListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (ae.getCommand().equals(back)) {
//Do Exit command code
System.out.println("Back pressed");
prevForm.showBack();
} else if (ae.getCommand().equals(ok)) {
//Do Start command code
System.out.println("Ok pressed");
}
}
});
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
//Do button code
System.out.println("Action performed");
}
});
}
showForm();
}}
for open nested form I use this code:
LanguageUI lang = new LanguageUI();
lang.showForm(this);
change language [form]:
protected boolean onBtnSave() {
if(isRbFarsiSelected()){
UIManager.getInstance().setResourceBundle(new CommonSettings().getFarsi());
}
else {
UIManager.getInstance().setResourceBundle(new CommonSettings().getEnglish());
}
return false;
}
I also hard code my UI on lwuit, and i have a variable parentForm on every class so i can easily show previous form. For language change i know there is Localization in the resource editor that you can make use of. Below is how you can access it. I guess the trick is how to set the content of the L10N in the res file in code? On the other hand you can create your own helper classes that mirror the methods below.
Resources theme = Resources.open("/theme.res");
theme.getL10N(id, locale);
theme.getL10NResourceNames();
theme.isL10N(name);
theme.listL10NLocales(id)

Double-click seems to disrupt Wicket-Spring injection

Our application uses a Wicket front-end, with Spring injection to load our DOAs and manage transactions.
We have discovered that several of our users are double clicking on links/buttons and this is
somehow disrupting the Spring injection, so that subsequent calls to whateverDao.doStuff(obj) throw N.P.E. This
application runs on our client's internal network, and for now, we have politely requested that the
client spread the word amongst their team that single clicks work on all features. But it is apparent
that this is becoming a problem for them.
A common use case involves a "Search" screen showing a list of all Foo objects currently in the system,
which can be filtered via search parameters if desired, and when an item is clicked the user is taken to
a detail page for that specific Foo, initially in a read-only mode. Next, the user may click an
"Edit" button in the corner to switch to edit mode. Then, the user might make some changes and
click "Save" (or possibly click "Delete" to remove the item.)
This scenario involves DAO calls at up to three steps:
1. On the search page, when the item is clicked, to load basic details of that item.
2. On the detail page in read-only mode, when edit is clicked, to load complete details of that item.
3a. On the detail page in edit mode, when save is clicked, to persist the changes.
3b. On the detail page in edit mode, when delete is clicked, to delelte.
In any of these cases, if the user double clicked on the previous step, the next step produces
the error. The reproducablitiy is about 33% with some variations between browsers and OSs.
Any insight on preventing this?
In the samples below, BasePage is our custom extension of Wicket's WebPage containing our menus
and other common page elements, and PageType is an enumeration of CREATE, EDIT, and READ_ONLY details.
Sample code for search page (Java shown, HTML is what you expect):
import org.apache.wicket.spring.injection.annot.SpringBean;
// and other imports
public class FooManagerPage extends BasePage {
#SpringBean
private transient FooDao fooDao;
public FooManagerPage() {
SortableDataProvider<Foo> provider = new SortableDataProvider<Foo>(fooDao);
add(new FeedbackPanel("feedback");
final Form<Foo> searchFooForm = new Form<Foo>("searchFooForm",
new CompoundPropertyModel<Foo>(new Foo()));
// the form's search parameter's go here
// with a 'search' button that filters table below
add(searchFooForm)
List<IColumn<Foo>> columns = new ArrayList<IColumn<Foo>>();
columns.add(new PropertyColumn<Foo>(Model.of("Name"), "name", "name"));
// a couple other columns here
DataTable fooTable = new AjaxFallbackDefaultDataTable<Foo>("fooTable", columns, provider, 10){
#Override
protected Item<Foo> newRowItem(String id, int index, final IModel<Foo> model){
Item<Foo> item = super.newRowItem(id, index, model);
item.add(new AjaxEventBehavior ("onclick") {
#Override
protected void onEvent(AjaxRequestTarget target) {
Foo foo = fooDao.load(model.getObject().getId());
setResponsePage(new FooViewPage(foo, PageType.READ_ONLY));
}
});
return item;
}
};
add(fooTable);
}
}
Sample code for view page (Java shown, HTML is what you expect)::
// several imports, including Spring Bean
public class FooFormPage extends BasePage {
#SpringBean
private transient fooDao fooDao;
public FooFormPage(final Foo foo, PageType type) {
Form<Foo> fooForm = new Form<Foo>("fooForm",
new CompoundPropertyModel<Foo>(foo));
// all of Foo's input elements go here
// are enabled or disabled and sometimes invisible based on PageType
add(fooForm);
SubmitLink submitButton = new SubmitLink("save", fooForm){
#Override
public void onSubmit() {
super.onSubmit();
//***** A double click on the Edit button can cause fooDao to be N.P.E. here *****
fooDao.save(createInitiativeForm.getModelObject().getId());
changePageType(PageType.VIEW, createFooForm.getModelObject());
}
};
add(submitButton);
AjaxLink<Void> editButton = new AjaxLink<Void>("edit"){
#Override
public void onClick(AjaxRequestTarget target) {
// reload the item from DB
//***** A double click on Search Page item will cause fooDao to be N.P.E. here *****
Foo foo = fooDao.load(fooForm.getModelObject().getId());
setResponsePage(new FooPage(foo, PageType.EDIT));
}
};
add(editButton);
// some stuff here that makes save button invisible in READ_ONLY, and Edit visible only in READ_ONLY
// delete button is similar (visible only in CREATE)
}
}
The dependency fields should not be marked as transient, they should be serialized along the page. The wicket-spring module injects serializable proxies into #SpringBean-annotated fields at component/page creation time, so that they can be safely serialized, without worry about serializing the dependencies themselves.

Resources