Eclipse RCP应用程序 - 自定义启动画面

时间:2011-12-01 17:51:46

标签: java eclipse eclipse-rcp splash-screen

我正在开发一个Eclipse RCP应用程序,我正在尝试实现一个自定义的启动画面处理程序,运行一个进度条(类似于你可以在.product定义中定义的默认进度条的行为)和多个骑自行车的背景图片。

以这种方式编辑主应用程序插件的扩展名后:

[...]
<!-- install custom splash handler -->
<extension point="org.eclipse.ui.splashHandlers">
   <splashHandler
        class="com.example.application.splash.SlideShowSplashHandler"
        id="splash.slideshow">
   </splashHandler>
   <splashHandlerProductBinding
        productId="com.example.application.product"
        splashId="com.example.application.splash.slideshow">
   </splashHandlerProductBinding>
</extension>
<!-- define images (in plugin root directory) to be shown -->
<extension point="com.example.application.splashExtension">
     <splashExtension id="01" image="01_Splash2Ag.bmp"></splashExtension>
     <splashExtension id="02" image="02_Splash3Ag.bmp"></splashExtension>
     <splashExtension id="00" image="00_Splash1Ag.bmp"></splashExtension>         
</extension>
[...]

我正在尝试实现自定义splashscreen处理程序类:

public class SlideShowSplashHandler extends AbstractSplashHandler {

    private List<Image> fImageList;
    private ProgressBar fBar;
    private final static String F_SPLASH_EXTENSION_ID = "com.example.application.splashExtension"; //NON-NLS-1
    private final static String F_ELEMENT_IMAGE = "image"; //NON-NLS-1
    private int imageIdx = 0;

    public SlideShowSplashHandler() {
        fImageList = new ArrayList<Image>(5);
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell)
     */
    public void init(Shell splash) {
        // Store the shell
        super.init(splash);
            // Force shell to inherit the splash background
            getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT); 
        // Load all splash extensions
        loadSplashExtensions();
        // If no splash extensions were loaded abort the splash handler
        if (hasSplashExtensions() == false) return;
        // Create UI
        createUI(splash);
    }

    private boolean hasSplashExtensions() {
        if (fImageList.isEmpty()) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public IProgressMonitor getBundleProgressMonitor() {
       return new NullProgressMonitor() {

          @Override
          public void beginTask(String name, final int totalWork) {
            getSplash().getDisplay().syncExec(new Runnable() {
              public void run() {
                  fBar.setSelection(50);
              }
            });
          }

          @Override
          public void subTask(String name) {
            getSplash().getDisplay().syncExec(new Runnable() {
              public void run() {
                  if (fBar.getSelection() < 100) fBar.setSelection(fBar.getSelection() + 10);
                  if (imageIdx >= fImageList.size()) imageIdx = 0;
                  Image image = fImageList.get(imageIdx++);
                  getSplash().setBackgroundImage(image);
                  getSplash().setRedraw(true);
                  getSplash().redraw();
              }
            });
          }
        };
    }

    private void createUI(Shell shell) {

        Composite container = new Composite(shell, SWT.NONE);
        container.setLayout(new GridLayout(1, false));
        container.setLocation(5, 374);
        container.setSize(480, 15);

        /* Progress Bar */
        fBar = new ProgressBar(container, SWT.HORIZONTAL);
        fBar.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        ((GridData) fBar.getLayoutData()).heightHint = 13;
        fBar.setMaximum(100);
        fBar.setSelection(25);

        /* Version Label */
        Label versionLabel = new Label(container, SWT.NONE);
        versionLabel.setLayoutData(new GridData(SWT.END, SWT.BEGINNING, true, false));
        //versionLabel.setFont(fVersionFont);
        //versionLabel.setForeground(fVersionColor);
        //versionLabel.setText(NLS.bind(Messages.SplashHandler_BUILD, "2.1 Nightly")); //$NON-NLS-1$

        /* Layout All */
        shell.layout(true, true);
    }   

    private void loadSplashExtensions() {
        // Get all splash handler extensions
        IExtension[] extensions = Platform.getExtensionRegistry()
                .getExtensionPoint(F_SPLASH_EXTENSION_ID).getExtensions();
        // Process all splash handler extensions
        for (int i = 0; i < extensions.length; i++) {
            processSplashExtension(extensions[i]);
        }
    }

    /**
     * Parse the extension points with the images filename.
     */
    private void processSplashExtension(IExtension extension) {
        // Get all splash handler configuration elements
        IConfigurationElement[] elements = extension.getConfigurationElements();
        // Process all splash handler configuration elements
        for (int j = 0; j < elements.length; j++) {
            processSplashElements(elements[j]);
        }
    }

    /**
     * Create the images defined as extension points
     */
    private void processSplashElements(IConfigurationElement configurationElement) {

        String name = configurationElement.getAttribute(F_ELEMENT_IMAGE);
        ImageDescriptor descriptor = Activator.getImageDescriptor("/"+name);
        if (descriptor != null) {
            Image image = descriptor.createImage();
            if (image !=null) {
                fImageList.add(image);
            }
        }
    }

    public void dispose() {
        super.dispose();
        // Check to see if any images were defined
        if ((fImageList == null) ||
                fImageList.isEmpty()) {
            return;
        }
        // Dispose of all the images
        Iterator<Image> iterator = fImageList.iterator();
        while (iterator.hasNext()) {
            Image image = iterator.next();
            image.dispose();
        }
    }
}

