Calling organize imports programmatically - eclipse

I'm trying to execute 'OrganizeImports' programmatically on files that I'm editing programmatically.
My code looks like this:
final ICommandService cmdService = (ICommandService)PlatformUI.getWorkbench().getService (ICommandService.class);
if (cmdService != null) {
final Command cmd = cmdService.getCommand(IJavaEditorActionDefinitionIds.ORGANIZE_IMPORTS);
final ExecutionEvent execEvt = new ExecutionEvent(cmd, Collections.EMPTY_MAP, compileationUnit, null);
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
ResourcesPlugin.getWorkspace().
Display.getDefault().syncExec(new Runnable() {
#Override
public void run() {
try {
//cmd.executeWithChecks(execEvt);
cmd.execute(execEvt);
} catch (Exception e) {
getLogger().severe("organize imports failed: " + e.getMessage());
}
}
My problem is that OrganizeImportsAction executes on the current selection which is not the same as the compilation unit I'm editing. I would like to set the selection programmatically on the compilation unit but I don't know how to do that. Or maybe there is another way to trigger OrganizeImports.
thanks,
stefan

May be this test ui.org.eclipse.jdt.ui.tests.quickfix.CleanUpTest class could offer some clue.
It is based on the enable method in ui.org.eclipse.jdt.ui.tests.quickfix.CleanUpTestCase and on the org.eclipse.ltk.core.refactoring.PerformChangeOperation class.
You can see PerformChangeOperation invoked ink the class org.eclipse.ltk.ui.refactoring.RefactoringWizard.

Related

how to call to context menu in swtboot

I want to call to context menu in my application.
The issue that I don't have any items in the tree.
I active my view and then I want to open context menu.
SWTBotView view = bot.viewByTitle("Project Explorer");
view.bot.tree().contextMenu("New").click();
then I got error message
Could you please advise me how I can open contextMeny without any item in the tree ?
As there is no direct way to do this. I assume you have a shortcut for opening your context menu.
bot.activeShell().pressShortcut(<your shortcut>);
bot.waitUntil(new ContextMenuAppears(tree,
"New"));
tree.contextMenu("New").click();
Where ContextMenuAppears is an ICondition which waits for the desired context menu to appear.
public class ContextMenuAppears implements ICondition {
private SWTBotTree swtBotTree;
private String mMenuText;
public TekstContextMenuAppears(SWTBotTree pSwtBotTree, String menuText) {
swtBotTree = pSwtBotTree;
mMenuText = menuText;
}
#Override
public boolean test() throws Exception {
try {
return swtBotTree.contextMenu(mMenuText).isVisible();
} catch (WidgetNotFoundException e) {
return false;
}
}
#Override
public void init(SWTBot bot) {
// TODO Auto-generated method stub
}
#Override
public String getFailureMessage() {
// TODO Auto-generated method stub
return null;
}
}
depending on what you're trying to achieve, you could try going via the file menu instead of the context menu. "new" should work that way.

How do I manage console output in a long running Eclipse plug-in?

I have written an Eclipse plugin that works. What happens, though, is that during the run, no console output is displayed. Only when the process is finished does the output show up in the console. Below is my handler, which appears as an extension point of type org.eclipse.ui.commands:
public class MyHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
...
MessageConsoleStream out = myConsole.newMessageStream();
...
IConsoleView view = (IConsoleView) page.showView(id);
view.display(myConsole);
...
out.println("output that only shows up at the end");
myConsole.activate();
...
// Slow process
...
out.println("everything is done");
return null;
}
}
So while the process runs, nothing in the console. Then at the end, both output lines pop into view.
I'm obviously doing the console thing incorrectly, but I haven't found any good examples, nor has my experimentation proven very fruitful. Please advise.
You could consider using a ProgressMonitor (possibly with cancelation in case the user wants to abort), so that the user can see that there is something going on.
This worked:
public class Merge extends AbstractHandler {
private static MessageConsole myConsole = null;
private static ExecutionEvent event = null;
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
Merge.event = event;
//same idea as original post and other examples where it makes new or finds existing
myConsole = makeConsole(Merge.event);
Job job = new Job("My Job Name"){
#Override
protected IStatus run(IProgressMonitor monitor){
...
if (blah) {
MessageConsoleStream out = myConsole.newMessageStream();
out.println("output show up right away");
...
// Slow process
...
out.println("everything is done");
} else {
MessageDialog.openInformation(HandlerUtil.getActiveShell(Merge.event), "Information", "Please select valid file");
}
monitor.done();
return Status.OK_STATUS;
}
};
job.setUser(true);
job.schedule();
return null;
}
...
}
Maybe you can call out.flush() after every out.print...

