How to reuse images in SWT

一曲冷凌霜 提交于 2019-12-24 11:13:32

问题


I have a list of items which I display in a grid layout. Each row have couple of image buttons. When the row count reached over 1000 I am getting org.eclipse.swt.SWTError: No more handles exception.

I used Sleak.java and found that there have been a number of images in the memory. Is it possible to reuse these buttons somehow?

Below is the statistics from Sleak.

Colors: 8 Cursors: 6 Fonts: 19 Images: 1317

Code:

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);
        }
    }

In these two lines are where the issue is occurring in my understanding.

ImageButton uploadButton = new ImageButton(uploadBtnComposite, SWT.PUSH);
    ImageButton cancelButton = new ImageButton(uploadCancelBtnComposite, SWT.PUSH);

回答1:


In SWT you can not reuse buttons however you can reuse images. Write a singleton class say ImageCache and cache all the images in it and fetch images from this class wherever required. I faced the same problem and solved it this way. Also create your custom dispose methods in your UI components and dispose UI components yourself because SWT does not disposes them properly and resources leak in most cases.

SWT best practice says that "all resources must be cached" so your fonts, colors, images must be cached and used properly in respective ItemRenderers.



来源:https://stackoverflow.com/questions/24007294/how-to-reuse-images-in-swt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!