问题是进度条正常工作,而图像没有显示。在调试时,我可以验证图像是否实际被找到并加载,并在shell中正确设置; shell似乎没有被重绘。我错过了什么吗?=

2 个答案:

答案 0 :(得分:1)

我可以解决linux和windows上的问题,但它无法在macos / cocoa上工作(在每个图像幻灯片迭代中,启动画面看起来都是“乱码”)。

确实非常简单,只需在splash shell和包含小部件的容器之间附加一个额外的Composite;然后在新创建的容器对象上更改背景图像。

private void createUI(Shell shell) {
    Composite bgcontainer = new Composite(shell, SWT.NONE); // new
    [...]
    Composite container = new Composite(bgcontainer, SWT.NONE);
    [...]
    fBar = new ProgressBar(container, SWT.HORIZONTAL);
    [...]
    Label versionLabel = new Label(container, SWT.NONE);
    versionLabel.setLayoutData(new GridData(SWT.END, SWT.BEGINNING, true, false));
    shell.layout(true, true);
}   

@Override public IProgressMonitor getBundleProgressMonitor() {
return new NullProgressMonitor() {
    @Override public void beginTask(String name, final int totalWork) {
        getSplash().getDisplay().syncExec(new Runnable() {
            public void run() {
                    if (fBar != null) fBar.setSelection(40);
                    Image image = fImageList.get(imageIdx++);
                    bgcontainer.setBackgroundImage(image);
                    bgcontainer.setRedraw(true);
                    bgcontainer.update();                 
                }
            });
        }

    @Override public void subTask(String name) {
        final String n = name;
        getSplash().getDisplay().syncExec(new Runnable() {
            String taskname = n;
            public void run() {
                    if (fBar != null && fBar.getSelection() < 100)
                        fBar.setSelection(fBar.getSelection() + 10);
                    if (fBar.getSelection() == 60 || fBar.getSelection() == 80) {
                        if (imageIdx >= fImageList.size()) imageIdx = 0;
                        Image image = fImageList.get(imageIdx++);
                        bgcontainer.setBackgroundImage(image);
                        bgcontainer.setRedraw(true);
                        bgcontainer.update();
                    }
                 }
             });
         }
    };
}

答案 1 :(得分:0)

我还没有尝试过您的代码,但是当您对Control进行更改时,仅拨打Control.redraw()是不够的,但您还必须致电Control.update()

Control.redraw()请求重新绘制控件,Control.update()实际重绘它。当您的代码在UI线程上运行时,需要使用后者!