
Ganymede is out the door! Hooray to everyone who helped make this happen!
Now get to work on Io(?) you slackers. It isn’t going to write itself. ![]()

Ganymede is out the door! Hooray to everyone who helped make this happen!
Now get to work on Io(?) you slackers. It isn’t going to write itself. ![]()
Tags:
Why is it that as every major release draws to a close some hoary, bizzare bug from the depths crawls to the surface like a creature from the imagination of Lovecraft? For this release I must point to bug 235847, a bug that somehow manages to destroy the help menu AND blank the Synchronize view in one fell swoop.
Is an eventual lie
And with strange builds
Even Kim may cry
Tags:
… how many readers here are into face to face gaming? Role playing, table top war gaming, board gaming, stuff of that nature. If you are, how satisfied are you with the available tools that allow you to bring this hobby into the online space?
Tags: question
There was a lot of noise made about how e4 is a community affair. It’s a lie.
It’s all really about Steve Northover. We are merely satellites held aloft by his sheer awesomeness. So awesome, in fact, that we’ve abandoned our traditional splash screen in favor of a picture of him. It’s hard to condense so much awesome into 134,225 pixels but I tried my best.

ps: for the record, that guitar wasn’t pink and adorned with Hello Kitty before he touched it. It spontaneously became that way after he touched it. After he was finished playing it became so despondent at the loss of his touch that it immediately started crying. It’s still crying now, days later That’s how awesome we’re talking about.
pps: Awesome.
Tags:
Hopefully this will be the last post with the words “startup changes” in its title for a very long time to come.
As mentioned previously, in 3.3 we prevent unknown Runnables from executing during the startup procedure via
and
. I last mentioned a strategy for avoiding use of such runnables during the initialization of editors. I believe that advice is still valid. However, there are scenarios where you may legitimately need access to these methods. Without them, for instance, Splash Screen implementors are forced to spin the event loop themselves if they want to do any clever UI work while the workbench is coming up. In an answer to this problem, we’ve added the new
class as API to the 3.4 stream. This class has one static method,
. Calling this method on any thread not created by the UI (ie: any user Thread) will allow that thread to access the Display.async() and Display.sync() methods as if they were one of our privileged startup threads.
For example:
package mail.example; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.application.DisplayAccess; import org.eclipse.ui.splash.AbstractSplashHandler; public class SplashHandlerWIthDisplayAccess extends AbstractSplashHandler { public void init(Shell splash) { super.init(splash); final Color[] color = new Color[] { splash.getDisplay().getSystemColor( SWT.COLOR_YELLOW) }; final Canvas canvas = new Canvas(splash, SWT.NONE); canvas.setBounds(0, 0, splash.getSize().x, splash.getSize().y); canvas.addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { e.gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK)); e.gc.setBackground(color[0]); e.gc.fillOval(0, 0, canvas.getSize().x, canvas.getSize().y); } }); Thread worker = new Thread() { public void run() { DisplayAccess.accessDisplayDuringStartup(); try { Thread.sleep(500); // sleep a little so we can see the // color change } catch (InterruptedException e) { } canvas.getDisplay().syncExec(new Runnable() { public void run() { color[0] = canvas.getDisplay().getSystemColor( SWT.COLOR_GREEN); if (!canvas.isDisposed()) canvas.redraw(); } }); } }; worker.start(); } }
This simple splash handler creates a canvas on the splash shell that will initially have a yellow oval taking up the entirety of the drawing area. We then create a thread which declares that it will be used to access the display during startup. After a short nap this thread will set the color of the oval to green and cause a repaint. You can verify that without the call to
the oval will remain yellow until the splash comes down.
Tags:
I wanted to give a heads up to anyone who’s currently using the org.eclipse.equinox.transforms projects that live in the Equinox incubator. They will be changing shape shortly in an effort to resolve some intractable build issues (alluded to previously). While providing transforms will be virtually identical there will be migration path for older transform bundles. I will outline the changes when the new code is in the incubator which I expect to happen sometime in the next week or so. In the meantime I’ve gone and tagged the existing code with Version_1 for any clients who were making use of it.
Tags:
While applying a patch for the About->Plug-ins dialog the other day (a patch that gets us off of deprecated code. Yay!) I was struck once again at how homely our certificate tray slide out is. It’s really quite ugly and it got me thinking: It’s an isolated piece of code; It’s a low-risk change; It’s potentially a very fun problem to work on (especially if you dig into the custom SWT controls).
It’s a perfect bug for some young would-be committer to step up to.
Tags:
While trying to clean up and refactor the Equinox XSLT transform code (a moderately complex Equinox framework extension broken out among several bundles) that I wrote last year I find myself in one of three situations:
Sigh.
Some days you’re the windshield, other days you’re the bug. ![]()
Tags:
There is another variant of the workbench startup problem I talked about previously that is outlined in bug 195664. In a nutshell, the problem is this.
In your editor (or view) part init method you need to pop up a progress dialog for some reason. When that kicks off, it uses a sync exec to do some work within ModalContext. After the workbench has started, this isn’t an issue, but if you hit this on startup there’ll be issues. The workbench is in a state where non-startup (a)sync execs are batched up for execution at a later time, after initialization is complete. Since we’re invoking one of these guys from the UI thread and waiting for it to complete we’re going to deadlock. Boourns.
So, what to do? Well, to start with, you probably don’t want to do any operation long enough to need a progress bar in the init method. Instead of performing the operation at that time instead defer the operation until after the editor is initialized. To do this you can use UI jobs. For instance, imagine an editor that prompts for a log-in before showing contents and then shows progress while the log-in is verified. The code could look something like the following:
package interactiveEditor; // snip imports public class InteractiveTextEditorWithLogin extends TextEditor { private StackLayout layout = new StackLayout(); private Composite composite; public void init(final IEditorSite site, IEditorInput input) throws PartInitException { setSite(site); setInput(input); Job loginJob = new LoginJob("login", site); loginJob.schedule(); } public void createPartControl(Composite parent) { composite = new Composite(parent, SWT.NONE); composite.setLayout(layout); Label label = new Label(composite, SWT.NONE); label.setText("Please log in."); layout.topControl = label; } protected void createRealContents() { Composite realComposite = new Composite(composite, SWT.NONE); realComposite.setLayout(new FillLayout()); super.createPartControl(realComposite); layout.topControl = realComposite; composite.layout(true); } private final class LoginJob extends UIJob { private final IEditorSite site; private LoginJob(String name, IEditorSite site) { super(name); this.site = site; } public IStatus runInUIThread(IProgressMonitor monitor) { Dialog dialog = new LoginDialog(site.getWorkbenchWindow() .getShell(), site); dialog.open(); return Status.OK_STATUS; } } private final class LoginDialog extends Dialog { private final class LoginRunnable implements IRunnableWithProgress { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("Logging in", 10); for (int i = 0; i < 10; i++) { monitor.worked(1); Thread.sleep(500); } } } private final IEditorSite site; private LoginDialog(Shell parentShell, IEditorSite site) { super(parentShell); this.site = site; } protected Control createDialogArea(Composite parent) { Composite composite = (Composite) super.createDialogArea(parent); Label nameLabel = new Label(composite, SWT.NONE); nameLabel.setText("Name:"); new Text(composite, SWT.SINGLE); Label passwordLabel = new Label(composite, SWT.NONE); passwordLabel.setText("Password:"); new Text(composite, SWT.PASSWORD); return composite; } protected void createButtonsForButtonBar(Composite parent) { createButton(parent, 1, "Login", true); } protected void buttonPressed(int buttonId) { close(); } public boolean close() { boolean code = super.close(); ProgressMonitorDialog pDialog = new ProgressMonitorDialog(site .getWorkbenchWindow().getShell()); try { pDialog.run(false, false, new LoginRunnable()); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } createRealContents(); return code; } } }
Instead of opening the login dialog (and subsequent progress dialog) directly in init we instead spawn a job that will open the the dialogs when executed. The initial contents of the editor is a simple label and only after the heavy lifting has been performed by the job are the real controls for the editor created and populated. This technique will work both when the editor is opened in a running Eclipse instance and when it is restored on startup in subsequent Eclipse instances - the workbench is smart enough not to run UIJobs until everything is settled after a startup.
So, this code will work but it still isn’t necessarily a good idea. Opening a dialog as a consequence of opening an editor is bad form. What would happen if you had two of these editors visible on startup? You’d have two dialogs opened with no idea which editor they belonged to. Instead, you might want to try the following code instead:
package interactiveEditor; // snip imports public class InteractiveTextEditorWithLoginNoJobs extends TextEditor { private final class LoginRunnable implements IRunnableWithProgress { public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask("Logging in", 5); for (int i = 0; i < 5; i++) { monitor.worked(1); Thread.sleep(250); } } } private StackLayout layout = new StackLayout(); private Composite composite; @Override public void init(final IEditorSite site, IEditorInput input) throws PartInitException { setSite(site); setInput(input); } @Override public void createPartControl(Composite parent) { composite = new Composite(parent, SWT.NONE); composite.setLayout(layout); Composite loginComposite = new Composite(composite, SWT.NONE); loginComposite.setLayout(new GridLayout(2, false)); Label label = new Label(loginComposite, SWT.NONE); label.setText("Please log in."); label.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 2, 1)); Label nameLabel = new Label(loginComposite, SWT.NONE); nameLabel.setText("Name:"); nameLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 1, 1)); Text nameText = new Text(loginComposite, SWT.SINGLE); nameText.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 1, 1)); Label passwordLabel = new Label(loginComposite, SWT.NONE); passwordLabel.setText("Password:"); passwordLabel.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 1, 1)); Text passwordText = new Text(loginComposite, SWT.PASSWORD); passwordText.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 1, 1)); Button loginButton = new Button(loginComposite, SWT.PUSH); loginButton.setText("Login"); loginButton.setLayoutData(new GridData(GridData.BEGINNING, GridData.BEGINNING, true, false, 2, 1)); loginButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { ProgressMonitorDialog pDialog = new ProgressMonitorDialog( getSite().getWorkbenchWindow().getShell()); try { pDialog.run(false, false, new LoginRunnable()); } catch (InvocationTargetException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace(); } createRealContents(); } }); layout.topControl = loginComposite; } protected void createRealContents() { Composite realComposite = new Composite(composite, SWT.NONE); realComposite.setLayout(new FillLayout()); super.createPartControl(realComposite); layout.topControl = realComposite; composite.layout(true); } }
This code will embed log in controls into the editor instead of opening a dialog to display them. This is a much less offensive solution, particularly in the restoration case. No one wants a dialog in the eye first thing in the morning after booting Eclipse!
Tags:
People have been asking for the ability to filter the user interface in Eclipse based on some abstract notion of “roles” for many years now. We partially addressed this issue via the introduction of activities but this solution is problematic at best - activities were designed to be gradually revealed over time and they were never really intended for hard lockdown of the user interface. Any effort in this direction could be easily circumvented by a manual call to the Workbench activity manager, for instance. Nonetheless, people have been using it for this purpose simply because there has been no alternative.
There is a lot of discussion happening on bug 201052 (”[RCP] RCP should provide some role based access control to UI elements”) at the moment pertaining to this issue. There are numerous solutions sketched out as proofs of concept and any input into this would be greatly appreciated. This problem wasn’t on our radar at all for 3.4 and without community support it probably wont see the light of day. If this is a problem you’re interested in please take a look at the bug.
Tags: