是否可以在Multibutton(Codename One)

时间:2017-02-14 21:03:18

标签: java codenameone

我有一个InfiniteScrollAdapter我使用Multibutton来显示包含照片及其描述的列表。

效果很好,但我需要将照片四舍五入。这就是为什么我受到the official guide图像掩盖的启发。不幸的是,我得到的只是一个黑色的圆形。这是我使用的代码:

MultiButton[] cmps = new MultiButton[reports.size()];
for (int iter = 0; iter < reports.size(); iter++) {
    Report currentReport = reports.get(iter);
    if (currentReport == null) {
        InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), new Component[0], false);
        return;
    }

    String photoFilenameInStorage = Report.getFilename(currentReport.getPhotoPath());
    Image reportImage = URLImage.createToStorage(placeholder, photoFilenameInStorage, currentReport.getPhotoPath(), URLImage.RESIZE_SCALE_TO_FILL );
    int w = reportImage.getWidth();
    int h = reportImage.getHeight();

    // Generates a mask to make the image round
    Image maskImage = Image.createImage(w, h, 0xff000000);
    Graphics g = maskImage.getGraphics();
    g.setAntiAliased(true);
    g.setColor(0xFFFFFF);
    g.fillArc(0, 0, w, h, 0, 360);

    Object mask = maskImage.createMask();

    Image maskedImage = reportImage.applyMask(mask);

    String summary = currentReport.getLocation();                        
    cmps[iter] = new MultiButton(summary);
    // Only shows a black filled circle!
    cmps[iter].setIcon(maskedImage);
} 

InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), cmps, true);

我注意到的是,我在CN1中找到的关于圆形图像的所有示例都涉及Label。是否可以在Codename One中的MultiButton上应用蒙版?如果是这样,我该怎么做?

任何帮助表示赞赏,

阅读答案和评论后的摘要2017-02-16

我很难弄明白为什么@ Diamond的答案确实有效而不是我的答案,尽管我确实按照@ Shai的指导进行了掩饰以获得圆润的图像。所以我写了我的调查结果,以防CN1的其他新手遇到这个问题。再次向@Diamond致敬,他的重要解释帮助了很多!

首先,上面介绍的圆形面罩正在工作,因为它会产生黑色圆形。实际上,在应用蒙版时,reportImage尚未下载since quoting from the javadoc

  

默认情况下,除非调用fetch()方法,否则会在GUI请求时懒惰地获取图像,在这种情况下,IO代码会立即执行。

因此,reportImage仍然像定位占位符一样黑。顺便说一下,这就是为什么@Diamond建议定义一个圆形占位符,在实际(圆形)图像可用之前显示一个漂亮的颜色(请参阅他的答案中的第一个cmps[iter].setIcon(placeholder)调用)。

只有当InfiniteScrollAdapter需要并获取图片时才会实际下载URLImage。这就是@Diamond包裹的原因

总而言之,上面的代码无法在InfiniteScrollAdapter中运行,经过我的所有试验后,我倾向于认为实现我想要做的唯一方法是@Diamond用@ Shai编写的代码&#39的建议。

请注意,如果下载的图片是PNG @ Diamond圆形蒙版适配器似乎不再起作用=&gt;如果PNG转换为JPEG ,则生成的图像仅舍入。

1 个答案:

答案 0 :(得分:2)

是的,Multibutton图标是一个Label组件,您可以通过调用

获得
cmps[iter].getIconComponent()

修改

根据Shai的评论,您的代码应该变成这样......

圆形面罩适配器:

private final URLImage.ImageAdapter RESIZE_SCALE_WITH_ROUND_MASK = new URLImage.ImageAdapter() {
    @Override
    public EncodedImage adaptImage(EncodedImage downloadedImage, EncodedImage placeholderImage) {
        Image tmp = downloadedImage.scaledLargerRatio(placeholderImage.getWidth(), placeholderImage.getHeight());
        if (tmp.getWidth() > placeholderImage.getWidth()) {
            int diff = tmp.getWidth() - placeholderImage.getWidth();
            int x = diff / 2;
            tmp = tmp.subImage(x, 0, placeholderImage.getWidth(), placeholderImage.getHeight(), true);
        } else if (tmp.getHeight() > placeholderImage.getHeight()) {
            int diff = tmp.getHeight() - placeholderImage.getHeight();
            int y = diff / 2;
            tmp = tmp.subImage(0, y, Math.min(placeholderImage.getWidth(), tmp.getWidth()),
                    Math.min(placeholderImage.getHeight(), tmp.getHeight()), true);
        }
        Image roundMask = Image.createImage(tmp.getWidth(), tmp.getHeight(), 0xff000000);
        Graphics gr = roundMask.getGraphics();
        gr.setColor(0xffffff);

        gr.fillArc(0, 0, tmp.getWidth(), tmp.getHeight(), 0, 360);
        Object mask = roundMask.createMask();
        tmp = tmp.applyMask(mask);
        return EncodedImage.createFromImage(tmp, false);
    }

    @Override
    public boolean isAsyncAdapter() {
        return true;
    }
};

代码改进:

//Placeholder image

int size = Display.getInstance().convertToPixels(20);
Image placeholder = Image.createImage(size, size, 0xbfc9d2);
Graphics g = placeholder.getGraphics();
g.setAntiAliased(true);
g.setColor(0xbfc9d2);
g.fillArc(0, 0, size, size, 0, 360);

MultiButton[] cmps = new MultiButton[reports.size()];
for (int iter = 0; iter < reports.size(); iter++) {
    Report currentReport = reports.get(iter);
    if (currentReport == null) {
        InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), new Component[0], false);
        return;
    }

    String photoFilenameInStorage = Report.getFilename(currentReport.getPhotoPath());

    String summary = currentReport.getLocation();
    cmps[iter] = new MultiButton(summary);
    // Only shows a black filled circle!
    cmps[iter].setIcon(placeholder);

    Display.getInstance().callSerially(() -> {
       cmps[iter].setIcon( URLImage.createToStorage(cmps[iter].getIcon(), photoFilenameInStorage, currentReport.getPhotoPath(), RESIZE_SCALE_WITH_ROUND_CORNER_MASK));
       cmps[iter].getParent().revalidate();
    });
}
InfiniteScrollAdapter.addMoreComponents(this.getContentPane(), cmps, true);