How can I correctly update a progress bar for an operation of unknown duration within an Eclipse wizard?

I have implemented a wizard for my Eclipse plug-in, showing several pages. One of these pages needs some lengthy initialization, that means it consists of a SWT table, which needs to be populated by information coming from an external source. This source needs to be activated first (one single method call that returns after a couple of seconds - I can not know in advance how long it will take exactly), before it can be used as input for for the table viewer. This initialization is currently done by the table model provider when it needs to access the external source for the first time.
Therefore, when I enter the wizard page, I would like to show a dummy progress bar that just counts up for a while. My approach was the following, but unfortunately does not work at all:
private void initViewer() {
IRunnableWithProgress runnable = new IRunnableWithProgress() { // needed to embed long running operation into the wizard page
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
SubMonitor progress = SubMonitor.convert(monitor);
Thread thread = new Thread() {
#Override
public void run() {
Display.getDefault().syncExec(new Runnable() {
public void run() {
viewer.setInput(ResourcesPlugin.getWorkspace().getRoot()); // this will make the table provider initialize the external source.
}
});
}
};
thread.start();
while(thread.isAlive()) {
progress.setWorkRemaining(10000);
progress.worked(1);
}
progress.done();
}
};
try {
getContainer().run(false, false, runnable);
} catch(Exception e) {
throw new Exception("Could not access data store", e);
}
}
This method gets then invoked when the wizard page's setVisible()-method is called and should, after a couple of seconds, set the viewer's input. This, however, never happens, because the inner-most run()-method never gets executed.
Any hints on how to deal with long-running (where an exact estimate is not available) initializations in Eclipse wizards would be very appreciated!
I have given below a simple example on how to use IRunnableWithProgress along with a ProgressMonitorDialog to perform a task of unknown quantity. To start with, have an implementation to IRunnableWithProgress from where the actual task is performed. This implementation could be an inner class.
public class MyRunnableWithProgress implements IRunnableWithProgress {
private String _fileName;
public MyRunnableWithProgress(String fileName) {
_fileName = fileName;
}
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
int totalUnitsOfWork = IProgressMonitor.UNKNOWN;
monitor.beginTask("Performing read. Please wait...", totalUnitsOfWork);
performRead(_fileName, monitor); // This only performs the tasks
monitor.done();
}
}
Now, a generic implementation to ProgressMonitorDialog can be created as below which could be used for other places where a progress monitor dialog is required.
public class MyProgressMonitorDialog extends ProgressMonitorDialog {
private boolean cancellable;
public MyProgressMonitorDialog(Shell parent, boolean cancellable) {
super(parent);
this.cancellable = cancellable;
}
#Override
public Composite createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
setCancelable(cancellable);
return container;
}
}
Having got the required implementation, the task can be invoked as below to get it processed with a progress dialog.
boolean cancellable = false;
IRunnableWithProgress myRunnable = new MyRunnableWithProgress(receivedFileName);
ProgressMonitorDialog progressMonitorDialog = new MyProgressMonitorDialog(getShell(), cancellable);
try {
progressMonitorDialog.run(true, true, myRunnable);
} catch (InvocationTargetException e) {
// Catch in your best way
throw new RuntimeException(e);
} catch (InterruptedException e) {
//Catch in your best way
Thread.currentThread().interrupt();
}
Hope this helps!
I assume the reason why it's "not working" for you is that the preparation of input is done in UI thread meaning that the progress bar cannot be updated. A better approach is to prepare input in advance and only set input to viewer after that.

Find the open eclipse dialog programmatically

It is possible to find an active page/editor in eclipse. How can we programmatically get hold of the instance of the open modal dialog in eclipse.
There are no corresponding interface in Eclipse to access any current model dialog. The best approximation is Display.getActiveShell(), which will return the shell that hosts the active dialog if one exists.
[Dialogs are implemented by having their own event loop, so it can be rather difficult to run your own code...]
EDIT: Based on your comment below, here is a small snippet I use constantly to test for the presence of specific preference pages. I guess this can be used used as the starting point for your own test... Note the use of Display.timerExec(...).
public void test(String pageId) {
try {
final IWorkbench workbench = PlatformUI.getWorkbench();
final Shell[] shells = workbench.getDisplay().getShells();
final ICommandService cs = (ICommandService) workbench.getService(ICommandService.class);
final ParameterizedCommand command = cs.deserialize("org.eclipse.ui.window.preferences(preferencePageId="
+ pageId + ")");
assertNotNull(command);
final IHandlerService hs = (IHandlerService) workbench.getService(IHandlerService.class);
// Have to use timerExec to get the runnable executed after the dialog is shown
workbench.getDisplay().timerExec(2000, new Runnable() {
#Override
public void run() {
assertEquals(shells.length + 1, workbench.getDisplay().getShells().length);
final Shell lastShell = findLastShell(workbench.getDisplay().getShells(), shells);
assertNotNull(lastShell);
final Object data = lastShell.getData();
assertNotNull(data);
assertTrue(data instanceof PreferenceDialog);
lastShell.close();
assertEquals(shells.length, workbench.getDisplay().getShells().length);
}
private Shell findLastShell(Shell[] currentShells, Shell[] oldShells) {
CheckNext: for (final Shell cs : currentShells) {
for (final Shell os : oldShells) {
if (os == cs) {
continue CheckNext;
}
}
return cs;
}
return null;
}
});
hs.executeCommand(command, null);
} catch (final Exception ex) {
fail(ex.getMessage());
}
}

Java process problem in Eclipse

This is my code:
final String run_tool ="cmd.exe /C pelda.exe";
final Process tool_proc = null;
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
InputStream toolstr = tool_proc.getInputStream();
After the eclipse gives this warning message fot the tool_proc variable:
The final local variable tool_proc
cannot be assigned, since it is
defined in an enclosing type
I dont't know why my code doesn't work
please help me
The final modifier forbids changing the variable once it has been set. Kevin gives an excellent explanation of why you can't use it in this context.
The construction you have chosen for requires you to introduce a field in the parent class and set it via run():
class MyClass {
Process tool_proc = null;
void myFunction() {
final String run_tool ="cmd.exe /C pelda.exe";
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
// tool_proc will be null at this point!
InputStream toolstr = tool_proc.getInputStream();
}
}
In the above code I have demonstrated that tool_proc will always be null on the last line, as the thread has in all liklihood not finished its execution by this time!
You can expect NullPointerExceptions!
It seems what you are trying to do is very similar to this article about capturing application output asynchronously. It's a good read, and explains why conventional approaches can cause problems. I have an implementation very similar to their StreamGobbler (article page 4).
I know a good trick since i'm C++ coder and always want pointers in java :
final String run_tool ="cmd.exe /C pelda.exe";
final Process tool_proc[] = new Process[1];
Runnable doRun = new Runnable() {
public void run() {
try {
tool_proc[0] = Runtime.getRuntime().exec(run_tool);
}
catch (IOException e) {
e.printStackTrace();
}
}
};
Thread th = new Thread(doRun);
th.start();
InputStream toolstr = tool_proc.getInputStream();
The tool_proc variable is final - final variables can only be assigned once, and you already assigned it the value null in the declaration. Removing the null assignment won't work because the runnable can be called more than once, resulting in multiple assignment. So your best option is to remove the final keyword and it should compile, at least
Edit
As noted in my comment to my answer, I neglected to account for the fact that tool_proc is a local variable, and without the final modifier it cannot be accessed from the anonymous Runnable subclass. As Paul first noted in his answer, you'll have to use a non-final field to store the Process object.
Initial value of final field cannot be changed. Remove final modificator from tool_proc:
Process tool_proc = null;