我有一个以网格布局显示的项目列表。每行都有几个图像按钮。当行数超过1000时,我得到org.eclipse.swt.SWTError: No more handles
例外。
我使用Sleak.java
并发现内存中有许多图像。是否有可能以某种方式重复使用这些按钮?
以下是Sleak
的统计信息。
颜色:8 游标:6 字体:19 图片:1317
代码:
private void looper(List<File> dicomFiles, int start, int stop, int toShow){
for(int i=start; i<stop; i++){
File dicomFile = dicomFiles.get(i);
Composite rowComposite = new Composite(dicomFilecomposite, SWT.None);
rowComposite.setLayout(configRowCompositeLayout());
rowComposite.setLayoutData(getRowCompositeGridData());
rowComposite.setBackground(Colors.CELL_BG_COLOR);
Label dicomFIleLabel = new Label(rowComposite, SWT.NULL);
dicomFIleLabel.setLayoutData(new GridData());
dicomFIleLabel.setText(dicomFile.getName());
dicomFIleLabel.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
dicomFIleLabel.setFont(FONT_10);
Label fileSizeLabel = new Label(rowComposite, SWT.None);
fileSizeLabel.setText((dicomFile.length() / 1000)+" "+Const.KB_LABEL);
fileSizeLabel.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
Composite progBarLabelComposite = new Composite(rowComposite, SWT.None);
progBarLabelComposite.setLayout(new RowLayout());
ProgressBar progressBar = new ProgressBar(progBarLabelComposite, SWT.HORIZONTAL | SWT.SMOOTH);
progressBar.setVisible(true);
Label progressPercentageLabel = new Label(progBarLabelComposite, SWT.None);
progressPercentageLabel.setText(Const.INITIAL_PROGBAR_PERCENTAGE);
progressPercentageLabel.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
Composite btnWrapperComposite = new Composite(rowComposite, SWT.None);
btnWrapperComposite.setLayout(configZeroMarginLayout(true));
GridData btnWrapperCompositeGridData = new GridData();
btnWrapperCompositeGridData.horizontalAlignment = GridData.END;
btnWrapperCompositeGridData.grabExcessHorizontalSpace = true;
btnWrapperComposite.setLayoutData(btnWrapperCompositeGridData);
Composite uploadCancelBtnComposite = new Composite(btnWrapperComposite, SWT.None);
uploadCancelBtnComposite.setLayout(new RowLayout());
Composite uploadBtnComposite = new Composite(uploadCancelBtnComposite, SWT.NULL);
uploadBtnComposite.setLayout(configZeroMarginLayout(false));
ImageButton uploadButton = new ImageButton(uploadBtnComposite, SWT.PUSH);
uploadButton.setImage(Const.UPLOAD_BTN_BG_IMAGE);
uploadButton.setListener(MainShell.this);
uploadButton.setCursor(HAND_CURSOR);
uploadButton.setToolTipText(Const.UPLOAD_LABEL);
ImageButton cancelButton = new ImageButton(uploadCancelBtnComposite, SWT.PUSH);
cancelButton.setImage(Const.DELETE_BTN_BG_IMAGE);
cancelButton.setListener(MainShell.this);
cancelButton.setCursor(HAND_CURSOR);
cancelButton.setToolTipText(Const.DELETE_LABEL);
FileUploadData fileUploadData = loadFileUploadData(progBarLabelComposite, dicomFilecomposite, dicomFile, progressBar, progressPercentageLabel);
uploadButton.setData(fileUploadData);
uploadButton.setData(IMG_BTN_DATA_KEY, Const.UPLOAD_LABEL);
uploadButtons.add(uploadButton);
fileUploadDatas.add(fileUploadData);
cancelButton.setData(fileUploadData);
cancelButton.setData(IMG_BTN_DATA_KEY, Const.DELETE_LABEL);
loadSeparatorField(rowComposite);
}
}
这两行是我理解中出现问题的地方。
ImageButton uploadButton = new ImageButton(uploadBtnComposite, SWT.PUSH);
ImageButton cancelButton = new ImageButton(uploadCancelBtnComposite, SWT.PUSH);
答案 0 :(得分:1)
在SWT中,您无法重复使用按钮,但可以重复使用图像。写一个单例类说ImageCache并缓存其中的所有图像,并在需要的地方从该类中获取图像。 我遇到了同样的问题并以这种方式解决了。 还要在UI组件中创建自定义配置方法并自行配置UI组件,因为在大多数情况下,SWT不会正确处理它们并且资源会泄漏。
SWT最佳实践说“必须缓存所有资源”,因此必须在相应的ItemRenderer中缓存和使用您的字体,颜色,图像。