Time for action – interacting with the UI

Sometimes it is necessary to write code to run in the UI thread, but when called back via a handler it's not always clear if the method is in the UI thread or not. In Eclipse 3.x, there is a Display.getDefault().syncExec() for running Runnable instances inside the UI thread immediately, or .asyncExec() for running them on the UI thread later. Eclipse 4 introduces the UISynchronize class, which is an abstract mechanism for executing code on the UI thread (it's like an interface for Display, except that Display doesn't implement it and it's not an interface). The syncExec and asyncExec methods can be used to schedule Runnable events. If a long calculation needs to update the UI after concluding, using UISynchronize allows the UI update to be scheduled on the right thread.

  1. Create a new Button as a field in the Hello part, and attach a selection listener such that when it is pressed, it invokes setEnabled(false) on itself. At the same time, schedule a Job to run after one second that invokes setEnabled(true) again:
    private Button button;
    @PostConstruct
    public void create(Composite parent) {
      button = new Button(parent, SWT.PUSH);
      button.setText("Do not push");
      button.addSelectionListener(new SelectionListener() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        button.setEnabled(false);
        new Job("Button Pusher") {
          @Override
          protected IStatus run(IProgressMonitor monitor) {
            button.setEnabled(true);
            return Status.OK_STATUS;
          }
          }.schedule(1000);
        }
        @Override
        public void widgetDefaultSelected(SelectionEvent e) {
        }
      });
      ...
    }
  2. Run the application, and when the button is pushed, the button will be disabled (grayed out) immediately. One second later, an exception will be logged to the console with an Invalid thread access message:
    !MESSAGE An internal error occurred during: "Button Pusher".
    !STACK 0
    org.eclipse.swt.SWTException: Invalid thread access
      at org.eclipse.swt.SWT.error(SWT.java:4491)
    
  3. The error occurs because the setEnabled call must be made on the UI thread. Although Display.getDefault().syncExec() can be used to do this, E4 provides an annotation-based way of doing the same thing. Inject an instance of the UISynchronize into the Hello part:
    @Inject
    private UISynchronize ui;
  4. Modify the Job implementation in the create method as follows:
    protected IStatus run(IProgressMonitor monitor) {
      ui.asyncExec(() -> button.setEnabled(true));
      return Status.OK_STATUS;
    }
  5. Now run the application and press the button. It will be disabled for one second, and then re-enabled afterwards.

What just happened?

  1. Using UISynchronize provides a way to interact with the UI thread safely. Another way of achieving this would be to use a UIJob.
  2. One advantage of using UISynchronize is that it is not necessarily tied down to SWT. E4 provides the option of having different part renderers, which could allow for future runtimes based on HTML or Swing, or JavaFX such as e(fx)clipse.

    Note

    When building plug-ins that will be shared between E4 and Eclipse 3.x systems, continue to use Display.getDefault() or Display.getCurrent() in order to schedule UI updates, as the UISynchronize class is not present in earlier releases.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.183.14