我正在开发一个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似乎没有被重绘。我错过了什么吗?=
答案 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线程上运行时,需要使用后者!